-
Notifications
You must be signed in to change notification settings - Fork 152
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
Should Absolute.from() have an option to resolve offset vs. timezone conflicts? #716
Comments
@ptomato - I'm going to remove the zoned-type label from this issue because it's really focused on what we should do with the existing Absolute type, and it applies even if there's no |
ISO 8601 strings don't contain the time zone, they can only contain an offset: Why wouldn't we reject non-ISO strings? |
We use a (common) extension to the ISO format which puts the name of the time zone in brackets after the offset. |
For example Elixir won't accept a datetime string holding the time zone in brackets, as it is not conform to ISO. I think it's originally a Java thing. Actually there is no reason to have the time zone AND offset in the datetime string. It just helps to create errors and confusion.
But why support a datetime string with offset and time zone? Why not stick to ISO and reject all other strings? It's really just some food for thought, and I raise those questions here as this issue reveals exactly the problem with such strings. |
These are all good questions. Some have easier answers than others.
A datetime+timezone pair is not sufficient to uniquely identify a moment in time. Offset is required to disambiguate repeated wall-clock times, e.g. during the hour after DST ends in the Fall. Some apps may be OK to ignore this ambiguity while others may not. Therefore the default is to always persist the offset, and the default is to prefer the offset over the time zone if both are present. That said, it's a good idea to enable apps to avoid persisting the IANA identifier or the offset if their use cases don't need them. See #741 which is the persistence-time equivalent to this parse-time issue.
It's helpful to have a single-string format to enable interop between apps and platforms. While the bracketed Java extension isn't part of the ISO standard, it's popular across platforms and libraries so it's a reasonable alternative to asking every developer to create their own persistence format, which would make interop harder-- not just with Java, but also between different JavaScript apps and libraries.
Here's a few use cases why having all three pieces of data (the wall time, the offset, and the time zone) can be helpful:
I'm not saying that all apps need this flexibility. But mistakes in persistence can be hard or impossible to fix after the fact so it's smart to make the default "lossless" and to require apps to opt in to lossy persistence. |
Even a datetime+offset+time zone is not sufficient to identify a unique moment as datestring in time with time zone. You need to add the tzdata version to it. For example "2022-07-09T07:32:00" + "+02:00" + "Europe/Brussels" + "tzdata2020a" When storing the time zone separately for example in a database: I was not saying that devs should not store an offset and time zone together. I was saying that those should be stored separately instead of combining those into a string. Also about #741, sending a non-ISO-conform datetime string to my server (with time zone in brackets), will make my code crash (Elixir doesn't accept non-ISO strings). To have an ISO string you are required to add an option every time? Ooch.. That comes as a surprise. Pros/cons of supporting bracketed time zones in datetime strings -> PROS:
CONS:
Now if you allow only ISO strings, all this burden disappear:-D |
To add to the list of pros:
|
@ptomato it would be interesting to dig why ISO didn't embrace that extension adding the time zone. Probably for the same reasons:) We can see all it involves in the code and the questions that it raises. As I mentioned here #741 (comment), this is how we currently get an ISO string from a given absolute and a given time zone:
It requires to get the offset from a TimeZone and a given absolute, then calling toString on that same absolute. For example @justingrant proposed the toString of an absolute + given time zone to omit the time zone to stay ISO compliant, but the toString of a zoned datetime (if any) to output the time zone. Quoting from #741 (comment):
That would be confusing in my opinion. These will be the questions we will have to deal with if we work with the extended format, which we currently support and seem to favor over ISO. |
It's certainly reasonable that that use case needs to be made more convenient, but I don't see why that invalidates the whole idea of using a common extension to the ISO 8601 format. I don't think this is necessarily a bad habit. We already have a laundry list of ways in which the format we loosely refer to as "ISO" deviates from ISO 8601. Or, I should say, the current version of ISO 8601, because there were strings (such as MonthDay strings) accepted in ISO 8601:2000 that became forbidden in ISO 8601:2004. There is also RFC 3339 in common use which is almost like ISO 8601 but not quite: stricter in some ways, and looser in others. I think the reality is that we have to make these concessions due to the very common appearance around the web of not-quite-ISO strings. And this is by necessity a subjective judgement call. Clearly we should not accept wacky strings like See also #198 for discussions of some of these deviations. On some occasions the idea has been suggested to have a separate We also have an explainer that we are hoping to build wider consensus around so that eventually these extensions can one day be standards-tracked. |
I think having a |
I think the question is misguided, and here is why:
Because of that the actual IANA zone is only ever present if in storing the data it was intended to be the more important element. So the offset in that case is only meant to disambiguate. However it can only disambiguate fully if it throws an exception for the case where the offset is not valid for that datetime combination in that IANA zone. So that in turn means that in |
For past dates, it is the offset that is most important.
I didn't fully understand your arguments. I think you talk specifically about DST rule changes? But IANA changes are not limited to DST changes. Say some country, without any DST rules, had its offset to +7 somewhere in the past, but it needs to be corrected to +6. In that context, the options "earlier" and "later" are not relevant. In any case, I think throwing an exception because some random IANA change happened is not a good idea; you would have to add error handling code every time for any parsing of the extended format including an offset and a time zone. |
This comment has been minimized.
This comment has been minimized.
Now that we will have LocalDateTime, should we remove parsing and emitting of IANA time zones from Absolute? Might be cleaner to have all timezone-related serialization and deserializaton in one place. |
In my opinion: Remove from emitting yes. Remove from parsing in that the IANA time zone is ignored, but it is not an error to have one in a string passed to (Discussion about removal of emitting IANA time zones from Absolute: #741) |
Agreed. Let's leave this issue open until after LocalDateTime is merged, and then we can remove parsing (meaning what you said where the time zone is ignored) and emitting of IANA time zones in Absolute. |
I don't think a parsing method should ignore part of its input, especially when that can displace future events. If |
Hard disagree: all temporal types take input that overspecifies since that allows parsing parts of a whole. The IANA bracket is overspecified from an Absolute PoV and should just be ignored |
Previous discussions: #428 |
There's two questions here:
Did we already answer (1)? Should this behavior (whichever we decide for the default) be controllable by the Re: the default behavior, I think there are good arguments on both sides. @gibson042 is correct that catching conflicts here could be useful. I also agree with @pipobscure that ignoring out-of-scope data is more consistent with the rest of Temporal. So I don't have a strong opinion about what the default should be. FWIW,
Although I'm very open to being convinced otherwise, I lean towards ignoring conflicts, because someone using But I'm open to other arguments too; I don't have a strong opinion here. BTW, I also might be suggesting this because "ignore" coincidentally matches an idea I had for a PR to the docs to better explain Temporal ISO 8601 parsing, via a visual diagram that maps string parts to Temporal types. If folks like the idea, I can PR it at some point. Something like this: |
Ignoring in |
+1 to your diagram.
That sounds bad to me. Generally, the offset and IANA name will match; it is rare that they don't match. Most (basically all) developers won't think about or handle the reject case, which means that their app will crash. I think defaulting to absolute disambiguation is almost always the right choice. |
I remain opposed to ignoring time elements, especially when an inconsistency can change the results—silent failures are even worse than unexpected errors. Anyone wanting to ignore the time zone and extract fixed-offset instants from strings like "2020-08-06T08:15+09:00[Undisclosed]" should be using |
Update: I was convinced in the meeting that it is acceptable to treat string input as a representation of structured fields and subsequently ignore irrelevant fields as with objects, subject to syntactic conformance with a well-documented format. Basically, |
Conclusions from 2020-08-20:
|
When parsing an ISO 8601 string, Temporal.Absolute.from should always use the offset, and ignore the bracketed IANA name, even if the two disagree. Closes: #716
When parsing an ISO 8601 string, Temporal.Absolute.from should always use the offset, and ignore the bracketed IANA name, even if the two disagree. Closes: #716
I have this in a branch at https://github.com/tc39/proposal-temporal/tree/716-741-absolute-zone-names but it should not be merged until LocalDateTime lands. |
When parsing an ISO 8601 string, Temporal.Absolute.from should always use the offset, and ignore the bracketed IANA name, even if the two disagree. Closes: #716
When parsing an ISO 8601 string, Temporal.Absolute.from should always use the offset, and ignore the bracketed IANA name, even if the two disagree. Closes: #716
What still needs to be discussed in this issue? Is the open question whether |
I believe we agreed that we'd ignore the IANA name in this case.
Sent from my mobile device.
…________________________________
From: Philip Chimento <[email protected]>
Sent: Friday, September 11, 2020 5:54:06 PM
To: tc39/proposal-temporal <[email protected]>
Cc: Justin Grant <[email protected]>; Mention <[email protected]>
Subject: Re: [tc39/proposal-temporal] Should Absolute.from() have an option to resolve offset vs. timezone conflicts? (#716)
What still needs to be discussed in this issue? Is the open question whether Temporal.Absolute.from('2020-08-05T20:06:13+09:00[Asia/Tokyo]') should throw or not? (IMO, no, it should ignore the IANA name.)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<#716 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AACDVXWKX5A6YBU2SFU2PKDSFLBC5ANCNFSM4ONSAAKA>.
|
When parsing an ISO 8601 string, Temporal.Instant.from should always use the offset, and ignore the bracketed IANA name, even if the two disagree. Closes: #716
When parsing an ISO 8601 string, Temporal.Instant.from should always use the offset, and ignore the bracketed IANA name, even if the two disagree. Closes: #716 Co-authored-by: Ujjwal Sharma <[email protected]>
Should Temporal should have a way to handle offset-vs.-zone conflicts when parsing ISO strings by giving users an option in
Absolute.from
to choose whether IANA time zone definition rules or time zone offset should "win" if they conflict? (This only applies when parsing anAbsolute
from an extended ISO string with both an IANA suffix and an offset.)As @gibson042 has raised, ISO strings that are valid when stored can end up conflicting between the offset and the time zone if the time zone definition is changed after the ISO string is stored. For example, when Western Europe permanently stops observing DST in 2021 (unless it's postponed again), far-future times that were stored before the tzData change may have a conflict between the persisted time zone offset (reflecting the old time zone rules) and the new time zone rules which might require a different offset for that stored instant.
This won't be a common case, but it will certainly happen, especially after the 2021 change in Europe which will coincidentally be around the same time that the first Temporal usage may be going into production.
To handle this potential conflict, #700 proposes a configuration option key
offset
for theLocalDateTime.from
method. But @ptomato noted in #700 (comment) that this problem applies toAbsolute
too:@sffc raised the same concern in #706 (comment)
So I'm filing this issue to close the loop.
Here's the proposed option used in
LocalDateTime.from
in #700:I have no strong opinion about the naming of this property or of the individual option strings.
I do have a moderately-strong opinion that the offset should win by default because:
reject
seems contrary to our general "don't throw by default" approach taken for handling DST ambiguity, overflows, etc.Absolute
it seems reasonable to prioritize theAbsolute
value that was originally stored so that round-tripping anAbsolute
to a string will always result in the same value, even if its local time is now different.Absolute.from
doesn't have an options parameter today so there's no naming conflicts. That said, #607 applies here too: if we do adopt aLocalDateTime
type then we'll have methods that accept multiple options properties. Naming them alldisambiguation
(even for different kinds of disambiguation) will make it harder to interop betweenLocalDateTime
and other Temporal types.The text was updated successfully, but these errors were encountered: