In all three of my environments I was able to reproduce this error:
My production server
My primary development machine
My secondary development machine
I can't get nodejs to properly format a datetime string in the machine locale. On all of these machines the locale is set to British English, and when recreated on each machine, I get the same output, so I'll just post it once.
The expected behaviour is as such with the en-GB locale set:
> new Date().toLocaleString();
'12/09/2016, 18:14:37'
> new Date().toLocaleString('en-GB');
'12/09/2016, 18:15:31'
> new Date().toLocaleString('en-US');
'9/12/2016, 6:15:34 PM'
I get:
> new Date().toLocaleString();
'9/12/2016, 6:14:37 PM'
> new Date().toLocaleString('en-GB');
'9/12/2016, 6:15:31 PM'
> new Date().toLocaleString('en-US');
'9/12/2016, 6:15:34 PM'
However, when tested in the chrome console, I get the following:
new Date().toLocaleString();
"12/09/2016, 18:03:03"
new Date().toLocaleString('en-GB');
"12/09/2016, 18:03:08"
new Date().toLocaleString('en-US');
"9/12/2016, 6:03:11 PM"
What's going on here? Am I doing something wrong, or is there a bug here?
By default --with-intl=small-icu
is used to build node, which contains just the en-US locale (@nodejs/intl -- is this correct or does it contain more?). You will need to either build node with --with-intl=full-icu
or --with-intl=system-icu
if you want to be able to use more locales. The reason node is built with a smaller ICU by default is file size.
There is another option that doesn't require a custom build of node. You can install the full-icu
module.
Thank you! At least this is now up somewhere where others can find it.
Funny that "JavaScript" or NodeJs can offer a built-in function toLocaleDateString
which not only delivers incorrect results (yyyy-M-d
is not the format for any de-*
locale) but also return a format yyyy-M-d
which is incorrect in any locale (yyyy-MM-dd
I could understand).
(new Date()).toLocaleDateString('de-CH'); // 2019-11-8 // Wrong
Installing full-icu
globally and requiring it does not fix this.
I experienced this with my colleague while running integration tests on our app, we were using new Date(date).toLocaleDateString('en-AU')
and we get different outputs, turns out to be NodeJS Version, he was using NodeJS@12, I was using NodeJS@13
new Date('11/29/2019').toLocaleDateString('en-AU')
NodeJS@12: 11/29/2019
<-- incorrect
NodeJS@13: 29/11/2019
<-- correct
I seek enlightenment.
The official distribution of Node 13 includes 'full icu': the locale database. Without that data Node only supports 'en-US' and will throw for other languages, and silently fall back to 'en-US' for English with other countries. What makes that so insidious is that no other English countries use the US date format and most use the British format which can be ambiguous so you won't even realize it is wrong.
If you have control over your Node invocation (ie. you are not using 3rd party FaaS) then you can add 'full icu' to earlier versions of node via a flag and a data file.
I don't understand why localization is "tacked" on to node like this. Surely date formats for 100 or so countries can't be more than a kb or so of additional weight.
1kb allows about 5 bytes per country in the world.... ICU is much, much, much larger and more complex than that.
I don't understand why localization is "tacked" on to node like this. Surely date formats for 100 or so countries can't be more than a kb or so of additional weight.
Not sure what you mean by "tacked". We discussed this way back in 2014 https://github.com/nodejs/node-v0.x-archive/issues/6371#issuecomment-42491824 , this was a deliberate and theoretically well documented decision to avoid doubling the download size of node.
What I mean is that the JavaScript experience is core + modules and now it's core + modules + thisOtherThing. It makes developing and operating node a pain since I now have to manage a dependency and environment variable instead of just installing a module. In fact, pains with this mean myself and others will drop ICU and install a 3rd party module. Whilst there may be 100+ countries there are not 100+ date formats - probably half a dozen or so.
For anyone that stumbles across this issue, it seems all locales are now included as of node v13: https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V13.md#2019-10-22-version-1300-current-bethgriggs
@WickyNilliams yes, this is true.
On Linux (CentOS) Node seems to ignore the system locale and produce US Date format MM/dd/yyyy:
(new Date()).toLocaleDateString()
'11/30/2020'
Anyone know where the locale can be set which Node uses?
[me@server~]$ sudo timedatectl
Local time: Mon 2020-11-30 10:11:02 CET
Universal time: Mon 2020-11-30 09:11:02 UTC
RTC time: Mon 2020-11-30 09:11:02
Time zone: Europe/Zurich (CET, +0100)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: no
Last DST change: DST ended at
Sun 2020-10-25 02:59:59 CEST
Sun 2020-10-25 02:00:00 CET
Next DST change: DST begins (the clock jumps one hour forward) at
Sun 2021-03-28 01:59:59 CET
Sun 2021-03-28 03:00:00 CEST
[me@server~]$ node
Welcome to Node.js v14.4.0.
Type ".help" for more information.
> (new Date()).toLocaleDateString()
'11/30/2020'
> .exit
[me@server~]$ date
Mon Nov 30 10:16:48 CET 2020
Most helpful comment
There is another option that doesn't require a custom build of node. You can install the
full-icu
module.