luxon: Parsing utc date in iso format returns local zone
DateTime.fromISO("2018-07-25T00:00:00Z");
The result has my local timezone, whereas I expected the result to be in UTC timezone, as clearly depicted by the ending “Z” character.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 17 (5 by maintainers)
@GuilhermeRossato you’re re-hashing an issue that has already been discussed in this thread. The key “gotcha” here that tripped up me and others is understanding that how a date is parsed and how a date is displayed (or formatted) are 2 different things.
When you parse an ISO date that ends in ‘Z’, luxon parses it as UTC, but when you display it by calling
toISODate()
it behaves like the nativeDate
class and displays it in your local timezone. You have to explicitly tell luxon to display it in the UTC timezone like so:In my opinion, this is a flaw with Luxon, and a “gotcha” for developers who expect Luxon to respect ISO spec. Javascript’s own Date() constructor properly interprets the Z:
Luxon is providing the added benefit of parsing offsets, but the presence of the “Z” at the end should override any offset and respect the spec.
@icambron specifying an offset and using the “Z” suffix is not the same thing. As offsets don’t have a one-to-one relationships to timezones, it’s completely reasonable for luxon to use the system’s timezone. But the “Z” suffix is a special case as it’s meant to be interpreted as UTC, see here: https://en.wikipedia.org/wiki/ISO_8601#Coordinated_Universal_Time_(UTC)
So I expect luxon to respect the ISO spec in that regard and use utc as a timezone and not the local system’s timezone.
Luxon parses the Z out and uses it to interpret the time encoded in the string; the only question is whether it also sets the zone on the resulting datetime to UTC or not.
The point isn’t whether Z is an offset or zone; check out the second example involving
Europe/Paris
. (Perhaps the section title should be changed to reflect that.) Luxon considers both a zone or offset specified in the string independent of zone in the resulting DateTime, unless you specifically tell it otherwise. It would be silly to do otherwise, because it would create really inconsistent behavior for a caller who doesn’t know whether the incoming string contains “Z” or not.I’m amazed to see how many words were wasted here to try to defend (an arguably bad (*)) design decision to make Luxon behave similar to native Date by default… and none to actually answer the original question.
So, for the posterity - here’s the real solution for everyone who might be wondering why Luxon is losing the timezone offset (regardless of whether it’s UTC, or any other):
(*) The reason we want to use Luxon is because the native Date support is full of broken idiosyncrasies like this one. We WANT it to behave more logically than the native.
@icambron I think we’re talking around eachother. In your example, you can see the issue:
"2018-07-25T00:00:00Z"
gets formatted in your local time zone:"2018-07-24T20:00:00.000-04:00"
You have to specify the zone with Luxon, instead of just providing the “Z”. Here’s an example:
outputs:
I’m saying we would expect the zone to be set as UTC since we are providing it as UTC. But instead we have to use helper methods like the following to process all our Luxon dates:
Please see Strings that specify an offset in the docs and the Set Zone section just after it.