Static let calendar with autoupdating Current timezone not working
In my application, I have a static property gregorian
in a class SharedCalendar
that is defined like this:
static let gregorian: Calendar = {
var calendar = Foundation.Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone.autoupdatingCurrent
return calendar
}()
When I want to access the day of a date in a specific time zone, I call:
SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!
Let's say someDate
there is Date(timeIntervalSinceReferenceDate: 512658000.0)
that 2017-03-31 13:00:00 +0000
.
When I run my app in Vancouver timezone the property SharedCalendar.gregorian.timeZone
is set America/Vancouver (autoupdatingCurrent)
and the result SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!
is 31
which is correct .
When I put the app in the background and switch the timezone to Sydney and start the app again, the property SharedCalendar.gregorian.timeZone
is set Australia/Sydney (autoupdatingCurrent)
(that's correct), but the result SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!
is 31
that it isn't (should be 1
) .
When I change the property definition gregorian
as var
:
var gregorian: Calendar {
var calendar = Foundation.Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone.autoupdatingCurrent
return calendar
}
Everything works correctly, what for America/Vancouver (autoupdatingCurrent)
I get 31
, and for Australia/Sydney (autoupdatingCurrent)
we get 1
.
Now I don't quite understand how it works TimeZone.autoupdatingCurrent
. When changing the time zone, the device SharedCalendar.gregorian.timeZone
reflects the time zone of the device, but it looks like SharedCalendar.gregorian
it is using the old time zone in some way.
Does anyone have an explanation for this behavior?
source to share
I informed radar regarding this issue and today Apple replied:
The reason your timezone is
static let
not updating is because you need to send a callNSTimeZone.resetSystemTimeZone()
to sync with the system timezone. For more information see the documentation forNSTimeZone.resetSystemTimeZone()
: https://developer.apple.com/documentation/foundation/nstimezone/1387189-resetsystemtimezone?language=objcThe reason your calendar works
var
is because each call to the calendar property actually creates a new calculated calendar that is set to be set to a new time zone that represents the current system time zone.
This makes sense because it static let
caches the system timezone and from the documentation for NSTimeZone.resetSystemTimeZone
we can read:
If the application has cached the system time zone, this method clears that cached object. If you subsequently call systemTimeZone, NSTimeZone will try to redefine the system time zone and a new object will be created and cached (see SystemTimeZone).
source to share