开发者

NSDate gurus: my calculation method fails to produce consistent dates. Why?

I created a method to find the third Friday of every month.

When I run it from Eastern time zone, all is well.

When I run it from Central, the dates are off.

My method:

-(NSDate*) getSaturdayAfterThirdFriday:(NSDate*)date {
    NSDate* resultDate = nil;

    if( date != nil ) {

        NSDateFormatter *df = [[NSDateFormatter alloc] init];

        // start at the 1st of the month
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

        NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"EST"];
        [calendar setTimeZone:zone];
        NSDateComponents *comp = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
        [comp setDay:1];
        date= [calendar dateFromComponents:comp];
        [calendar release];

        // count number of 'fri' (including today)
        BOOL foundFlag = NO;
        NSString* dateString = nil;
        NSInteger count = 0;

        [df setDateFormat:@"EEE"];

        while (foundFlag == NO) {
            dateString = [df stringFromDate:date];
            if( [dateString caseInsensitiveCompare:@"fri"] == 0 ) {
                count++;
                NSLog(@"Found Friday: %@", [date description]);
            }
            if( count >= 3 ) foundFlag = YES;
            else date = [NSDate dateWithTimeInterval:86400 sinceDate:date];
        }

        // get the next day (Saturday)
        resultDate = [NSDate dateWithTimeInterval:86400 sinceDate:date];

        [df release];
    }

    return resultDate;
}

The date that is passed is created with this method:

-(NSDate*) getDateForEasternTime:(NSDate*)date {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"EST"];
    [calendar setTimeZone:zone];
    NSDateComponents *comp = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
    date = [calendar dateFromComponents:comp];
    [calendar release];
    NSLog(@"getDateForEasternTime: %@", [date description]);
    return date;
}

I need to calculate dates based on Eastern Time only.

Here's my log output for Eastern time zone:

getDateForEasternTime: 2010-11-14 05:00:00 GMT

Found Friday: 2010-11-05 05:00:00 GMT

Found Friday: 2010-11-12 05:00:00 GMT

Found Friday: 2010-11-19 05:00:00 GMT

And for Ce开发者_如何学JAVAntral Time:

getDateForEasternTime: 2010-11-14 05:00:00 GMT

Found Friday: 2010-11-05 05:00:00 GMT

Found Friday: 2010-11-13 05:00:00 GMT

Found Friday: 2010-11-20 05:00:00 GMT

What's even more strange is that if I go further West in time zones, there is the discrepancy. If I go East in time zones there is none.

Any NSDate guru's can help with this?

Edit:

When I refer to changing the time zone, I'm talking about changing the time zone on the device itself. The line:

NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"EST"];

Remains unchanged.


All your code is unnecessary. Using the weekday and weekdayOrdinal properties of NSDateComponents you can directly query a NSCalendar for the 3rd Friday of a month:

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setWeekday:6];        // 1 = Sunday ... 7 = Saturday
[components setWeekdayOrdinal:3]; // 3rd Friday  
[components setMonth:11]; 
[components setYear:2010];
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDate *date = [currentCalendar dateFromComponents:components];

Also, there is almost the same example for this in the Developer Documentation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜