Skip to content

Replace js-joda with JavaScript Temporal #501

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
YarnSphere opened this issue Mar 16, 2025 · 5 comments
Open

Replace js-joda with JavaScript Temporal #501

YarnSphere opened this issue Mar 16, 2025 · 5 comments

Comments

@YarnSphere
Copy link

YarnSphere commented Mar 16, 2025

With Temporal being a stage 3 proposal and starting to be implemented in browsers, I was wondering if the kotlinx-datetime team has any plans to ditch js-joda in favour of Temporal for the JS targets.

Due to Temporal supporting timezones natively, this would have the added benefit that users would no longer need to install a separate library to handle them.

While Temporal is in the process of being shipped in browsers and other engines, kotlinx-datetime could encourage users to install one of the existing polyfills, knowing that at some point in the future, said polyfills would no longer be necessary.

I'm opening this issue in order to track any progress in this area, if such a task is on the team's radar. Hope that's okay. 😄

@dkhalanskyjb
Copy link
Collaborator

I was wondering if the kotlinx-datetime team has any plans to ditch js-joda in favour of Temporal for the JS targets.

There is only a tiny piece of js-joda that we still use, and that's their timezone database. The only piece of Temporal that is aware of timezones is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime, I believe, and it doesn't expose enough of the timezone database for us to be able to reimplement all the functionality we need. For example, to implement LocalDate.atStartOfDayIn(TimeZone), if there is a time gap at 00:00 at the given date, we need to find the first moment that happens after that gap, but this gap resolution strategy is not among the list of strategies provided in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#ambiguity_and_gaps_from_local_time_to_utc_time.

So, unfortunately, it's not possible for us to reimplement our functionality on top of Temporal in its current form.

@dkhalanskyjb dkhalanskyjb closed this as not planned Won't fix, can't repro, duplicate, stale Mar 17, 2025
@YarnSphere
Copy link
Author

ZonedDateTime offers a startOfDay which seems to have similar semantics:

The startOfDay() method of Temporal.ZonedDateTime instances returns a Temporal.ZonedDateTime object representing the first instant of this date in the time zone. It usually has a time of 00:00:00, but may be different if the midnight doesn't exist due to offset changes, in which case the first time that exists is returned.

Also, it seems like you can convert a PlainDate into a ZonedDateTime via toZonedDateTime which, by default, seems to have similar semantics to atStartOfDayIn:

Defaults to the first valid time in this time zone on this calendar date, which is usually "00:00:00", but may be different if, for example, daylight saving time skips midnight.

Apologies if I'm just ignorant on this matter, but do these methods somehow offer different semantics from those expected by kotlinx-datetime? I'm sure you're right in that the spec doesn't expose much of the timezone database, but is it not at all possible to implement kotlinx-datetime's API simply using Temporal's API without having to implement the operations "directly"?

@YarnSphere
Copy link
Author

Rereading your comment (apologies), you're saying that the disambiguation policy employed by LocalDate.atStartOfDayIn(TimeZone) is none of the ones listed in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#ambiguity_and_gaps_from_local_time_to_utc_time?

if there is a time gap at 00:00 at the given date, we need to find the first moment that happens after that gap

How does this differ from the later disambiguation option?

If there are two possible instants, choose the later one. If there is a gap, go forward by the gap duration.

Although it might already be too late, it would be nice to understand exactly what features Temporal lacks that kotlinx-datetime would require to implement its API on top of it, so that such needs could be possibly reported to the Temporal spec developers.

In this case, you're saying that Temporal would need a new disambiguation option for it to be compatible with kotlinx-datetime's semantics?

@dkhalanskyjb
Copy link
Collaborator

ZonedDateTime offers a startOfDay which seems to have similar semantics

Oh, okay. This means that we probably can implement LocalDate.atStartOfDay after all. Then some other examples: we probably can't implement the check for whether a time zone is fixed-offset (and make it an instance of a FixedOffsetTimeZone if so), and we won't be able to implement the general resolver logic needed for #237

How does this differ from the later disambiguation option?

If clocks jumped from 23:29 directly to 00:30 and we ask for 00:00, later should return 01:00, but we actually need 00:30.

In this case, you're saying that Temporal would need a new disambiguation option for it to be compatible with kotlinx-datetime's semantics?

In the current state of the library, possibly not. In the planned state of our library, we need either the direct access to the timezone database or at least something similar to https://en.cppreference.com/w/cpp/chrono/local_info

@dkhalanskyjb dkhalanskyjb reopened this Mar 19, 2025
@dkhalanskyjb
Copy link
Collaborator

Having researched some more, I believe now that it's possible, albeit cumbersome, to use the Temporal as our backend if we have to. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/getTimeZoneTransition is the key to that. Thanks for raising this issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants