In my application I have a static gregorian
property in SharedCalendar
class 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 a day of some date in specific time zone I am calling:
SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!
Let's say someDate
is Date(timeIntervalSinceReferenceDate: 512658000.0)
which is 2017-03-31 13:00:00 +0000
.
When I start the app in Vancouver time zone the SharedCalendar.gregorian.timeZone
property has value America/Vancouver (autoupdatingCurrent)
and the result of SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!
is 31
which is correct.
When I put the application to background and switch the time zone to Sydney and run the app again the SharedCalendar.gregorian.timeZone
property has value Australia/Sydney (autoupdatingCurrent)
(which is correct), but the result of SharedCalendar.gregorian.dateComponents([ .day ], from: someDate).day!
is 31
which is wrong (should be 1
).
When I change the definition of gregorian
property to be a var
:
var gregorian: Calendar {
var calendar = Foundation.Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone.autoupdatingCurrent
return calendar
}
Everything works properly, which is for America/Vancouver (autoupdatingCurrent)
I get 31
, and for Australia/Sydney (autoupdatingCurrent)
I get 1
.
Right now I don't quite understand how TimeZone.autoupdatingCurrent
is working. When device's time zone changes the SharedCalendar.gregorian.timeZone
reflects the device's time zone, but it looks like SharedCalendar.gregorian
is somehow using the old time zone.
Does anyone have explanation of this behaviour?
I reported radar regarding this issue and today Apple responded:
The reason that your
static let
calendar’s time zone doesn’t update is that you need to issue a call toNSTimeZone.resetSystemTimeZone()
to sync up with the system time zone. See the documentation forNSTimeZone.resetSystemTimeZone()
for more info: https://developer.apple.com/documentation/foundation/nstimezone/1387189-resetsystemtimezone?language=objcThe reason your
var
calendar works is because every call to the calendar property actually creates a new computed calendar, which happens to be set to a new time zone representing the current system time zone.
This makes sense, because static let
caches system's time zone, and from 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 invoke systemTimeZone, NSTimeZone will attempt to redetermine the system time zone and a new object will be created and cached (see systemTimeZone).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With