logoalt Hacker News

ravenstinetoday at 5:21 PM3 repliesview on HN

When I write JavaScript, I make as many things immutable as I can. Sometimes it adds verbosity and leads to less efficient computational patterns, but overall I believe I run into far fewer bugs that are hard to make sense of. There are things about the design of Temporal I don't really like, but immutability was a solid move.

What I don't understand is why they had to make string formatting so rigid. Maybe it has to do with internationalization? I'd have liked if it included a sort of templating system to make the construction of rendered date-time strings much easier.


Replies

WorldMakertoday at 5:52 PM

> What I don't understand is why they had to make string formatting so rigid. Maybe it has to do with internationalization? I'd have liked if it included a sort of templating system to make the construction of rendered date-time strings much easier.

I think Temporal takes the right approach: toString() is the (mostly) round-trippable ISO format (or close to it) and every other format is accessible by toLocaleString(). In Python terms, it is a bit like formally separating __repl__ and __str__ implementations, respectively. Date's toString() being locale-dependent made it a lot harder to round-trip Date in places like JSON documents if you forgot or missed toISOString().

Temporal's various toLocaleString() functions all take the same Intl.DateTimeFormat constructor parameters, especially its powerful options [1] argument, as Date's own toLocaleString() has had for a long while and has been the preferred approach to locale-aware string formatting.

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

show 1 reply
kandrostoday at 5:23 PM

I remember the first time I got in touch with Elixir and immutability as a core principle. It changed the way I wrote JavaScript since

devnotes77today at 7:04 PM

The formatting decision is intentional and documented in the proposal: toString() is meant to be the round-trippable ISO representation, not a display string. For locale-aware output, toLocaleString() accepts the full Intl.DateTimeFormat options bag, which covers most real-world display needs.

For non-locale custom formats ("YYYY-MM-DD" style), there is a gap - Temporal deliberately does not ship a strftime-style templating system. The design rationale was that custom format strings are a source of i18n bugs (hard-coded separators, month/day order assumptions, etc). The idea was to push display formatting toward Intl so locale handling is correct by default.

In practice you can cover most cases with something like:

  const d = Temporal.PlainDate.from('2026-03-11')
  const parts = d.toLocaleString('en-CA', {year:'numeric',month:'2-digit',day:'2-digit'})
for YYYY-MM-DD (Canadian locale uses that order). Fragile, but workable.

The V2 issue Dragory linked is exactly tracking this - custom format pattern support is on the backlog. For now, date-fns or luxon work fine alongside Temporal if you need templated strings.