代码之家  ›  专栏  ›  技术社区  ›  just_another_coder

NSDate专家:我的计算方法无法生成一致的日期。为什么?

  •  0
  • just_another_coder  · 技术社区  · 15 年前

    我发明了一种方法来找到每个月的第三个星期五。

    当我从东部时区运行时,一切都很好。

    当我从中环查的时候,日期取消了。

    我的方法:

    -(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;
    }
    

    使用此方法创建传递的日期:

    -(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;
    }
    

    我只需要根据东部时间来计算日期。

    这是我在东部时区的日志输出:

    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
    

    对于中央时间:

    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
    

    更奇怪的是,如果我在时区往西走得更远,就会有差异。如果我在时区向东走,那里没有。

    有谁能帮上忙吗?

    编辑:

    当我提到更改时区时,我指的是更改设备本身的时区。台词:

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

    保持不变。

    1 回复  |  直到 15 年前
        1
  •  4
  •   Sven    15 年前

    你所有的代码都是多余的。使用 weekday weekdayOrdinal 属性 NSDateComponents 您可以直接查询 NSCalendar 一个月的第三个星期五:

    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];
    

    而且,在 Developer Documentation .