static let calendar with autoupdating当前时区不起作用

时间:2017-05-25 22:27:32

标签: ios swift static calendar timezone

在我的应用程序中,我在gregorian类中有一个静态SharedCalendar属性,其定义如下:

static let gregorian: Calendar = {
    var calendar = Foundation.Calendar(identifier: .gregorian)
    calendar.timeZone = TimeZone.autoupdatingCurrent
    return calendar
}()

当我想在特定时区访问某个日期时,我正在打电话:

SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!

我们说someDateDate(timeIntervalSinceReferenceDate: 512658000.0)2017-03-31 13:00:00 +0000

当我在温哥华时区启动应用时,SharedCalendar.gregorian.timeZone属性的值为America/Vancouver (autoupdatingCurrent),而SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!的结果为31 ,这是正确的

当我将应用程序置于后台并将时区切换到悉尼并再次运行应用程序时,SharedCalendar.gregorian.timeZone属性的值为Australia/Sydney (autoupdatingCurrent)(这是正确的),但结果为{{1} } SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day! 是错误的(应该是31

当我将1属性的定义更改为gregorian时:

var

一切正常,var gregorian: Calendar { var calendar = Foundation.Calendar(identifier: .gregorian) calendar.timeZone = TimeZone.autoupdatingCurrent return calendar } 我得到America/Vancouver (autoupdatingCurrent),而31得到Australia/Sydney (autoupdatingCurrent)

现在我不太明白1是如何运作的。当设备的时区发生变化时,TimeZone.autoupdatingCurrent会反映设备的时区,但看起来SharedCalendar.gregorian.timeZone会以某种方式使用旧的时区。

有没有人对此行为有解释?

1 个答案:

答案 0 :(得分:1)

关于这个问题我报告了radar,今天Apple回复了:

  

您的static let日历时区未更新的原因是您需要向NSTimeZone.resetSystemTimeZone()发出呼叫以与系统时区同步。有关详细信息,请参阅NSTimeZone.resetSystemTimeZone()的文档:https://developer.apple.com/documentation/foundation/nstimezone/1387189-resetsystemtimezone?language=objc

     

您的var日历工作的原因是因为对日历属性的每次调用实际上都会创建一个新的计算日历,该日历恰好设置为表示当前系统时区的新时区。

这是有道理的,因为static let缓存了系统的时区,而我们可以从NSTimeZone.resetSystemTimeZone的文档中读到:

  

如果应用程序已缓存系统时区,则此方法将清除该缓存的对象。如果您随后调用systemTimeZone,NSTimeZone将尝试重新确定系统时区,并将创建并缓存新对象(请参阅systemTimeZone)。