在我的应用程序中,我在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!
我们说someDate
是Date(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
会以某种方式使用旧的时区。
有没有人对此行为有解释?
答案 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)。