我从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字符串并考虑用户区域设置。
干杯
答案 0 :(得分:4)
使用NSDateFormatter的setTimeZone:
。您还需要将时区偏移与NSDate分开存储,以便稍后再次显示这些时区中的时间。
答案 1 :(得分:4)
谢谢Ole。我终于明白了NSDate
和NSDateformatter
只是抽象的
概念和“日期”真正保存为“自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