Skip to content

inconsistency problems of sub-minute offset in ZonedDateTime.from #3099

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

Open
fabon-f opened this issue Mar 3, 2025 · 8 comments · May be fixed by #3107
Open

inconsistency problems of sub-minute offset in ZonedDateTime.from #3099

fabon-f opened this issue Mar 3, 2025 · 8 comments · May be fixed by #3107
Labels
behavior Relating to behavior defined in the proposal meeting-agenda needs-review normative Would be a normative change to the proposal

Comments

@fabon-f
Copy link
Contributor

fabon-f commented Mar 3, 2025

Temporal.ZonedDateTime.from('1970-06-01T00:00:00-00:45[Africa/Monrovia]') // no error, OK
Temporal.ZonedDateTime.from('1970-06-01T00:00:00-00:44:30[Africa/Monrovia]') // no error, OK
Temporal.ZonedDateTime.from('1970-06-01T00:00:00-00:44:40[Africa/Monrovia]') // error, OK
Temporal.ZonedDateTime.from('1970-06-01T00:00:00-00:45:00[Africa/Monrovia]') // no error, OK?

Actual offset is -00:44:30 in this case, so accepting -00:45 (MATCH-MINUTES) and -00:44:30, rejecting -00:44:40 (wrong offset) makes a sense. The question is the 4th case, is it consistent to accept -00:45:00?

There is one more problem which I guess has same root cause (I haven't checked the spec yet though).

// looks fine
Temporal.ZonedDateTime.from({
  year: 1952, month: 10, day: 15, hour: 23, minute: 59, second: 59,
  timeZone: 'Pacific/Niue', offset: '-11:19:40'
}).offset // -11:19:40
Temporal.ZonedDateTime.from({
  year: 1952, month: 10, day: 15, hour: 23, minute: 59, second: 59,
  timeZone: 'Pacific/Niue', offset:'-11:20:00'
}).offset // -11:20
Temporal.ZonedDateTime.from('1952-10-15T23:59:59-11:19:40[Pacific/Niue]').offset // -11:19:40
Temporal.ZonedDateTime.from('1952-10-15T23:59:59-11:19:50[Pacific/Niue]') // error, wrong offset

// looks not fine
Temporal.ZonedDateTime.from('1952-10-15T23:59:59-11:20:00[Pacific/Niue]').offset // -11:19:40 (!!!)

// no problem
Temporal.ZonedDateTime.from('1910-12-31T23:59:59-03:40:40[America/Paramaribo]').offset // -03:40:40
Temporal.ZonedDateTime.from('1910-12-31T23:59:59-03:40:52[America/Paramaribo]').offset // -03:40:52

It seems that offset string -11:20:00 is treated same to -11:20 (ambiguous offset) in from method. If both offset (before and after the transition) has sub-minute part, this problem doesn't happen.

@gibson042
Copy link
Collaborator

gibson042 commented Mar 4, 2025

Thanks for the report! Without digging into spec text, my preference is to accept a sub-minute offset only when it matches the actual offset up to its specified precision:

Input Result Reason
1970-06-01T00:00:00-00:45[Africa/Monrovia] no error offset matches at minutes precision
1970-06-01T00:00:00-00:44:30[Africa/Monrovia] no error offset matches at seconds precision
1970-06-01T00:00:00-00:44:40[Africa/Monrovia] error offset does not match at seconds precision
1970-06-01T00:00:00-00:45:00[Africa/Monrovia] error offset does not match at seconds precision
1952-10-15T23:59:59-11:20[Pacific/Niue] no error offset matches at minutes precision
1952-10-15T23:59:59-11:19:40[Pacific/Niue] no error offset matches at seconds precision (pre-transition)
1952-10-15T23:59:59-11:20:00[Pacific/Niue] no error offset matches at seconds precision (post-transition)
1910-12-31T23:59:59-03:41[America/Paramaribo] no error offset matches at minutes precision
1910-12-31T23:59:59-03:40:40[America/Paramaribo] no error offset matches at seconds precision (pre-transition)
1910-12-31T23:59:59-03:40:52[America/Paramaribo] no error offset matches at seconds precision (post-transition)
1910-12-31T23:59:59-03:41:00[America/Paramaribo] error offset does not match at seconds precision

@fabon-f
Copy link
Contributor Author

fabon-f commented Mar 4, 2025

small correction: both -11:20:00 and -11:19:40 are valid offset for 1952-10-15T23:59:59 in Niue, because of backward offset transition of 20 seconds (a second after 23:59:59 was 23:59:40). So 1952-10-15T23:59:59-11:20:00[Pacific/Niue] would be post-transition moment (with offset -11:20:00) and wouldn't raise an error, according to the strict sub-minute offset rule mentioned above.

@gibson042
Copy link
Collaborator

Thanks for the correction; updated above.

@fabon-f
Copy link
Contributor Author

fabon-f commented Mar 8, 2025

When ToTemporalZonedDateTime parses string with time zone, matchBehaviour is always MATCH-MINUTES: https://tc39.es/proposal-temporal/#sec-temporal-totemporalzoneddatetime
And when matchBehaviour is MATCH-MINUTES, InterpretISODateTimeOffset checks whether given offsetNanoseconds equals to rounded candidateOffset in InterpretISODateTimeOffset. Since both -0:45 and -0:45:00 has same offset (2.7e12 nanoseconds), two offset strings behave in the same way.
https://tc39.es/proposal-temporal/#sec-temporal-interpretisodatetimeoffset

the result for Africa/Monrovia case:

offset string offsetNanoseconds candidateOffset (nanosec) rounded candidateOffset result in InterpretISODateTimeOffset
-0:44:30 -2670000000000 -2670000000000 -2700000000000 matched in step 10-b-i (exact match)
-0:44:40 -2680000000000 -2670000000000 -2700000000000 rejected
-0:45:00 -2700000000000 -2670000000000 -2700000000000 matched in step 10-c-ii-1 (match in minutes precision)
-0:45 -2700000000000 -2670000000000 -2700000000000 matched in step 10-c-ii-1 (match in minutes precision)

For the same reason, in Pacific/Niue case, the offset string -11:20:00 matches to the earlier moment (offset: -11:19:40) in step 10-c-ii-1 (at minutes precision), although later moment (offset: 11:20:00) would exactly match in step 10-b-i (according to compatible rule: earlier one if two moments exist).

I think setting matchBehaviour to MATCH-EXACT when the sub-minute offset is provided (even if 00) would produce the result as @gibson042 suggested above, in both cases.

@fabon-f
Copy link
Contributor Author

fabon-f commented Mar 8, 2025

Maybe the point is what kind of result is desirable for this case in terms of compatibility, interoperability, and extensibility of the spec, which I'm not sure about.

@gibson042 gibson042 added behavior Relating to behavior defined in the proposal meeting-agenda needs-review normative Would be a normative change to the proposal labels Mar 8, 2025
@fabon-f
Copy link
Contributor Author

fabon-f commented Apr 12, 2025

Is this topic already discussed among champions? If so and there's an agreement not to change current behavior, then it's fine. @ptomato

@ptomato
Copy link
Collaborator

ptomato commented Apr 23, 2025

It's on the agenda for the next time we meet.

@ptomato
Copy link
Collaborator

ptomato commented May 7, 2025

Note that if we made this change, the behaviour of the offset option in from() might be surprising:

> Temporal.ZonedDateTime.from("1970-01-01T12-00:45:00[Africa/Monrovia]", { offset: "use" })
Temporal.ZonedDateTime <1970-01-01T12:00:30-00:45[Africa/Monrovia]>
> Temporal.ZonedDateTime.from("1970-01-01T12-00:45:00[Africa/Monrovia]", { offset: "prefer" })
Temporal.ZonedDateTime <1970-01-01T12:00:00-00:45[Africa/Monrovia]>

It makes sense to me, but it surprised me when I was writing the tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
behavior Relating to behavior defined in the proposal meeting-agenda needs-review normative Would be a normative change to the proposal
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants