9 ms·
Temporal is great. I've been using it for a while in production using a polyfill [1], and it solves all issues I've encountered with the old Date() API (which i
by phiresky 2y ago
Temporal is great. I've been using it for a while in production using a polyfill [1], and it solves all issues I've encountered with the old Date() API (which is a lot).
It clearly takes inspiration from other high-quality time libraries such as chrono in Rust and Joda Time in Java and combines them into a nice API that's pretty comfortable to use.
Yes, it is a bit more complex to handle since it separates time into naive time, instant and zoned time. But by experience, developers only confront complexity when they are forced to, and time _is_ complex.
If you want to do the operation "add one day to this timestamp", you _must_ decide whether that timestamp is local to a specific timezone and which one. Otherwise you'll get a bug twice per year due to DST, or when the user switches time zones, or when you deploy on a server with a different timezone.
It even solves the serialization issue of the difference between a "fixed-offset" timestamp (e.g. 2025-01-01T00:00+02:00) and one in a specific timezone (e.g. Europe/Paris).
[1]: https://www.npmjs.com/package/temporal-polyfill https://www.npmjs.com/package/temporal-polyfill
- tomtomtom777 2y ago> It even solves the serialization issue of the difference between a "fixed-offset" timestamp (e.g. 2025-01-01T00:00+02:00) and one in a specific timezone (e.g. Europe/Paris). Could you elaborate on that? What is the issue?
- SonOfLilit 2y agoEurope/Paris might change between now and the referenced time.
- Piskvorrr 2y agoIn other words, 2025-01-01T00:00+02:00 was NOT Europe/Paris (as it was CET at that time, GMT+1), 2024-08-01T00:00+02:00 could have been Europe/Paris (CEST, GMT+2), 2030-08-01T00:00+02:00 may be Europe/Paris (CEST, GMT+2), or perhaps not (CET, GMT+1). Or it may be a completely different TZ that incidentally shares the same offset at that time.
- burntsushi 2y agoThe issue is that if you have a timestamp (e.g., `2025-06-20T17:00:00+02:00`) and a time zone (e.g., `Europe/Paris`) and you go to serialize it, are you explicitly including the time zone in that serialization? And when you deserialize it, are you checking that the offset is still valid for that time zone at that time? Temporal fixes this by using RFC 9557[1], which includes the time zone in the serialized representation. RFC 9557 is a superset of RFC 3339. So where as previously you might just emit `2025-06-20T17:00:00+02:00`, using RFC 9557, you would emit `2025-06-20T17:00:00+02:00[Europe/Paris]`. For example, using Temporal: >> instant = Temporal.Instant.from('2025-06-20T17:00:00+02') >> zdt = instant.toZonedDateTimeISO("Europe/Paris") >> zdt.toJSON() "2025-06-20T17:00:00+02:00[Europe/Paris]" And when you go to deserialize an RFC 9557 timestamp, Temporal will do some validation to help ensure it's still correct. For example, you might serialize a RFC 9557 timestamp that is in the future, but at some later point, that region might abolish DST. At which point, your RFC 9557 timestamp might or might not resolve to the intended time. If it was in DST, Temporal will reject it at parsing time. You can read more about this at https://tc39.es/proposal-temporal/docs/zoneddatetime.html https://tc39.es/proposal-temporal/docs/zoneddatetime.html and search for "conflict". There's an example about Brazil abolishing DST in 2019 that should lay it out for you. Separately from even this, there are other concerns. If you forget to include the time zone in your serialization and then just deserialize it as a simple timestamp, then it makes it very easy for arithmetic on that value to be wrong because it won't be DST safe (unless you're careful to reconstitute its time zone somehow). With Temporal and RFC 9557, all of that is handled for you automatically. [1]: https://datatracker.ietf.org/doc/rfc9557/ https://datatracker.ietf.org/doc/rfc9557/
- vlovich123 2y agoI get that it’s more correct, but it assumes that Europe/Paris is a constant representation of how to apply the timezone-specific stuff but that’s incorrect. For example, ‘2025-06-20T17:00:00+02[Europe/Dublin]’ is a very different time if it’s created today vs if it were created in 1760 [1]. That’s a very extreme example, but timezone rules change and dates created from before the change was announced would be interpreted differently from ones created after they were announced. It’s interesting to me the standard doesn’t embed the creation time of the timestamp in UTC as well. https://en.wikipedia.org/wiki/Time_in_the_Republic_of_Ireland#History https://en.wikipedia.org/wiki/Time_in_the_Republic_of_Irelan...
- stewx 2y agoOne represents a time in a specific place, and one represents merely a shift from UTC. A specific time zone can have different offsets depending on the time of year, for example with Daylight Savings Time.
- amiga386 2y ago+02:00 is not political. It's an offset from UTC and will be the same offset in the past and future. Europe/Paris is political. It defines that offsets change at certain times of the year, but that could change tomorrow, or the political boundary that the timezone applies to could split such that the person or entity needing a time in their "local" timezone finds another one needs to be picked (see various US states/counties applying/disapplying daylight savings). It's impossible to be 100% confident what the offset from UTC will be at any time in the future. You also need to be a historian to correctly apply it to times in the past - take https://en.wikipedia.org/wiki/Time_in_the_Republic_of_Ireland#History https://en.wikipedia.org/wiki/Time_in_the_Republic_of_Irelan... as an example!
- Cthulhu_ 2y agoI wonder what happens when a timezone ceases to exist, e.g. what if Paris is renamed to New New York after the British take revenge and take over France.
- jitl 2y agoA timezone changing or being eliminated doesn’t erase the history of that timezone. So you can still use the last definition of such a timezone if the date is still in the future, or use the appropriate definition of the timezone at the time of a date marked in the past.
- williamdclt 2y ago> you can still use the last definition of such a timezone if the date is still in the future but that'll possibly give you an incorrect time! If you want to store "8am in Paris on the 2026-01-01", then you store "2026-01-01T08:00:00 Europe/Paris". Great, if Paris decides to change their offset rules, that's fine. Currently, that would be `2026-01-01T08:00:00+01:00` but if Paris decide to ditch DST, it could become `2026-01-01T08:00:00+00:00`. All good, you stored a timezone rather than an offset, so you're decoupled from the timezone->offset changes. But if tomorrow `Europe/Paris` cease to exist, and is replaced with Europe/NewNewYork? The last definition of Europe/Paris would make this date `2026-01-01T08:00:00+01:00`, but if Europe/NewNewYork ditched DST then it wouldn't be 8am for the people living there, it'd be 7am. You're decoupled from the timezone->offset changes, but not from location->timezone changes.
- MobiusHorizons 2y agoPlaces like Europe/Paris or America/Los Angeles can participate in daylight savings, and if they do, they may have different schedules, and those schedules may change at different points in history due to the passing of laws. Europe and the us already have a different schedule for daylight savings, and the whole west coast is trying to opt into permanent daylight savings for the last several years. But that would require an act of congress. Programmatically it mostly means you have to ship metadata about how the offsets change over time, which needs to be updated periodically. Browsers already ship that metadata, so it is really nice to finally have a way to access it from JavaScript without shipping the extra few tens of kilobytes.
- burntsushi 2y ago> It clearly takes inspiration from other high-quality time libraries such as chrono in Rust You might be interested in Jiff (a crate for Rust), which is inspired by Temporal. And here is a comparison I did with other datetime crates (including `chrono`): https://docs.rs/jiff/latest/jiff/_documentation/comparison/index.html https://docs.rs/jiff/latest/jiff/_documentation/comparison/i... I actually don't think Temporal takes a ton of inspiration from the `chrono` crate personally. I think it's definitely more from Joda (as you mentioned) or `java.time` these days, and some of the other Javascript datetime libraries that have cropped up over the years (thinking about date-fns and Moment.js).
- DanielHB 2y ago> time _is_ complex If only humans could read int64 epoch values
- AndrewStephens 2y agoAnd lived on a flat planet.
- moi2388 2y agoThat’s not a valid argument. There is no reason why people in Japan couldn’t start their workday at 03:00, or people in France at 22:00
- troupo 2y agoYou've just introduced timezones
- taeric 2y agoIt always cracks me up when people think they are proposing a simpler system by ignoring complexity. Is akin to people saying, "why don't we just change the start/end time of schools/businesses instead of changing the clock back?" As if getting companies to agree to when to make a change, and updating all of their documents/signage/etc. would somehow be easier than allowing them to continue to say "open at 8." For this one, It really amuses me on how they think they would accomplish keeping someone's phone to alarm at the equivalent of 7am when they fly across a nation. Granted, I still hold the silly view that we should probably change daylight savings time to be a 10 minute change of the clock every month. Up for six months, down for 6 months. Would effectively be trying to tie it to actual solar time, which is what we seem to care about. And would be trivial with modern devices. (Though, no, I don't hold that this will happen.)
- AndrewStephens 2y agoYour idea is a lot better than my plan. When I am king of the world, no business or transactions will be allowed to occur on Feb 29th. Instead, every 4th year there would be a nothing day, where nothing happens. So no systems would ever have to deal with leap days or 366 day years.
- klysm 2y agoI’m also using it in production and it’s so much better than any of the existing alternatives
- yread 2y agowhy does the polyfill have dependencies? And it's 200KB alone compared to 60KB of moment.
- numbsafari 2y agoDid you bother to look at it? It has a single dependency, and that single dependency has no dependencies of its own. So what is that dependency? "temporal-spec" And it looks like it comes from the same github repo. It basically looks like they broke out the API definitions so that they could be depended on by other potential implementations. This isn't atypical.
- yread 2y agoOh sorry I was looking at https://www.npmjs.com/package/@js-temporal/polyfill https://www.npmjs.com/package/@js-temporal/polyfill this one looks much better indeed
- evilduck 2y agoIf payload size is the top concern you shouldn't be using Moment either though. Luxon and DayJS are both considerably smaller (their uncompressed size is about what Moment's compressed size is) and the date-fns library is much, much smaller and also tree-shakeable. Moment also performs at or near the bottom of all available options if speed is a concern. Other than reflexive popularity or the cost already being paid there's not really a good reason to use it anymore.
- yread 2y agoExactly. I should've written even compared to moment
- michaelcampbell 2y ago> Otherwise you'll get a bug twice per year due to DST Those of us of a certain age learned long ago never to schedule cron (etc.) jobs in a production environment between 01:00 and 03:00 local time.
- wlesieutre 2y agoThat won't save you everywhere, Greenland falls back at midnight (12 AM Sunday to 11 PM Saturday) in order to synchronize their DST change with Europe https://www.timeanddate.com/time/change/greenland/nuuk https://www.timeanddate.com/time/change/greenland/nuuk
- yard2010 2y agoA long while ago my friend and I released a Safari extension that shows a few clocks in the timezones that you choose. I can't recall the details, but we had an off by 1 error on a few zones during DST. I ended up fixing it by hand changing the time, releasing a version every 6 months for years, otherwise we would get mails about it from the few users using it. I think I could automate this or otherwise solve the issue, but it always felt nice to move the clocks of a few hundred people.
- 2y ago
- stephen 2y agoSame! We've also been using the polyfill in production for a ~year or so. We recently configured the node-pg driver to leave the postgres DATE / TIMESTAMP / TIMESTAMPTZ dates as "just strings" (instead of its default parsing to JS dates), and then we go straight from strings -> temporals at our ORM layer, without the jank/hop of it first being a JS Date. ...shoot, we need to get the Temporal out-of-the-box support updated in our Joist (https://github.com/joist-orm/joist-orm/ https://github.com/joist-orm/joist-orm/) docs. :-/ But it's been great, having `DATE` in the db => `PlainDate` in the TS backend => `Date` in GraphQL API => `PlainDate` again in the TS/React FE. Very clean.
- WickyNilliams 2y agoIt's so much nicer than what we're used to working with! I built a set of low-level calendar components for building date/range pickers [0]. In anticipation of Temporal landing in browsers I decided to forgo Date (at least on the surface, I hid it away) and polyfilled the slither of Temporal I needed. When it lands I can just delete a bunch of code. The components come in at less than 10kb already, so I am looking forward to making them even slimmer! [0] https://wicky.nillia.ms/cally/ https://wicky.nillia.ms/cally/
- marxisttemp 2y agoSee also Swift’s built-in Date/DateComponents/Calendar types.
- LaGrange 2y agoThis is true, but there's one fly in the ointment I noticed: a lot of people _hate_ using time zones that refer to a real life location. They ain't gonna bother finding out whether "Europe/Paris" is like a wide slice of France or just specifically Paris, they don't want to tell you they live in Paris and will get annoyed. When using things to like, schedule online community events or whatever, this has been a pain. People _want_ to use fixed offset, they are fine with things like "CET/CEST", and _hate_ things like "Europe/yourexactcoordinates." And before you run into here, _I_ know time zones well enough to be chill - most of them (all?) are actually really large areas. But there's plenty of people who are both privacy-minded and not really interested in researching the differences between a "time" and a "time zone" or whatever because they aren't terminal dorks.
- sesm 2y ago> chrono in Rust and Joda Time in Java Those are from different time epochs, by the time Rust 1.0 was released, Java already had this approach implemented in standard library via java.time and didn't need any 3rd party libraries for this.
- jillesvangurp 2y agoJava.time basically is based on joda time and aside from slightly different package names is largely the same thing. That happened to more parts of the Java API. The concurrent package also started out as a standalone library. Joda time has inspired spinoffs on lots of platforms. Including js-joda for the javascript ecosystem. I'm not sure how much the new Temporal approach is based on that but it wouldn't surprise me that that was one of the starting points for the new standard.
- soheil 2y agoIf they had hurried up and released it before LLMs they might have actually saved hundreds of thousands of wasted development hours.
- modzu 2y agodear god i wish we could just end dst already
- obbfhjqsxjfqqbx 2y ago[dead]
- darepublic 2y agoNot all use cases related to time are too complex to just use the existing javascript Date
- jillesvangurp 2y agoSounds great. I've been working with kotlinx-date time for a few projects on both the JVM and in browsers using kotlin-js. Because this is a multiplaform library that needs to work on multiple platforms it sort of is stuck with the lowest common denominator; which on kotlin-js was the old Date API. The way this kotlin library works is that it implements a modern API that uses the underlying platform rather than re-implementing a bunch of things. This is mostly not a bad decision but it does have its limitations. One of the limitations is that not all platforms exposes a sane way to e.g. resolve timezones by their name and localize times while taking into account e.g. day light saving. Fixing that basically requires dealing with the time zone database and not all platforms expose that. I ran into this recently. I managed to work around it as this is something you can dig out of existing browser APIs but it was annoying having to deal with that. Unfortunately there are probably a few more obstacles on other Kotlin platforms.