Thursday, June 13, 2013

NSCalendar ordinalityOfUnit example in Objective C (iOS).

NSCalendar ordinalityOfUnit

Returns, for a given absolute time, the ordinal number of a smaller calendar unit (such as a day) within a specified larger calendar unit (such as a week).

- (NSUInteger)ordinalityOfUnit:(NSCalendarUnit)smaller inUnit:(NSCalendarUnit)larger forDate:(NSDate *)date

The smaller calendar unit
The larger calendar unit
The absolute time for which the calculation is performed

Return Value of [NSCalendar ordinalityOfUnit]
The ordinal number of smaller within larger at the time specified by date. Returns NSNotFound if larger is not logically bigger than smaller in the calendar, or the given combination of units does not make sense (or is a computation which is undefined).

Discussion of [NSCalendar ordinalityOfUnit]
The ordinality is in most cases not the same as the decomposed value of the unit. Typically return values are 1 and greater. For example, the time 00:45 is in the first hour of the day, and for units Hour and Day respectively, the result would be 1. An exception is the week-in-month calculation, which returns 0 for days before the first week in the month containing the date.

Note that some computations can take a relatively long time.

NSCalendar ordinalityOfUnit example.
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];

//NSDate * dateA = [NSDate date];
NSDate * dateA = [formatter dateFromString:@"2009-12-15 06:09:00 +1100"];
NSDate * dateB = [formatter dateFromString:@"2009-12-15 04:17:00 +1100"];

NSUInteger currentMinuteOrdinal =
    [[NSCalendar currentCalendar] ordinalityOfUnit:NSMinuteCalendarUnit
                                           forDate:dateA];      // current

NSUInteger passedInMinuteOrdinal =
    [[NSCalendar currentCalendar] ordinalityOfUnit:NSMinuteCalendarUnit
                                           forDate:dateB];      // passed in

NSUInteger minuteDifference = currentMinuteOrdinal - passedInMinuteOrdinal;

NSLog(@" currentMinuteOrdinal: %d", currentMinuteOrdinal);
NSLog(@"passedInMinuteOrdinal: %d", passedInMinuteOrdinal);
NSLog(@"     minuteDifference: %d", minuteDifference);
Output in this case:

2009-12-15 21:51:46.215 x[50036:903]  currentMinuteOrdinal: 1056606130
2009-12-15 21:51:46.216 x[50036:903] passedInMinuteOrdinal: 1056606018
2009-12-15 21:51:46.217 x[50036:903]      minuteDifference: 112

Example of [NSCalendar ordinalityOfUnit].
NSCalendar *gregorian =
   [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger dayOfYear =
   [gregorian ordinalityOfUnit:NSDayCalendarUnit
     inUnit:NSYearCalendarUnit forDate:[NSDate date]];
[gregorian release];
return dayOfYear;
where date is the date you want to determine the day of the year for. The documentation on the NSCalendar.ordinalityOfUnit method is here.

NSCalendar ordinalityOfUnit example.
NSTimeZone *tz = [[NSCalendar autoupdatingCurrentCalendar] timeZone];
NSTimeInterval offset =  [tz secondsFromGMT];

NSDate* dateC = [formatter dateFromString:@"2010-12-27 11:11:17 +1100"]; 
NSDate* dateD = [formatter dateFromString:@"2010-12-27 10:11:17 +1100"]; 

NSLog(@"dateC=%@, %@", dateC, [formatter stringFromDate:dateC]);
NSLog(@"dateD=%@, %@", dateD, [formatter stringFromDate:dateD]);

dateC = [dateC dateByAddingTimeInterval: offset];
dateD = [dateD dateByAddingTimeInterval: offset];

NSLog(@"C day inUnit:Era =%d", [calendar ordinalityOfUnit:NSDayCalendarUnitinUnit:NSEraCalendarUnit forDate: dateC]);
NSLog(@"D day inUnit:Era =%d", [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSEraCalendarUnit forDate: dateD]);

End of NSCalendar ordinalityOfUnit example article.