When I convert any sort of timestamp to a date, whether it be UTC or with another offset, it converts it to my local time. How can I stop it from doing that?
As an example, the following code prints out 2022-05-24 09:40:11 0000
but it should show up as 2022-05-24 01:40:11 0000
. I do not want the equivalent time in my own time zone that it is returning
let dateStr = "2022-05-024T01:40:11.126-08:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
let parsedDate = dateFormatter.date(from: dateStr)
print(parsedDate)
CodePudding user response:
Date
is just a container for the amount of time which has passed since some anchor point (ie milliseconds since the Unix Epoch), it doesn't "convert" the value, what it does do is, when you use "print", it make use of the platforms locale/timezone to present a "human readable" presentation of the time it represents
For example...
let dateStr = "2022-05-024T01:40:11.126-08:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
let date = dateFormatter.date(from: dateStr)!
print(date)
prints 2022-05-24 09:40:11 0000
But, if I change the formatter's timezone, for example...
let utcFormatter = DateFormatter()
utcFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
utcFormatter.timeZone = TimeZone(abbreviation: "UTC")
let utcDate = utcFormatter.date(from: dateStr)!
print(utcDate)
it still prints 2022-05-24 09:40:11 0000
Okay, it's printing in UTC anyway, so lets trying a different timezone:
let auFormatter = DateFormatter()
auFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
auFormatter.timeZone = TimeZone(abbreviation: "AEST")
let auDate = auFormatter.date(from: dateStr)!
print(auDate)
it still prints 2022-05-24 09:40:11 0000
If we read the docs it actually says "The representation is useful for debugging only."
If you want the presentation done differently, use a different formatter, for example...
let dateStr = "2022-05-024T01:40:11.126-08:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
let date = dateFormatter.date(from: dateStr)!
print(date)
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
print(dateFormatter.string(from: date))
dateFormatter.timeZone = TimeZone(secondsFromGMT: -(8 * 60 * 60))
print(dateFormatter.string(from: date))
dateFormatter.timeZone = TimeZone(abbreviation: "AEST")
print(dateFormatter.string(from: date))
Which prints...
2022-05-24 09:40:11 0000 // print(date)
2022-05-24T09:40:11.126Z // UTC
2022-05-24T01:40:11.126-08:00 // -8
2022-05-24T19:40:11.126 10:00 // AEST
(obviously you could also configure the Locale
for different representations)
They all represent the same date/time value, just at different time zones
You could also check the different date values using Date#timeIntervalSinceReferenceDate
or Date#timeIntervalSince1970
, for example...
let dateStr = "2022-05-024T01:40:11.126-08:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
print(dateFormatter.date(from: dateStr)!.timeIntervalSince1970)
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
print(dateFormatter.date(from: dateStr)!.timeIntervalSince1970)
dateFormatter.timeZone = TimeZone(secondsFromGMT: -(8 * 60 * 60))
print(dateFormatter.date(from: dateStr)!.timeIntervalSince1970)
dateFormatter.timeZone = TimeZone(abbreviation: "AEST")
print(dateFormatter.date(from: dateStr)!.timeIntervalSince1970)
which prints...
1653385211.126
1653385211.126
1653385211.126
1653385211.126
And as the docs state, "The interval between the date value and 00:00:00 UTC on 1 January 1970."
In this case, the formatter timezone has not effect on the parsing, only the presentation (the locale
can fix parsing issues, but that's another topic)