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.
精彩评论