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

nsdate datefromstring,如何解析“大约”UTC、GMT和用户区域设置?

  •  3
  • RickiG  · 技术社区  · 15 年前

    我分析XML文件中的一些值。 有一个 @"25-12-2010'T'23:40:00" 带有时间和日期的字符串,其中有一个带有GMT偏移量的字符串,如@“+0200”。 所以上面的时间是25。12月23:40:00,时区+0200 GMT(或21:40 UTC) 我有很多不同的GMT偏移量的日期。我必须把这些日期显示为 它们是,也就是说,不能更改它们以适合用户的区域设置。所以,如果时间1:是22:45+0500,那么这就是我必须向用户显示的内容,即使用户在不同的时区。

    我在显示、计算和解析这些字符串时遇到了各种麻烦。

    如果我使用日期格式化程序 dateFromString 结果中将包含用户特定的GMT信息 NSDate 这意味着上面的内容将被保存为23:40:00+0100GMT,因为这是我的手机设置,纽约手机用户可能会保存为23:40:00–0400。

    当我随后在这些日期之间做减法、加法和比较时,我必须保持GMT偏移,如果手机切换地区设置,从分析日期到显示日期,一切都会变得更糟…

    是否有方法将此日期从字符串中提取为UTC,然后将其保存为间隔而不是实际的(取决于时区的)日期。我知道这就是为什么日期总是保存在内部。但我不知道如何使用单独的gmt字符串并考虑用户的区域设置。

    干杯

    2 回复  |  直到 15 年前
        1
  •  4
  •   Ole Begemann    15 年前

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

        2
  •  4
  •   RickiG    15 年前

    谢谢你,奥莱。我终于明白了 NSDate NSDateformatter 只是抽象的 概念和“日期”在内部真正被保存为“自2001年1月1日起的毫秒或秒”。

    我做了一个“概念证明”来真正理解它。现在,写一些分类突然变得非常简单 小精灵 这样可以确保输入和输出的日期格式正确,但所有计算都是在原始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,原始GMT 2010-03-30 18:50:31.285 Timezonepoc[39830:207]2010-03-30 16:00:00+0200(当地时间GMT)

    2010-03-30 18:50:31.287 Timezonepoc[39830:207]2010-03-30 12:00:00-0100,原始GMT 2010-03-30 18:50:31.287 Timezonepoc[39830:207]2010-03-30 15:00:00+0200(当地时间GMT)

    2010-03-30 18:50:31.289 Timezonepoc[39830:207]2010-03-30 12:00:00+0000,原始GMT 2010-03-30 18:50:31.289 Timezonepoc[39830:207]2010-03-30当地时间14:00:00+0200

    2010-03-30 18:50:31.290时区记录[39830:207]2010-03-30 12:00:00+0100,原始GMT 2010-03-30 18:50:31.292时间分区太平洋[39830:207]2010-03-30 13:00:00+0200当地时间GMT

    2010-03-30 18:50:31.292 Timezonepoc[39830:207]2010-03-30 12:00:00+0200,原始GMT 2010-03-30 18:50:31.294 Timezonepoc[39830:207]2010-03-30 12:00:00+0200(当地时间GMT)

    推荐文章