question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

'fromISO' does not parse 'Z' or other timezone information

See original GitHub issue

Describe 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:closed
  • Created 2 years ago
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
icambroncommented, Apr 21, 2022

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:

const iso = "2022-04-21T10:13:31+04:00";
new Date(iso) == new Date(iso) // => false

Instead, try this, which works fine:

const iso = "2022-04-21T10:13:31+04:00";
new Date(iso).valueOf() === DateTime.fromISO(iso).toJSDate().valueOf(); // => true

That has nothing to do with the time zone; it has to do with what time it is. Or as the docs put it:

It’s important to remember that a DateTime represents a specific instant in time and that instant has an unambiguous meaning independent of what time zone you’re in; the zone is really a piece of social metadata that affects how humans interact with the time, rather than a fact about the passing of time itself. Of course, Luxon is a library for humans, so that social metadata affects Luxon’s behavior too. It just doesn’t change what time it is.

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.

How does Z carry more information than the numerical offset? 2022-04-21T10:13:31+04:00 means the UTC+4 time zone

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 use setZone: true

1reaction
icambroncommented, Apr 22, 2022

@thw0rted Yeah, zone: "UTC" does sound like what you want, and IMO is much better than setZone: 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 operations yourDateTime.hour will return 7, not 11, as it would if you used setZone). 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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Parsing utc date in iso format returns local zone #306 - GitHub
The result has my local timezone, whereas I expected the result to be in UTC timezone, as clearly depicted by the ending "Z"...
Read more >
How do I parse an ISO 8601-formatted date? - Stack Overflow
A plain datetime object has no concept of timezone. If all your times are ending in "Z", all the datetimes you get are...
Read more >
Parse "Z" timezone suffix in datetime - Ideas
To be clear, currently the idea is that you should parse this name as "from isoformat " rather than “from ISO format”, meaning...
Read more >
luxon 3.1.1 | Documentation
It contains class and instance methods for creating, parsing, interrogating, transforming, and formatting them. A DateTime comprises of: A timestamp. Each ...
Read more >
How to Handle Time Zones using DateTime and Luxon
Let's suppose you have a date representation from an external API, and you need to convert the date to any desired time zone....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found