-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Z designator (designating UTC) results in errors #133
Comments
@mathieuprog - What is your use case? I ask because the errors you ran into are intentional. Those errors prevent developers from initializing a Temporal instance from a string that does not match the data model of that Temporal type. If the data model of your input string is a UTC timestamp, then Temporal.Instant.from('2022-02-07T10:30:00Z')
// => 2022-02-07T10:30:00Z I've written up some additional info below to explain the reasoning behind the behavior you encountered. Feel free to follow up with more questions/concerns. Here's a few Temporal types with the data model of each:
With those data models in mind, here's why you're running into the errors above:
This is an error because the data model of Temporal.ZonedDate time is an exact time AND a time zone that can be used to derive other values via addition, subtraction, If you want to use the ZonedDateTime type, you'll need to tell Temporal what the time zone is, e.g.
To understand why this is an error, first let's look at similar code using the Temporal.Instant.from('2022-02-07T20:30:00Z').toZonedDateTimeISO('Asia/Tokyo').toPlainDate();
// => 2022-02-08 (note that this is different from the UTC "date" ! Now let's get back to your original question: why does For this reason, the only way to get UTC ("Z") timestamp strings into Temporal is via If you want to get the local date/time in a particular time zone, you'll need to supply the time zone: Temporal.Instant.from('2022-02-07T20:30:00Z').toZonedDateTimeISO('Asia/Tokyo');
// => 2022-02-08T05:30:00+09:00[Asia/Tokyo] If for some reason (I'd love to learn more about these reasons; please share if you have them) you really, really want to read the year/month/day/hour/minute/second fields from a Z string, you can always hack it using the const zdt = Temporal.Instant.from('2022-02-07T20:30:00Z').toZonedDateTimeISO('UTC');
const { day, hour, minute } = zdt
// => { day: 7, hour: 20, minute: 30 }
The reason why this case was not an error is because the data model of this string (local date, local time, UTC offset, and time zone) is compatible with the (local date, local time) data model of |
First let me start my answer with some observation: Temporal.ZonedDateTime.from('2000-02-29 23:00:07-04:00 AMT America/Manaus') It says "invalid ISO 8601 string". The error makes it then clear that Now let's try to pass Temporal.ZonedDateTime.from('2000-02-29 23:00:07-04:00[America/Manaus]') This works, however
So the error message for the first input seems incorrect. What do you think about that? Actually we've already mentioned that a format such as "2000-02-29 23:00:07-04:00[America/Manaus]" is not an ISO 8601 string (user thojanssens) at tc39/proposal-temporal#716 and tc39/proposal-temporal#741 and tc39/proposal-temporal#703 Either there is some extension to ISO 8601 that I'm not aware of, or we have to rewrite the error message to explain what format Now about the Z designator: The problem I'm having with the Z designator is that there are some languages that seem to consider Z to be 0 offset in UTC zone (and ZonedDatetime needs just that, an offset and a time zone). However (correct me if I'm wrong), Temporal doesn't consider Z to be UTC time zone, it only interprets it as 0 offset, that's why Temporal doesn't accept only Z. Example in Elixir: DateTime.from_naive!(~N[2000-01-01 00:00:00], "Etc/UTC") |> DateTime.to_string()
With other time zones than "Etc/UTC",
which is not even the format chosen by Temporal, because again, there are no standard representation (which seems to me really a pity by the way). In conclusion, it depends how we interpret the meaning of Z designator:
Wikipedia https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators states:
Do we then consider it as a UTC timestamp without zone information, or do we consider it is a datetime in the UTC time zone? Why not be pragmatic and let I could use I've browsed through my code, I use these utc timestamps for comparing, and The error for PlainDate, PlainDateTime, ... also depend on that interpretation of Z.
Overall I agree with you that I don't see use cases for a UTC date to be used other than logging, comparing, sorting, ... As a final note, I have to say I use |
We call them ISO 8601 strings out of habit, but the string format used in Temporal (which is also used by java.time, Joda/Noda time, etc.) will be likely be standardized by IETF, not ISO. We're working with IETF to standardize the time zone and calendar extensions to RFC 3339. Once the standard is approved, we'll update the docs and error messages of polyfills.
Yep, "Representing timezone-specific events where the time zone is not stored together with the date/time data." is the first use case mentioned in the
The former. Temporal places a lot of importance on the difference between an "offset" and a "time zone". The former (like For this reason,
The reason is because the data model of
If the string doesn't clearly have this assertion (in the form of a bracketed time zone annotation) then it's rejected. This rejection has the effect of forcing developers to provide the time zone in a different way, e.g.
This seems like the right outcome. If you are only comparing timestamps, then However, when you want to do things that do require a time zone and/or calendar (e.g. |
Thank you for the comprehensive replies:) One more thing: you wrote the time zone UTC in brackets as [UTC], but the time zone should be [Etc/UTC]. If we plan to accept [UTC] (for the reason that it is more convenient/less verbose/...), we might not be in line with the future IETF standard if they won't allow this, and then we might continue to accept non-standard strings for compatibility reasons. We can't technically call the string input as IETF strings in that case. That would be a pity for such a thing. But you might just have written a typo 😅 |
However, both Firefox and V8 canonicalize > new Intl.DateTimeFormat('en', {timeZone: 'Etc/UTC'}).resolvedOptions()
{
locale: 'en',
calendar: 'gregory',
numberingSystem: 'latn',
timeZone: 'UTC',
year: 'numeric',
month: 'numeric',
day: 'numeric'
} This is the result of an explicit algorithm step in CanonicalizeTimeZoneName, which Temporal also uses. So even if |
Fittingly there was a clarification update made to the documentation a couple of weeks ago. The description of
|
Oh I see! I never noticed that or forgot about it! 👍 |
That will take years right? The IETF mentions "JAVAZDT" to refer to the format Java Time (and Temporal) are using: https://www.ietf.org/archive/id/draft-ryzokuken-datetime-extended-02.html. I thought that maybe we can change ISO8601 to JAVAZDT in the error messages, and then replace it by the IETF standard. Feel free to close this issue by the way, if it no longer requires attention. Thank you for all the clarifications! |
When giving
PlainDateTime
a datetime string with time zone in brackets, the time zone is simply ignored:When giving
PlainDateTime
a datetime string with Z appended (UTC), an error occurs:When giving
ZonedDateTime
a datetime string with time zone in brackets:When giving
ZonedDateTime
a datetime string with Z appended (UTC), another error occurs:It is very common for programming languages to append Z on a datetime in UTC. My Elixir backend returns a string like
'2022-02-07T10:30:00Z'
and Temporal doesn't seem to give me an easy way to parse it.I don't see why time zones in brackets are allowed but not the Z designator.
The text was updated successfully, but these errors were encountered: