This article lists several of the absurdities of the Date constructor, but only barely touches on the most unforgivable one. The example from the article is:
// Unless, of course, you separate the year, month, and date with hyphens.
// Then it gets the _day_ wrong.
console.log( new Date('2026-01-02') );
// Result: Date Thu Jan 01 2026 19:00:00 GMT-0500 (Eastern Standard Time)
In this example, the day is "wrong" because the constructor input is being interpreted as midnight UTC on January 2nd, and at that instantaneous point in time, it is 7pm on January 1st in Eastern Standard Time (which is the author's local time zone).
What's actually happening here is a comedy of errors. JavaScript is interpreting that particular string format ("YYYY-MM-DD") as an ISO 8601 date-only form. ISO 8601 specifies that if no time zone designator is provided, the time is assumed to be in local time. The ES5 spec authors intended to match ISO 8601 behavior, but somehow accidentally changed this to 'The value of an absent time zone offset is “Z”' (UTC).
Years later, they had realized their mistakes, and attempted to correct it in ES2015. And you can probably predict what happened. When browsers shipped the correct behavior, they got too many reports about websites which were relying on the previous incorrect behavior. So it got completely rolled back, sacrificed to the altar of "web compatibility."
For more info, see the "Broken Parser" section towards the bottom of this article:
>So it got completely rolled back, sacrificed to the altar of "web compatibility."
This is why I don't understand the lack of directives.
'use strict'; at the top of a file was ubiquitous for a long time and it worked. It didn't force rolling back incompatibilities, it let you opt into a stricter parsing of JavaScript.
It would have been nice for other wide changes like this to have like a 'strict datetime'; directive which would opt you into using this corrected behavior.
They couldn't and shouldn't do this sort of thing for all changes, but for really major changes to the platform this would be an improvement.
Or they could go all in on internal modules, like how you can import `node:fs` now. They could include corrected versions of globals like
To be fair, the new opt-in "use strict" here is "switch to Temporal". It's a new, stricter namespace object. Old Date code gets the old Date code quirks, new code gets the nice new Temporal API.
Internal modules would be handy in theory to maybe keep from having to dig through a thesaurus every time browsers decide to add a new, stricter version of an older API. Internal modules have even been proposed to TC-39 as a recommended way to continue to expand the JS API. Last I checked on that proposal it was stuck behind several concerns including:
1. Feature detection: detecting if Temporal available is as easy as `if ('Temporal' in globalThis) {}`, but detecting if a module import is missing is a bit harder. Right now the standard is that loading a module fails with an Error if one of its imports fails. You can work around that by doing a dynamic import inside a try/catch, but that's a lot of extra boilerplate compared to `const thingINeed = 'someApi' in globalThis ? someApi() : someApiPolyfill()`. I've seen multiple proposals on that front from extensions to import maps and `with { }` options on the import itself.
2. Bikeshedding (and lots of it): defining a URI scheme like `browser:` or `standard:` takes a bunch of thought on how you expand it. If it is just `browser:some-api` you run the risk of eventually polluting all the easy names in the exact way people worry about the risk of over-polluting `globalThis` (and in the way that it can be weirdly hard to find an available one-word name on npm), you've just moved the naming problem from one place to the other. On the other side, if you go down the road of something like `es-standard:https://tc39.es/ecma262/2025/v1/final-draft/Temporal`, even (especially) assuming users would mostly importmap that to something shorter you've recreated XMLNS URIs in a funny new hat and people who use JS all certainly have plenty of opinions on XMLNS URIs, many are very vocal in their hatred of it, but also they came out of a strong backwards incompatibility fixing desire exactly like this. (As they say time is a flat circle.)
> It would have been nice for other wide changes like this to have like a 'strict datetime'; directive which would opt you into using this corrected behavior.
That would be ugly, because you'd want some parts of your program (eg libraries) to use the old behaviour, and other parts might want the new behaviour. How would you minify multiple modules together if they all expect different behaviour from the standard library?
In my opinion the right way to do this is to have multiple constructors (as Obj-C, swift, C and rust all do). Eg:
let d = new Date(...) // old behaviour (not recommended for new code)
let d = Date.fromISOString(...) // fixed behaviour
The big downside of this is that its tricky to keep track of which fields and functions people should really stop using in modern javascript. It'd be nice if there was a way to enable more shouty warnings during development for deprecated JS features.
I find it very unfortunate that browsers (or rather, the spec) do not support some kind of versioning. If we could declare which version of HTML, JS and CSS to use, it would allow for breaking changes without breaking the entire web.
There are so many (in hindsight bad) design choices and implementation accidents that currently exist in perpetuity because of backwards compatibility; the web would really benefit if every now and then we could shed old baggage.
This was the approach Perl took and much as I love(d) that language, it do get pretty out of hand after a while if you wanted to adopt any newer or stricter language features.
directives sort of kinda work if you squint the eyes, but only as a crutch and only if you can't/don't want to change the API.
> Or they could go all in on internal modules, like how you can import `node:fs` now. They could include corrected versions of globals like
`import Date from 'browser:date';`
This is what happened here, only the API changed as well
I very much remember coding a function that split the string on their components and then rebuild them to ensure the date was created without time zone.
Sometimes a date is just a date. Your birthday is on a date, it doesn't shift by x hours because you moved to another state.
The old Outlook marked birthdays as all-day events, but stored the value with time-zone, meaning all birthdays of people whose birthday I stored in Belgium were now shifted as I moved to California...
I always found it weird when systems code dates as DateTime strings. There needs to be a different primitive for Date, which is inherently timezone-less, and DateTime, which does require a timezone.
After having a bunch of problems with dealing with Dates coded as DateTime, I've begun coding dates as a Date primitive, and wrote functions for calculation between dates ensuring that timezone never creeps its way into it. If there is ever a DateTime string in a Date column in the database, it's impossible to know what the date was supposed to be unless you know you normalized it at some point on the way up.
Then I found that a lot of DatePicker libraries, despite being in "DATE" picker mode, will still append a local timezone to its value. So I had to write a sanitizer for stripping out the TZ before sending up to the server.
That said, I am pretty excited about Temporal, it'll still make other things easier.
I mean... That's kinda how it works? More than once I've halfway forgotten birthdays of friends who live in timezones to my east, and then sent them a message saying "Happy birthday! (It still is where I am, lol)".
I'm not necessarily defending the implementation, just pointing out another way in which time is irreducibly ambiguous and cursed.
I agree with the "don't break the web" design principle, but I sometimes disagree with precisely where TC39 draws the line. There is obviously a cost to breaking old, unchanging websites. But there's also a cost to allowing old, unchanging websites to hold the entire web hostage. Balancing those costs is a subjective matter.
As far as I know, TC39 doesn't have any clear guidelines about how many websites or how many users must be affected in order to reject a proposed change to JavaScript behavior. Clearly there are breaking changes that are so insignificant that TC39 should ignore them (imagine a website with some JavaScript that simply iterates over every built-in API and crashes if any of them ever change).
Have an optional parameter to opt in to the old behaviour and keep the new correct behaviour the default (without the parameter) seems like a decent choice.
Nah, that's not a "sacrifice", but the only sane way. In the ideal case, clearly document the constructor with a warning that it's not ISO conformant and offer a ISO conformant alternative.
In my (unfortunate) experience, DateTime/Timezone handling is one of the things most prone to introduce sneaky, but far-reaching bugs as it is. Introducing such a behaviour change that (usually) won't fail-fast, will often seemingly continue working as before until it doesn't and is deceptively tricky to debug/pinpoint/fix ist just asking for a fast lane into chaos.
And even with JS going the extra mile on backwards compatibility, I don't think most other languages would introduce that kind of breaking change in that way either.
Personally, I like that UTC is the default time zone. Processing of dates should happen in a standardized time zone. It’s only when you want to display it that the date should become local.
UTC is a fine default time zone, but that doesn't matter here.
A datetime with a timezone and a datetime without one are two different things, both of them useful. My birthday does not have a time zone. My deadline does.
The company deadline for getting some document returned? It might or might not, that's policy.
Poetically: we are born free of time zones. We die bound to one.
This will result in incorrect behavior when, between converting to UTC and back to the original timezone, the timezone database has changed, which happens more often than you think.
It's a common source of off-by-one date formatting bugs in client-rendered web apps, particularly ones that pass around "YYYY-MM-DD" date strings (common for OpenAPI JSON APIs).
const dateStringFromApiResponse = "2026-01-12";
const date = new Date(dateStringFromApiResponse);
const formatter = new Intl.DateTimeFormat('en-US', { dateStyle: 'long' });
formatter.format(new Date("2026-01-12"));
// 'January 11, 2026'
Local time is unparsable, and this case is only human readable, because humans can handle ambiguity ad hoc. Parsing it as UTC is a reasonable default for a machine parser, at least the only workable one.
There's a lot wrong with Javascript's Date, but the fact that it's an object is is not really in the top 10.
Would it have been nice if the Date object had been immutable? Sure, but the fact that changing the mutable object does indeed change the object shouldn't be a shock
What happened to me is I passed a date to an external library, and then after that library did its work, that date was changed. Super annoying even if you know that it's a mutable object.
It's definitely a shock when something else changes the date object you've been holding on to. The problem with mutable values has never been when you (that is, the local context) change them. It's always that you can't trust that nothing else (some very non-local code) does.
This is a skill issue imo. Yes, if you change the referenced object you get a different value. Just because you are not paying attention to the change does not a problem of the language make.
There are million other things legitimately wrong wit JS, developers being bad at understanding referenced objects is not one of them.
I do find it annoying how the Temporal API, just like nearly all other datetime APIs, has 0 support for querying leap-second information in any shape or form. Suggested workarounds like temporal-tai all require plugging in a leap-second file and keeping it updated, which is especially painful for client-side JS, where you can't just download a leap-second file from someone else's site thanks to the SOP. Meanwhile, browsers update on a cadence more than sufficient to keep an up-to-date copy, but the datetime APIs refuse to expose leap-second info because they're too committed to "only UTC is in-scope for this project".
(The context is that I want to write some JS tools for astronomical calculations, but UTC conversions need leap-second info, so this trend makes it impossible to write something that Just Works™.)
>only UTC is in-scope for this project
>tools for astronomical calculations
Pity, since UTC is objectively the wrong time for astronomical calculations. Among other problems, UTC runs slightly slower or faster depending on how far the Earth is from the Sun. UTC does not run uniformly (outside of Earth-at-sealevel), instead the length of 1 second will slightly grow or shrink depending on the current configuration of the Solar system.
As you allude to, the correct time scale for this purpose would be TBD (aka Barycentric Dynamical Time), which applies relativistic corrections to act like the atomic clock is fixed at the barycentre of the Solar system. This is the only clock that actually runs "smoothly" for the purposes of astronomical calculations.
> Among other problems, UTC runs slightly slower or faster depending on how far the Earth is from the Sun. UTC does not run uniformly (apart from Earth-at-sealevel), instead the length of 1 second will slightly grow or shrink depending on the current configuration of the Solar system.
That is completely wrong. UTC seconds are exactly SI seconds, which are all the same uniform length (defined by quorum of atomic clocks).
> where you can't just download a leap-second file from someone else's site thanks to the SOP
WDYM by this? Why does the SOP prevent a website from hosting a leap seconds file? All they need to do is set Access-Control-Allow-Origin to allow websites to access it. Or provide it as a JS file—in which case no headers are necessary at all. All the SOP prevents is you hotlinking someone else's leap-seconds file and using their bandwidth without their opt-in.
> Meanwhile, browsers update on a cadence more than sufficient to keep an up-to-date copy
Is this true? I don't know any browser right now that ships with a copy of a leapseconds data file. Adding such a data file and keeping it up to date would probably be a pretty non-trivial task for new browser developers—just for something the browser will never end up using itself. It's not like the ICU/CLDR files where browsers are going to need them anyway for rendering their own user-interface components.
> All they need to do is set Access-Control-Allow-Origin to allow websites to access it. All the SOP prevents is you hotlinking someone else's leap-seconds file and using their bandwidth without their opt-in.
They can, but the major providers (read: the ones I would trust to update it) don't. The IERS doesn't [0], the USNO doesn't [1], IANA doesn't [2], and NIST uses FTP [3]. Keep in mind that these files are constantly being downloaded by various clients for NTP and whatnot, it's not like these providers want to restrict public access, they just don't bother to set the header that would allow JS requests.
> Is this true? I don't know any browser right now that ships with a copy of a leapseconds data file.
From ECMA-262:
> It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.
Any browser that ships with a copy of tzdb, or knows where to find a copy from the OS, should have access to its leapseconds file. Unless you mean that all of them go solely through ICU and its data files? Which I suppose could be an obstacle unless ICU were to start exposing them.
> but the datetime APIs refuse to expose leap-second info because they're too committed to "only UTC is in-scope for this project".
This doesn't make sense on at least two different levels.
First, pedantically, the definition of UTC as a time scale is that it includes leap seconds. So if you're committed to UTC, then you're supporting leap seconds.
Second, and to more broadly address your point, you should say, "they're too committed to 'only the POSIX time scale is in-scope for this project.'" That more accurately captures the status quo and also intimates the problem: aside from specialty applications, basically everything is built on POSIX time, which specifically ignores the existence of leap seconds.
Sure, but my gripe isn't even that we ought to change the "POSIX time by default" status quo (the ship has long sailed that everyone counts durations by 'calendar seconds'), it's that the underlying libraries don't even provide enough information for "specialty applications" to reliably correct for it, short of perpetually updating it themselves.
> I do find it annoying how the Temporal API, just like nearly all other datetime APIs, has 0 support for querying leap-second information in any shape or form.
That’s because human time keeping doesn’t use leap seconds.
> like nearly all other datetime APIs, has 0 support for querying leap-second information
That's probably because you only need leap second accuracy in niche use cases, like astronomy or GPS. In JavaScript specifically, that kind of accuracy isn't needed for 99% of client-side use cases. Most date-time libraries work with POSIX time which assumes 86,400 seconds each day.
We’ve been loving using it in our Deno servers since last year. It’s been frustrating that we haven’t been able to upgrade our web client date logic yet, since even though Firefox has supported Temporal for a while, Chrome have really dragged their feet
I don't know if that's totally fair to Chrome. The specification was undergoing a lot of changes at the time, and V8 decided to wait for the specification to stabilize; meanwhile, Anba kept working on the implementation for FireFox. Additionally, the version of Temporal that Deno exposed last year was the heavily out of date to the most recent specification and had a large portion of the specification that was not even implemented.
It is a lot more complex than moment, but only because there's a lot of inherent complexity to dates and times that moment just doesn't deal with. So you need to be explicit about whether you're dealing with dates, times, or datetime objects, whether or not the object you're working with has a timezone, etc. Where moment is generally designed to have a convenient API, Temporal is designed to have a correct API.
The main selling point for me is that it has proper data times for dates, times, etc.
Most date/time libraries that I've seen have a only single "date/time" or "timestamp" type, then they have to do things like representing "January 13 2026" as "January 13 2026 at midnight local time" or "January 13 2026 at midnight UTC."
Temporal has full-fledged data types representing the different concepts: an Instant is a point in time. A PlainDate is just a date. A PlainTime is just a time. ("We eat lunch at 11am each day.") A ZonedDateTime is an Instant in a known time zone. Etc.
Temporal draws a lot of inspiration from Java's Joda-Time (which also went on to inspire .NET's Noda Time, Java's official java.time API, and JavaScript's js-joda). This is helpful; it means that some concepts can transfer if you're working in other languages. And, more importantly, it means that it benefits from a lot of careful thought on how to ergonomically and effectively represent date/time complexities.
> When an immutable value is assigned to a variable, the JavaScript engine creates a copy of that value and stores the copy in memory
Not exactly. The language doesn't specify whether the value is copied or not and, precisely because values are immutable, there's no way for a user to tell if it was or wasn't.
For example, strings are also immutable value types, but you can be certain that no JS engine is fully copying the entire string every time you assign one to a variable or pass it to a parameter.
Late to the party, I really wish everyone would copy Rails + Ruby, but specifically it's Rails additions.
2 things it got right:
1. Like the article a great API - Time.current.in_time_zone('America/Los_Angeles') + 3.days - 4.months + 1.hour
2. Rails overloads Ruby's core library Time. You're in 1 object the whole time no swap/wondering.
In the py world, pendulum is close but just like the article, it's cumbersome as it's still a separate obj (i.e. Temporal vs Date) and so you need to "figure out" what you have to manipulate or need to cast it first.
Overloading the core libs is dangerous for a whole host of reasons but for the end developer it's a pleasure to use.
If we could just do `new Date().add({ days: 1})` it would be so easier.
Is this what it looks like? A specific concept like time units being defined as members of more general types like numbers? I.e. if I type `1.` to get auto-complete, am I going to see days, and all the rest, as options?? That API design pattern would be a nightmare!
In Ruby, I assume this is done by monkey patching, so yes, it would have all the issues you mention and fear.
In more modern languages like Kotlin, there is a notion of extension methods and properties, where you would be able to write a library that allows this syntax, but the .days property would only be accessible in files where you have explicitly imported it (so basically a synthetic sugar for a static function call).
Here is the neat part about Ruby, your autocomplete barely works and your IDE can only guess what you want, instead of relying on a good language service…
And yet people have been using it for decades without much trouble. I can't remember ever seeing any complaints about API explosion from adding methods to numbers in ruby, and rails does a fair bit of it.
Possibly one reason is with a fluent API that's pretty understandable, you don't need to rely on autocomplete. (And indeed, all this happened before that was a big thing in tooling.)
// A numeric string between 32 and 49 is assumed to be in the 2000s:
console.log( new Date( "49" ) );
// Result: Date Fri Jan 01 2049 00:00:00 GMT-0500 (Eastern Standard Time)
// A numeric string between 33 and 99 is assumed to be in the 1900s:
console.log( new Date( "99" ) );
// Result: Date Fri Jan 01 1999 00:00:00 GMT-0500 (Eastern Standard Time)
What's actually happening here is a comedy of errors. JavaScript is interpreting that particular string format ("YYYY-MM-DD") as an ISO 8601 date-only form. ISO 8601 specifies that if no time zone designator is provided, the time is assumed to be in local time. The ES5 spec authors intended to match ISO 8601 behavior, but somehow accidentally changed this to 'The value of an absent time zone offset is “Z”' (UTC).
Years later, they had realized their mistakes, and attempted to correct it in ES2015. And you can probably predict what happened. When browsers shipped the correct behavior, they got too many reports about websites which were relying on the previous incorrect behavior. So it got completely rolled back, sacrificed to the altar of "web compatibility."
For more info, see the "Broken Parser" section towards the bottom of this article:
https://maggiepint.com/2017/04/11/fixing-javascript-date-web...
This is why I don't understand the lack of directives.
'use strict'; at the top of a file was ubiquitous for a long time and it worked. It didn't force rolling back incompatibilities, it let you opt into a stricter parsing of JavaScript.
It would have been nice for other wide changes like this to have like a 'strict datetime'; directive which would opt you into using this corrected behavior.
They couldn't and shouldn't do this sort of thing for all changes, but for really major changes to the platform this would be an improvement.
Or they could go all in on internal modules, like how you can import `node:fs` now. They could include corrected versions of globals like
`import Date from 'browser:date';`
has corrected behavior, for example
Internal modules would be handy in theory to maybe keep from having to dig through a thesaurus every time browsers decide to add a new, stricter version of an older API. Internal modules have even been proposed to TC-39 as a recommended way to continue to expand the JS API. Last I checked on that proposal it was stuck behind several concerns including:
1. Feature detection: detecting if Temporal available is as easy as `if ('Temporal' in globalThis) {}`, but detecting if a module import is missing is a bit harder. Right now the standard is that loading a module fails with an Error if one of its imports fails. You can work around that by doing a dynamic import inside a try/catch, but that's a lot of extra boilerplate compared to `const thingINeed = 'someApi' in globalThis ? someApi() : someApiPolyfill()`. I've seen multiple proposals on that front from extensions to import maps and `with { }` options on the import itself.
2. Bikeshedding (and lots of it): defining a URI scheme like `browser:` or `standard:` takes a bunch of thought on how you expand it. If it is just `browser:some-api` you run the risk of eventually polluting all the easy names in the exact way people worry about the risk of over-polluting `globalThis` (and in the way that it can be weirdly hard to find an available one-word name on npm), you've just moved the naming problem from one place to the other. On the other side, if you go down the road of something like `es-standard:https://tc39.es/ecma262/2025/v1/final-draft/Temporal`, even (especially) assuming users would mostly importmap that to something shorter you've recreated XMLNS URIs in a funny new hat and people who use JS all certainly have plenty of opinions on XMLNS URIs, many are very vocal in their hatred of it, but also they came out of a strong backwards incompatibility fixing desire exactly like this. (As they say time is a flat circle.)
That would be ugly, because you'd want some parts of your program (eg libraries) to use the old behaviour, and other parts might want the new behaviour. How would you minify multiple modules together if they all expect different behaviour from the standard library?
In my opinion the right way to do this is to have multiple constructors (as Obj-C, swift, C and rust all do). Eg:
The big downside of this is that its tricky to keep track of which fields and functions people should really stop using in modern javascript. It'd be nice if there was a way to enable more shouty warnings during development for deprecated JS features.There are so many (in hindsight bad) design choices and implementation accidents that currently exist in perpetuity because of backwards compatibility; the web would really benefit if every now and then we could shed old baggage.
> Or they could go all in on internal modules, like how you can import `node:fs` now. They could include corrected versions of globals like `import Date from 'browser:date';`
This is what happened here, only the API changed as well
Deleted Comment
Sometimes a date is just a date. Your birthday is on a date, it doesn't shift by x hours because you moved to another state.
The old Outlook marked birthdays as all-day events, but stored the value with time-zone, meaning all birthdays of people whose birthday I stored in Belgium were now shifted as I moved to California...
After having a bunch of problems with dealing with Dates coded as DateTime, I've begun coding dates as a Date primitive, and wrote functions for calculation between dates ensuring that timezone never creeps its way into it. If there is ever a DateTime string in a Date column in the database, it's impossible to know what the date was supposed to be unless you know you normalized it at some point on the way up.
Then I found that a lot of DatePicker libraries, despite being in "DATE" picker mode, will still append a local timezone to its value. So I had to write a sanitizer for stripping out the TZ before sending up to the server.
That said, I am pretty excited about Temporal, it'll still make other things easier.
I'm not necessarily defending the implementation, just pointing out another way in which time is irreducibly ambiguous and cursed.
What should they have done instead? Force everybody to detect browser versions and branch based on that, like in the olden days of IE5?
(Serious question, maybe I'm overlooking some smart trick.)
As far as I know, TC39 doesn't have any clear guidelines about how many websites or how many users must be affected in order to reject a proposed change to JavaScript behavior. Clearly there are breaking changes that are so insignificant that TC39 should ignore them (imagine a website with some JavaScript that simply iterates over every built-in API and crashes if any of them ever change).
Somehow, the standard groups decided to remove the versioning that was there.
In my (unfortunate) experience, DateTime/Timezone handling is one of the things most prone to introduce sneaky, but far-reaching bugs as it is. Introducing such a behaviour change that (usually) won't fail-fast, will often seemingly continue working as before until it doesn't and is deceptively tricky to debug/pinpoint/fix ist just asking for a fast lane into chaos.
And even with JS going the extra mile on backwards compatibility, I don't think most other languages would introduce that kind of breaking change in that way either.
One can't fathom how weird JS Date can be.
Got to question 4 and gave up:
There's literally no way of guessing this crap. It's all random.A datetime with a timezone and a datetime without one are two different things, both of them useful. My birthday does not have a time zone. My deadline does.
The company deadline for getting some document returned? It might or might not, that's policy.
Poetically: we are born free of time zones. We die bound to one.
This feels like something that must be the root of innumerable small and easily overlooked bugs out there.
Deleted Comment
Would it have been nice if the Date object had been immutable? Sure, but the fact that changing the mutable object does indeed change the object shouldn't be a shock
There are million other things legitimately wrong wit JS, developers being bad at understanding referenced objects is not one of them.
(The context is that I want to write some JS tools for astronomical calculations, but UTC conversions need leap-second info, so this trend makes it impossible to write something that Just Works™.)
As you allude to, the correct time scale for this purpose would be TBD (aka Barycentric Dynamical Time), which applies relativistic corrections to act like the atomic clock is fixed at the barycentre of the Solar system. This is the only clock that actually runs "smoothly" for the purposes of astronomical calculations.
https://stjarnhimlen.se/comp/time.html
https://www2.mps.mpg.de/homes/fraenz/systems/systems2art/nod...
That is completely wrong. UTC seconds are exactly SI seconds, which are all the same uniform length (defined by quorum of atomic clocks).
WDYM by this? Why does the SOP prevent a website from hosting a leap seconds file? All they need to do is set Access-Control-Allow-Origin to allow websites to access it. Or provide it as a JS file—in which case no headers are necessary at all. All the SOP prevents is you hotlinking someone else's leap-seconds file and using their bandwidth without their opt-in.
> Meanwhile, browsers update on a cadence more than sufficient to keep an up-to-date copy
Is this true? I don't know any browser right now that ships with a copy of a leapseconds data file. Adding such a data file and keeping it up to date would probably be a pretty non-trivial task for new browser developers—just for something the browser will never end up using itself. It's not like the ICU/CLDR files where browsers are going to need them anyway for rendering their own user-interface components.
They can, but the major providers (read: the ones I would trust to update it) don't. The IERS doesn't [0], the USNO doesn't [1], IANA doesn't [2], and NIST uses FTP [3]. Keep in mind that these files are constantly being downloaded by various clients for NTP and whatnot, it's not like these providers want to restrict public access, they just don't bother to set the header that would allow JS requests.
> Is this true? I don't know any browser right now that ships with a copy of a leapseconds data file.
From ECMA-262:
> It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.
Any browser that ships with a copy of tzdb, or knows where to find a copy from the OS, should have access to its leapseconds file. Unless you mean that all of them go solely through ICU and its data files? Which I suppose could be an obstacle unless ICU were to start exposing them.
[0] https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list
[1] https://maia.usno.navy.mil/ser7/tai-utc.dat
[2] https://data.iana.org/time-zones/tzdb/leap-seconds.list
[3] ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list
This doesn't make sense on at least two different levels.
First, pedantically, the definition of UTC as a time scale is that it includes leap seconds. So if you're committed to UTC, then you're supporting leap seconds.
Second, and to more broadly address your point, you should say, "they're too committed to 'only the POSIX time scale is in-scope for this project.'" That more accurately captures the status quo and also intimates the problem: aside from specialty applications, basically everything is built on POSIX time, which specifically ignores the existence of leap seconds.
That’s because human time keeping doesn’t use leap seconds.
Deleted Comment
That's probably because you only need leap second accuracy in niche use cases, like astronomy or GPS. In JavaScript specifically, that kind of accuracy isn't needed for 99% of client-side use cases. Most date-time libraries work with POSIX time which assumes 86,400 seconds each day.
I would have hoped it'd be ready for wider use by now.
https://caniuse.com/temporal
Most date/time libraries that I've seen have a only single "date/time" or "timestamp" type, then they have to do things like representing "January 13 2026" as "January 13 2026 at midnight local time" or "January 13 2026 at midnight UTC."
Temporal has full-fledged data types representing the different concepts: an Instant is a point in time. A PlainDate is just a date. A PlainTime is just a time. ("We eat lunch at 11am each day.") A ZonedDateTime is an Instant in a known time zone. Etc.
Temporal draws a lot of inspiration from Java's Joda-Time (which also went on to inspire .NET's Noda Time, Java's official java.time API, and JavaScript's js-joda). This is helpful; it means that some concepts can transfer if you're working in other languages. And, more importantly, it means that it benefits from a lot of careful thought on how to ergonomically and effectively represent date/time complexities.
Not exactly. The language doesn't specify whether the value is copied or not and, precisely because values are immutable, there's no way for a user to tell if it was or wasn't.
For example, strings are also immutable value types, but you can be certain that no JS engine is fully copying the entire string every time you assign one to a variable or pass it to a parameter.
2 things it got right:
1. Like the article a great API - Time.current.in_time_zone('America/Los_Angeles') + 3.days - 4.months + 1.hour
2. Rails overloads Ruby's core library Time. You're in 1 object the whole time no swap/wondering.
In the py world, pendulum is close but just like the article, it's cumbersome as it's still a separate obj (i.e. Temporal vs Date) and so you need to "figure out" what you have to manipulate or need to cast it first.
Overloading the core libs is dangerous for a whole host of reasons but for the end developer it's a pleasure to use.
If we could just do `new Date().add({ days: 1})` it would be so easier.
Is this what it looks like? A specific concept like time units being defined as members of more general types like numbers? I.e. if I type `1.` to get auto-complete, am I going to see days, and all the rest, as options?? That API design pattern would be a nightmare!
In more modern languages like Kotlin, there is a notion of extension methods and properties, where you would be able to write a library that allows this syntax, but the .days property would only be accessible in files where you have explicitly imported it (so basically a synthetic sugar for a static function call).
And yet people have been using it for decades without much trouble. I can't remember ever seeing any complaints about API explosion from adding methods to numbers in ruby, and rails does a fair bit of it.
Possibly one reason is with a fluent API that's pretty understandable, you don't need to rely on autocomplete. (And indeed, all this happened before that was a big thing in tooling.)
How is that a good thing?
> Rails overloads Ruby's core library Time. You're in 1 object the whole time regardless of what you do.
How is that a good thing?