当前位置: 首页 > 工具软件 > DateTools > 使用案例 >

iOS 10 中时区问题导致 DateTools 框架 weekday 方法计算不正确

姚永年
2023-12-01

某日发现 DateTools 的 weekday 方法在不同 iOS 上计算出的结果不一样的问题。具体表现为:在 iOS 10 上计算出的结果比 iOS 12 上的结果少一天。比如同样是 2019-09-23,iOS 10 上计算结果为 1,而 iOS 12 上计算结果为 2。

跟踪代码发现,weekday 方法中调用了 [self componentForDate:self type:DTDateComponentWeekday calendar:nil]; 一句。

这里的 calendar 参数为 nil 表明将使用默认日历,而默认日历的 timezone 默认将使用本地时区。

但是,在 iOS 11 之前,NSTimeZone 无法正确获取系统设置的时区!因而导致计算出的结果少了一天。

分别在 iOS 11-12 和 iOS 10-10.3 下调用 NSTimeZone 的 defaultTimeZone、localTimeZone 和 systemTimeZone,以及 [NSCalendar currentCalendar].timeZone,发现后者无法正确获取到系统设置的当前地区。

以下测试在模拟器上进行,测试前都将地区设置为 China。

这是 iOS 11.4-12.4 的测试结果:

iOS 11.4 - 12.4

------------------------------------
(lldb) po [NSTimeZone defaultTimeZone]
Asia/Shanghai (GMT+8) offset 28800

(lldb) po [NSTimeZone localTimeZone]
Local Time Zone (Asia/Shanghai (GMT+8) offset 28800)

(lldb) po [NSTimeZone systemTimeZone]
Asia/Shanghai (GMT+8) offset 28800

(lldb) po [NSCalendar currentCalendar].timeZone
Asia/Shanghai (GMT+8) offset 28800

上面的结果显示,iOS 11.4 - 12.4 上,通过上述 API,能够正确获取到系统设置的时区(中国 +8 区)。

iOS 10-10.31 的测试结果如下:


iOS 10 - 10.31
------------------------------------
(lldb) po [NSTimeZone defaultTimeZone]
GMT (GMT) offset 0

(lldb) po [NSTimeZone localTimeZone]
Local Time Zone (GMT (GMT) offset 0)

(lldb) po [NSTimeZone systemTimeZone]
GMT (GMT) offset 0

(lldb) po [NSCalendar currentCalendar].timeZone
GMT (GMT) offset 0

上面的结果显示,iOS 10-10.31 上,无法正确获取到的系统当前时区,都会返回 GMT。

解决办法

用 weekdayWithCalandar 方法取代 weekday 方法。

NSCalendar* cal = [NSCalendar currentCalendar];
cal.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
NSInteger w = [baseDate weekdayWithCalendar:cal];
 
 类似资料: