Skip to content

Distinction between ambiguous and nonexistent times #35

@lutzky

Description

@lutzky

Add a way to distinguish the two failure cases for {disambiguation: 'reject'} (where, due to a clock change, either the local time in question can represent zero or two times).

This is a follow-up for tc39/proposal-temporal#3111.

Possible syntaxes:

// Option 1
Temporal.ZonedDateTime.from(t, {disambiguation: 'explicit'})

// Option 2
Temporal.ZonedDateTime.getPossibleInstantsFor(t)

Expected output, for either option, calling it f:

tz = 'Europe/Dublin'; // Specifically for the following example

// ordinary time
f({timeZone: tz, year: 2025, month: 5, day: 26, hour: 1, minute: 30});
// [Temporal.ZonedDateTime(2025-05-26T01:30:00+01:00[Europe/Dublin]]

// mid-spring-forward
f({timeZone: tz, year: 2025, month: 3, day: 30, hour: 1, minute: 30});
// []

// mid-fall-back
f({timeZone: tz, year: 2025, month: 10, day: 26, hour: 1, minute: 30});
// [
//     Temporal.ZonedDateTime(2025-10-26T01:30:00+01:00[Europe/Dublin], 
//     Temporal.ZonedDateTime(2025-10-26T01:30:00+00:00[Europe/Dublin]
// ]

Notably, this can already (with Temporal v1) be implemented by the workaround described in chronotope/chrono#1701 (comment).

Advantages:

Advantages of being able to distinguish the two cases:

  • Enable the UI to show an error when selecting a nonexistent time
  • Enable development of a UI to allow the user to make a specific choice when the time is ambiguous

However, technically the ability to distinguish is already possible with the workaround from chronotope/chrono#1701 (comment). The advantages of this proposal are:

  • Improve ergonomics
  • Improve performance (workaround requires 2-3 calls to ZonedDateTime.from and 1-2 .equals() comparisons between results)

Concerns:

None from me.

Prior art:

This is roughly analogous to a Rust library: chrono's MappedLocalTime. In fact, it is proposed here as a result of chronotope/chrono#1701 - where this distinction is not possible in Rust-WASM due to shortcomings of Date, and is possible with a workaround using Temporal-v1. This proposal only makes it ergonomic.

Constraints / corner cases:

n/a - this feature is all about handling a constraint/corner-case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions