Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ordinal weekday index from NSDateComponents

Tags:

ios

nsdate

I have created a category for NSDate which can create a string representation of a date with the weekday name, such as Thursday 5 January.

I want to get the weekday index and use a custom made array of weekdays which are stored in a plist and localised to english and spanish.

However using NSDateComponents is giving me some unexpected results. I'm requesting both NSWeekdayOrdinalCalendarUnit and NSWeekdayCalendarUnit and I am outputting the results to the log and I am getting the following example:

NSDateComponents *components    = [[NSCalendar currentCalendar] components:NSWeekdayOrdinalCalendarUnit | NSWeekdayCalendarUnit fromDate:self];
NSInteger weekdayOrdinal        = [components weekdayOrdinal];
NSInteger weekdayNonOrdinal     = [components weekday];
NSLog(@"Date: %@", [self description]);
NSLog(@"Device oridinal weekday: %d", weekdayOrdinal);
NSLog(@"Device non-oridinal weekday: %d", weekdayNonOrdinal);

2012-01-06 15:05:56.492 MyApp[964:11903] Date: 2012-01-05 16:13:46 +0000

2012-01-06 15:05:56.492 MyApp[964:11903] Device oridinal weekday: 1

2012-01-06 15:05:56.493 MyApp[964:11903] Device non-oridinal weekday: 5

This day should be Thursday, ordinal should be 4 and non ordinal 5

I don't understand where the 1 comes from.

I found a way to adjust this to make sure we are using the gregorian calendar with NSDateFormatter and specifying an NSCalendar (with the first date of the week to be Monday) like the following:

NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[gregorian setFirstWeekday:2];
NSUInteger adjustedWeekdayOrdinal = [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:self];

NSDateFormatter *weekdayF = [[[NSDateFormatter alloc] init] autorelease];
[weekdayF setDateFormat: @"EEEE"];
[weekdayF setCalendar:gregorian];
[weekdayF setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_UK"]];
NSLog(@"The day of the week is: %@", [weekdayF stringFromDate:self]);

This will give me what I want but now I have to store the locale identifier in the plist to use in spanish, what I would prefer to keep is the first instance with NSDateComponents but I don't understand why I am getting a funny value sometimes.

I did find a solution to adjust the index with this solution: https://stackoverflow.com/a/3524462/662605

However, to be honest, I wouldn't like to use that along with NSDateComponents, I would rather use the NSDateFormatter, but overall it would be cool to fix the first example which gives me a false weekdayOrdinal value.

Any ideas on this ?

like image 745
Daniel Avatar asked Dec 21 '22 03:12

Daniel


1 Answers

I think you're misinterpreting what weekdayOrdinal means. According to the doc for NSDateComponents, getting the weekdayOrdinal returns the ordinal number of weekday units for the receiver, where weekday ordinal units are the "position of the weekday within the next larger calendar unit, such as the month. For example, 2 is the weekday ordinal unit for the second Friday of the month".

By this reasoning, 2012-01-05 correctly has a weekdayOrdinal of 1 b/c it's the first Thursday of the month.

like image 51
dw.mackie Avatar answered Jan 07 '23 10:01

dw.mackie