'fromISO' does not parse 'Z' or other timezone information
See original GitHub issueDescribe the bug
In version 2.0.1, DateTime.fromISO
no longer parses ‘Z’ as setting the zone to UTC.
To Reproduce Please share a minimal code example that triggers the problem: import { DateTime } from ‘luxon’;
const date1 = DateTime.fromISO(‘2020-12-23T12:30:30Z’); const date2 = DateTime.fromISO(‘2020-12-23T12:30:30’, { zone: ‘utc’ });
// Expected output: ‘2020-12-23T12:30:30.000Z’ console.log(date1.toString()); // Actual output: ‘2020-12-23T04:30:30.000-08:00’
// Expected output: ‘2020-12-23T12:30:30.000Z’ console.log(date2.toString()); // Actual output: ‘2020-12-23T12:30:30.000Z’
Actual vs Expected behavior ‘Z’ should be respected as the timezone, but timezone is now set to the machine’s timezone.
Desktop (please complete the following information):
- OS: OSX
- Browser: N/A (Node or ts-node)
- Luxon version:
- Your timezone: ‘-08:00’
Additional context I am upgrading from 1.27.0 which parsed ‘Z’ correctly.
Issue Analytics
- State:
- Created 2 years ago
- Comments:11 (4 by maintainers)
This isn’t a bug.
The information is not discarded. It’s used to compute the date and time. The offset indicator is how the string was expressed, a fact that Luxon uses to determine the epoch time being communicated. And the resulting DateTime is put in the system zone by default.
Your code snippet is wrong; equality in Javascript doesn’t work that way, because the two dates are different objects. For example, this is also false:
Instead, try this, which works fine:
That has nothing to do with the time zone; it has to do with what time it is. Or as the docs put it:
So Luxon computes the moment in time correctly, and the the question is, “what zone does it use when answering questions about the local time?” By default, it uses the system zone, though there are a lot of ways to change this, such as setting a default zone, explicitly changing the DateTime’s zone, and using the offset or zone specified in the string. That last one sounds like what you want:
DateTime.fromISO(someString, { setZone: true })
. It sets the zone to the one in the string for when that’s what you want. Which in my experience is rare, and I think you’ll find it’s a good way to introduce bugs (remember: I’ve spent my life building DateTime applications), but it’s there for the cases you might need it. But again: this doesn’t change the time.It doesn’t mean that; you’re confusing zones and offsets. I live Boston, MA, which part of the America/New_York timezone, often called US Eastern Time. Sometimes it’s in -4 and sometimes its in -5, so it is not in UTC-4. If I called my zone “-4” I’d just be wrong half the time. For example, if I parsed a string using
setZone
with -4 as the offset, and then added 6 months to it, I’d get the wrong local time for 6 months later. Perhaps even more clearly: Europe/London is sometimes in GMT (00:00) and sometimes in British Summer Time (+1:00), but it’s not == UTC, because UTC doesn’t change halfway through the year. So the nice thing about the Z is that it means UTC, which implies the offset is always 0, whereas +00:00 just means the offset is 0 for that particular moment in time. Luxon doesn’t do anything interesting with that Z vs 0 difference when parsing strings, hence the nuance I was introducing. But none of that is here nor there if you always want the offset used as the zone; just usesetZone: true
@thw0rted Yeah,
zone: "UTC"
does sound like what you want, and IMO is much better thansetZone: true
. Specifically: with explicit UTC, you get a string with some other offset like “2022-04-22T11:17:23+04:00”, you’ll still get a datetime zoned in UTC (i.e. local time operationsyourDateTime.hour
will return 7, not 11, as it would if you usedsetZone
). Always using the same zone allows your code not to have to worry about how this particular string was expressed; the string’s offset is only used in computing the time by interpreting the string correctly, not messing with the zone metadata on the resulting DateTime object.You can also just set the default zone for the whole application to UTC via
Settings.defaultZone = "utc"
and then not really worry about it again.To add a little extra context about system-zone-by-default: most servers have (or should have) their system clocks set to UTC, which means that UTC is the default for Luxon anyway. Browsers typically have theirs set to the user’s local time zone, so that results in Luxon using that, which is usually what client applications want (i.e. show dates in UIs in the user’s zone). That means that accessors like
hour
do what people generally expect in both cases, regardless of what offset the string uses. All the options are for the exceptions to that pattern, wherein you need to compute local times for other zones.