Repository navigation
Intl.DateFormat changes output between Node 16.16 and Node 16.17 #44454
Description
Activity
- addedicuIssues and PRs related to the ICU dependency.Issues and PRs related to the ICU dependency.
on Aug 31, 2022 I also noticed
formatRangeoutputs differently as well:const assert = require("assert/strict") const date = new Date("2022-03-16T14:25:38") const date2 = new Date("2022-03-16T16:25:38") const options = { hour: "2-digit", } const formatted = new Intl.DateTimeFormat("en", options).formatRange(date, date2) assert.strictEqual(formatted, "2 – 4 PM")With node 16.17.0
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + actual - expected + '2 – 4 p' - '2 – 4 PM' ^ at Object.<anonymous> (/Users/chriscanizares/Desktop/index.js:16:8) at Generator.next (<anonymous>) { generatedMessage: true, code: 'ERR_ASSERTION', actual: '2 – 4 p', expected: '2 – 4 PM', operator: 'strictEqual' }In this case though, Chrome
Version 105.0.5195.52outputs:2 – 4 PMcc @nodejs/i18n-api
Yes, these are linguistic cultural preferred forms and they can and do shift. Best is not to depend on fixed formats. See https://cldr.Unicode.org for more info on the process and delta charts.
Will add more details.
@srl295 Can you point to where in the delta (DTD or tickets) this change appears? As someone who's not used to reading this changelog, it's hard to tell 🙂
Even if not depending on fixed formats, it seems strange to me that the time format for
en-USwould be "The meeting was set for 4 p", but maybe seeing the context in the CLDR ticket would help understand why this change happened.@nodejs/i18n-api we should put this in a FAQ…?
@ramonsnir try the following:
- running
node -p process.versions.cldrwill give you the CLDR versions.40.0vs41.0in this case. - go to https://cldr.unicode.org/index/downloads
- FYI: Δ41 link will give you all tickets between 40 and 41
- Go to the Charts41 link
- Choose Delta Data
- English Delta and this section
- Shows the 'at' was dropped.
- running
Thank you, @srl295 , I appreciate it! 🙂 I missed a step going through the delta earlier and never even reached the right page.
Reacted by Steven R. Loomis@srl295 As mentioned, it's my first time dealing with CLDR so I may be misreading things.
From the issues reported above, there were two changes in the format outputs from Node.js:
- Date format
'March 16, 02:25 PM'is now'March 16 at 02:25 PM' - Range format
'2 – 4 PM'is now'2 – 4 p'
CLDR version 40 had two date combination formats in English: When using long/full formats,
atwas used. When using short/medium formats,,was used. Version 41 removes both theatand the,from the combinations (see image below). That wouldn't explain why Node.js switched its default date format from,toat. That would explain the comma being removed, but that's not what happened.For the second issue, I went to the spec to see the definition of time periods. A change from
PMtopwould appear in the delta as (a) a change in some format fromatoaaaaa, or (b) the hour fromjjto something likejjjjj, or (c) somewhere else there was a change in encoding that replaced the literal string'PM'with'p'. I don't see a change that looks like that, in fact, I don't see any change relating to periods.If I am misunderstanding and wasting your time, tell me and I'll drop it. However, I have a feeling that this change wasn't intended and there's a mistranslation somewhere between CLDR / v8 / Node.js.
Reacted by Chris Canizares, Feng Yu and Rizki Fikriansyah- Date format
Just to clear up where this change is coming from.
It's indeed related to Unicode, but it's not actually related to the CLDR specification v41 change. That one was a change about adding theen_MVlocale.The change that this issue is referring to actually comes from ICU, which was updated to v71 in node v16.17.0. You can see that change mentioned in the ICU release notes here: https://icu.unicode.org/download/71#h.z0qyjvmbhu9m
Reacted by NoahJust adding a bit from the ECMA-402 point of view: Never depend on the result of a
formatfunction being something very specific, since the results are all subject to changes in locale data and information and the implementation reserves all rights to adapt them at any point of time. This is formatted locale information that should only be used to display to users.Reacted by Steven R. Loomis, Vytautas Sugintas and Tereza TomcovaClosing this since this has nothing to fix, but feel free to reopen if you disagree.
Just adding a bit from the ECMA-402 point of view: Never depend on the result of a
formatfunction being something very specific, since the results are all subject to changes in locale data and information and the implementation reserves all rights to adapt them at any point of time. This is formatted locale information that should only be used to display to users.💯 — can you comment on #42440 also? I'm concerned about the direction of regression tests assuming format outputs.
Reacted by Ujjwal Sharma and Feng Yu

Version
v16.17.0
Platform
Darwin 21.6.0 Darwin Kernel Version 21.6.0: Wed Aug 10 14:25:27 PDT 2022; root:xnu-8020.141.5~2/RELEASE_X86_64 x86_64
Subsystem
No response
What steps will reproduce the bug?
Given this script:
Run with Node 16.16 will run just fine, with Node 16.17 it will throw:
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
March 16, 02:25 PM
What do you see instead?
March 16 at 02:25 PM
Additional information
I suspect that #42655 introduced the change. And I guess it's fine, since current browsers I've checked actually produce the same output as 16.17, so this issue is likely just documentation for people who stumble into this :)