Thursday, June 13, 2013

NSCalendar NSWeekdayOrdinalCalendarUnit example in Objective C (iOS).


NSCalendar NSWeekdayOrdinalCalendarUnit

Calendar Units
Specify calendrical units such as day and month.

enum {
NSEraCalendarUnit = kCFCalendarUnitEra,
NSYearCalendarUnit = kCFCalendarUnitYear,
NSMonthCalendarUnit = kCFCalendarUnitMonth,
NSDayCalendarUnit = kCFCalendarUnitDay,
NSHourCalendarUnit = kCFCalendarUnitHour,
NSMinuteCalendarUnit = kCFCalendarUnitMinute,
NSSecondCalendarUnit = kCFCalendarUnitSecond,
NSWeekCalendarUnit = kCFCalendarUnitWeek,
NSWeekdayCalendarUnit = kCFCalendarUnitWeekday,
NSWeekdayOrdinalCalendarUnit = kCFCalendarUnitWeekdayOrdinal,
NSQuarterCalendarUnit = kCFCalendarUnitQuarter,
NSWeekOfMonthCalendarUnit = kCFCalendarUnitWeekOfMonth,
NSWeekOfYearCalendarUnit = kCFCalendarUnitWeekOfYear,
NSYearForWeekOfYearCalendarUnit = kCFCalendarUnitYearForWeekOfYear
NSCalendarCalendarUnit = (1 << 20),
NSTimeZoneCalendarUnit = (1 << 21),
};
typedef NSUInteger NSCalendarUnit;

Constants
NSEraCalendarUnit
Specifies the era unit.
The corresponding value is an NSInteger. Equal to kCFCalendarUnitEra.
NSYearCalendarUnit
Specifies the year unit.
The corresponding value is an NSInteger. Equal to kCFCalendarUnitYear.
NSMonthCalendarUnit
Specifies the month unit.
The corresponding value is an NSInteger. Equal to kCFCalendarUnitMonth.
NSDayCalendarUnit
Specifies the day unit.
The corresponding value is an NSInteger. Equal to kCFCalendarUnitDay.
NSHourCalendarUnit
Specifies the hour unit.
The corresponding value is an NSInteger. Equal to kCFCalendarUnitHour.
NSMinuteCalendarUnit
Specifies the minute unit.
The corresponding value is an NSInteger. Equal to kCFCalendarUnitMinute.
NSSecondCalendarUnit
Specifies the second unit.
The corresponding value is a double. Equal to kCFCalendarUnitSecond.
NSWeekCalendarUnit
Specifies the week unit.
The corresponding value is an kCFCalendarUnitSecond. Equal to kCFCalendarUnitWeek.
NSWeekdayCalendarUnit
Specifies the weekday unit.
The corresponding value is an kCFCalendarUnitSecond. Equal to kCFCalendarUnitWeekday. The weekday units are the numbers 1 through N (where for the Gregorian calendar N=7 and 1 is Sunday).
NSWeekdayOrdinalCalendarUnit
Specifies the ordinal weekday unit.
The corresponding value is an kCFCalendarUnitSecond. Equal to kCFCalendarUnitWeekdayOrdinal. The weekday ordinal unit describes ordinal position within the month unit of the corresponding weekday unit. For example, in the Gregorian calendar a weekday ordinal unit of 2 for a weekday unit 3 indicates "the second Tuesday in the month".
NSQuarterCalendarUnit
Specifies the quarter of the calendar as an kCFCalendarUnitSecond.
NSWeekOfMonthCalendarUnit
Specifies the original week of a month calendar unit.
NSWeekOfYearCalendarUnit
Specifies the original week of the year calendar unit.
NSYearForWeekOfYearCalendarUnit
Specifies the year when the calendar is being interpreted as a week-based calendar.
NSCalendarCalendarUnit
Specifies the calendar of the calendar.
NSTimeZoneCalendarUnit
Specifies the time zone of the calendar as an NSTimeZone.

Discussion of [NSCalendar NSWeekdayOrdinalCalendarUnit]
Calendar units may be used as a bit mask to specify a combination of units. Values in this enum are equal to the corresponding constants in the CFCalendarUnit enum.

NSCalendar NSWeekdayOrdinalCalendarUnit example.
- (BOOL) isSameWeekAsDate: (NSDate *) aDate andDate:(NSDate *) bDate
{
    NSDateComponents *components1 = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit |  NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit) fromDate:aDate];
    NSDateComponents *components2 = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit| NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit |  NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit) fromDate:bDate];

    if ([components1 week] != [components2 week]) return NO;

    //return (abs([self timeIntervalSinceDate:aDate]) < 604800); // ops, forgot to change "self" with parameter "bDate":
    return (abs([bDate timeIntervalSinceDate:aDate]) < 604800);
}

Example of [NSCalendar NSWeekdayOrdinalCalendarUnit].
 NSDate *today = [[NSDate alloc] init];
 NSLog([today description]);

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

 NSDateComponents *weekdayComponents = [gregorian components:(NSWeekdayCalendarUnit | NSWeekdayOrdinalCalendarUnit) fromDate:today];

 NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
 [componentsToSubtract setDay: 0 - ([weekdayComponents weekday])];
 [componentsToSubtract setWeekdayOrdinal:([weekdayComponents weekday] <= 6) ? 3 : 4];
 //[componentsToSubtract setWeekdayOrdinal:3]; //old way - not perfect

 NSDate *saturday = [gregorian dateByAddingComponents:componentsToSubtract toDate:today options:0];
 NSDateComponents *components =
 [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
     fromDate: saturday];
 saturday = [gregorian dateFromComponents:components];

 NSLog([saturday description]);

NSCalendar NSWeekdayOrdinalCalendarUnit example.
-(NSString *)relativeTime:(int)datetimestamp
{
    NSDate *aDate = [NSDate dateWithTimeIntervalSince1970:datetimestamp];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    unsigned int unitFlags =  NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayOrdinalCalendarUnit|NSWeekdayCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit;
    NSDateComponents *messageDateComponents = [calendar components:unitFlags fromDate:aDate];
    NSDateComponents *todayDateComponents = [calendar components:unitFlags fromDate:[NSDate date]];

    NSUInteger dayOfYearForMessage = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:aDate];
    NSUInteger dayOfYearForToday = [calendar ordinalityOfUnit:NSDayCalendarUnit inUnit:NSYearCalendarUnit forDate:[NSDate date]];

    NSString *dateString;

    if ([messageDateComponents year] == [todayDateComponents year] &&
        [messageDateComponents month] == [todayDateComponents month] &&
        [messageDateComponents day] == [todayDateComponents day])
    {
        dateString = [NSString stringWithFormat:@"%02d:%02d", [messageDateComponents hour], [messageDateComponents minute]];
    } else if ([messageDateComponents year] == [todayDateComponents year] &&
               dayOfYearForMessage == (dayOfYearForToday-1))
    {
        dateString = @"Yesterday";
    } else if ([messageDateComponents year] == [todayDateComponents year] &&
               dayOfYearForMessage > (dayOfYearForToday-6))
    {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"EEEE"];
        dateString = [dateFormatter stringFromDate:aDate];
        [dateFormatter release];

    } else {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"yy"];
        dateString = [NSString stringWithFormat:@"%02d/%02d/%@", [messageDateComponents day], [messageDateComponents month], [dateFormatter stringFromDate:aDate]];
        [dateFormatter release];
    }

    return dateString;
}

End of NSCalendar NSWeekdayOrdinalCalendarUnit example article.