NSDate dateFromString,如何解析'围绕'UTC,GMT和用户区域设置?

时间:2010-03-28 22:04:31

标签: iphone nsdate

我从xml文件中解析一些值。 有一个带有时间和日期的@"25-12-2010'T'23:40:00"字符串,并且有一个GMT偏移的字符串,如@“+ 0200”。 所以上面的时间是12月23日凌晨23点40分,时间点+格林威治标准时间+0200。 (或UTC时间21:40) 我有很多这些日期与不同的GMT抵消。我必须将这些日期显示为 它们是,即它们不得更改以适合用户的区域设置。因此,如果时间1:是22:45 +0500那么这就是我必须向用户显示的内容,即使用户位于不同的时区。

我在显示,计算和解析这些字符串方面遇到了各种各样的麻烦。

如果我使用dateFormatter和dateFromString,则用户特定的GMT信息将包含在结果NSDate中,意味着上述内容将保存为格林威治标准时间23:40:00 +0100,因为那是我的手机设置,也许23:40:00 -0400来自新纽约电话的用户。

当我随后在这些日期之间进行减法,加法和比较时,我必须保持GMT偏移,如果手机切换区域设置,从解析日期到显示日期时,一切都会变得更糟...... < / p>

我有没有办法从字符串中提取此日期作为UTC,然后将其保存为间隔而不是实际(时区相关)日期。我知道日期总是在内部保存。但我无法弄清楚如何使用单独的GMT字符串并考虑用户区域设置。

干杯

2 个答案:

答案 0 :(得分:4)

使用NSDateFormatter的setTimeZone:。您还需要将时区偏移与NSDate分开存储,以便稍后再次显示这些时区中的时间。

答案 1 :(得分:4)

谢谢Ole。我终于明白了NSDateNSDateformatter只是抽象的 概念和“日期”真正保存为“自2001年1月1日以来的毫秒或秒”。

我做了一个“概念证明”来真正理解它。现在,在NSDate上编写一些类别,确保进出日期的格式正确,但是所有计算都是在原始UTC日期完成的。

- (void) testGMTDateParser {

    NSMutableArray *arrayDates = [NSMutableArray arrayWithCapacity:5];
    [self setParsedDates:arrayDates];

    NSMutableArray *arrayGMTOffsets = [NSMutableArray arrayWithCapacity:5];
    [self setParsedGMTOffsets:arrayGMTOffsets]; 

    NSString *date00    = @"2010-03-30T12:00:00";   
    NSString *GMT00     = @"-2";

    NSString *date01    = @"2010-03-30T12:00:00";   
    NSString *GMT01     = @"-1";

    NSString *date02    = @"2010-03-30T12:00:00";   
    NSString *GMT02     = @"+0";

    NSString *date03    = @"2010-03-30T12:00:00";   
    NSString *GMT03     = @"+1";

    NSString *date04    = @"2010-03-30T12:00:00";   
    NSString *GMT04     = @"+2";    

    NSArray *dateArray  = [NSArray arrayWithObjects:date00, date01, date02, date03, date04,nil];
    NSArray *GMTArray   = [NSArray arrayWithObjects:GMT00, GMT01, GMT02, GMT03, GMT04, nil];

    for (int i = 0; i < [dateArray count]; i++) {

        [self parseDateString:[dateArray objectAtIndex:i] withGMTString:[GMTArray objectAtIndex:i]];
    }   

}

根据各自的GMT偏移量解析日期。这将确保保存UTC时间 内部是正确的。

-(void) parseDateString:(NSString*) dateString withGMTString:(NSString*) GMTString {

    NSInteger hoursFromGMT      = [GMTString intValue]; 
    NSInteger secondsFromGMT    = (hoursFromGMT * 60 * 60);

    NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:secondsFromGMT];

    NSDateFormatter *dateFormatterGMTAware = [[NSDateFormatter alloc] init];
    [dateFormatterGMTAware setTimeZone:timeZone];
    [dateFormatterGMTAware setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
    NSDate *date = [dateFormatterGMTAware dateFromString:dateString];
    [dateFormatterGMTAware release];

    [self.parsedDates addObject:date];
    [self.parsedGMTOffsets addObject:[NSNumber numberWithInt:secondsFromGMT]];
}

设置NSDateformatter以打印出与GMT偏移有关的保存日期。 所有日期现在都可以作为UTC进行操作而不考虑GMT。

-(void) printOutDates {

    for (int i = 0; i < [self.parsedDates count]; i++) {

        NSTimeZone *timeZone = [NSTimeZone timeZoneForSecondsFromGMT:[[parsedGMTOffsets objectAtIndex:i] intValue]];

        NSDateFormatter *dateFormatterGMTAware = [[NSDateFormatter alloc] init];
        [dateFormatterGMTAware setTimeZone:timeZone];
        [dateFormatterGMTAware setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"];

        NSLog(@"%@ in Original GMT", [dateFormatterGMTAware stringFromDate:[parsedDates objectAtIndex:i]]);
        NSLog(@"%@ in Local GMT\n\n", [parsedDates objectAtIndex:i]);
    }
}

2010-03-30 18:50:31.284 TimeZonePOC [39830:207] 2010-03-30 12:00:00 -0200 in Original GMT 2010-03-30 18:50:31.285 TimeZonePOC [39830:207] 2010-03-30 16:00:00 +0200 in Local GMT

2010-03-30 18:50:31.287 TimeZonePOC [39830:207] 2010-03-30 12:00:00 -0100 in Original GMT 2010-03-30 18:50:31.287 TimeZonePOC [39830:207] 2010-03-30 15:00:00 +0200 in Local GMT

2010-03-30 18:50:31.289 TimeZonePOC [39830:207] 2010-03-30 12:00:00 +0000 in Original GMT 2010-03-30 18:50:31.289 TimeZonePOC [39830:207] 2010-03-30 14:00:00 +0200 in Local GMT

2010-03-30 18:50:31.290 TimeZonePOC [39830:207] 2010-03-30 12:00:00 +0100 in Original GMT 2010-03-30 18:50:31.292 TimeZonePOC [39830:207] 2010-03-30 13:00:00 +0200 in Local GMT

2010-03-30 18:50:31.292 TimeZonePOC [39830:207] 2010-03-30 12:00:00 +0200 in Original GMT 2010-03-30 18:50:31.294 TimeZonePOC [39830:207] 2010-03-30 12:00:00 +0200 in Local GMT