NSDate: 我只输入utc时间成分,并正确设置日历,但NSDate不知为何会被重新计算到我的时区。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NSDate: 我只输入utc时间成分,并正确设置日历,但NSDate不知为何会被重新计算到我的时区。相关的知识,希望对你有一定的参考价值。

我有一个日期是UTC格式的字符串。我正确地创建了NSDate,并将日历也设置为UTC。然而,最后的日期是在本地时区。如果我的UTC时间是21:25,我用这段代码设置它,最后我通过NSLog得到新的日期23:25。为什么会这样呢?

NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear:[[timeStamp substringWithRange:NSMakeRange(0, 4)] floatValue]];
[dateComponents setMonth:[[timeStamp substringWithRange:NSMakeRange(5, 2)] floatValue]];
[dateComponents setDay:[[timeStamp substringWithRange:NSMakeRange(8, 2)] floatValue]];
[dateComponents setHour:[[timeStamp substringWithRange:NSMakeRange(11, 2)] floatValue]];
[dateComponents setMinute:[[timeStamp substringWithRange:NSMakeRange(14, 2)] floatValue]];

NSCalendar *calendar = [[NSCalendar alloc]  initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
[calendar setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSDate *configuredDate = [calendar dateFromComponents:dateComponents];

另外:我在柏林时区。所以+2是正确的,但是日期应该是在UTC?

这里是编辑。

2018-10-17 19:11:54.964754+0200 FollowMe[2005:91382] 时间戳之前:2018-10-17T17:37Z。

2018-10-17 19:11:54.965017+0200 FollowMe[2005:91382] 配置日期:Wed Oct 17 19:37:00 2018。

2018-10-17 19:11:54.965096+0200 FollowMe[2005:91382] 时间间隔:1539797820.000000。

答案

我找到的解决方案是在创建日历之前将defaultTimezone设置为 "UTC",然后使用dateFromComponents创建日期。现在日期被正确地创建了,并且可以使用dateFormatter检索和转换到任何需要的时区,而所需的时区被设置为 "UTC"。

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:1987];
[components setMonth:4];
[components setDay:10];
[components setHour:0];
[components setMinute:0];
[components setSecond:0];
[components setNanosecond:0];

NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *date = [gregorianCalendar dateFromComponents:components]; 
NSLog(@"%@", date); // puts out Fri Apr 10 00:00:00 1987

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.s ZZZZ"];

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Berlin"]];
NSLog(@"%@", [dateFormatter stringFromDate:date]); // puts out 1987-04-10 00:00:00.0 GMT+02:00
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSLog(@"%@", [dateFormatter stringFromDate:date]); // puts out 1987-04-09 22:00:00.0 GMT

现在如果我改变了defaultTimeZone:

NSTimeZone *UTCzone=[NSTimeZone timeZoneWithAbbreviation:@"UTC"];
NSTimeZone.defaultTimeZone= UTCzone;

然后重新创建一个日历和一个日期(来自相同的组件)。

NSCalendar *gregorianCalendar2 = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *date2 = [gregorianCalendar2 dateFromComponents:components];
NSLog(@"%@", date2); // puts out Fri Apr 10 02:00:00 1987    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Berlin"]];
NSLog(@"%@", [dateFormatter stringFromDate:date2]); // puts out 1987-04-10 02:00:00.0 GMT+02:00
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSLog(@"%@", [dateFormatter stringFromDate:date2]); // puts out 1987-04-10 00:00:00.0 GMT

这是令人沮丧的,因为我在Xcode文档中没有找到任何提到NSDate总是用默认时区创建。当然,我试着使用文档中所说的 (https:/developer.apple.comlibraryarchivedocumentationCocoaConceptualDatesAndTimesArticlesdtTimeZones.html#/apple_refdocuid20000185-BBCBDGID),

[gregorianCalendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];

这只是没有工作... 我也不知道为什么不行。如果有人知道,请分享。

以上是关于NSDate: 我只输入utc时间成分,并正确设置日历,但NSDate不知为何会被重新计算到我的时区。的主要内容,如果未能解决你的问题,请参考以下文章

将 UTC 日期格式转换为本地 nsdate

NSDate dateWithTimeIntervalSince1970 不返回 GMT/UTC 时间

ios 时间解析 差8个小时

iOS:将 UTC NSDate 转换为本地时区

将UTC日期格式转换为本地nsdate

如何计算不同时区的两个 NSDate 对象之间的天数差异?