X Tutup
The Wayback Machine - https://web.archive.org/web/20231224182959/https://github.com/nodejs/node/issues/42391
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid Date generated by toLocaleString('en-gb', ...) #42391

Open
RobinBol opened this issue Mar 18, 2022 · 3 comments
Open

Invalid Date generated by toLocaleString('en-gb', ...) #42391

RobinBol opened this issue Mar 18, 2022 · 3 comments
Labels
i18n-api Issues and PRs related to the i18n implementation.

Comments

@RobinBol
Copy link

RobinBol commented Mar 18, 2022

Version

v13.14.0

Platform

Darwin .... 21.3.0 Darwin Kernel Version 21.3.0: Wed Jan 5 21:37:58 PST 2022; root:xnu-8019.80.24~20/RELEASE_ARM64_T6000 arm64

Subsystem

Always on Node >= 13.

What steps will reproduce the bug?

nvm use 13
Now using node v13.14.0 (npm v6.14.4)
node -p "new Date().toLocaleString('en-GB', { timeZone: 'Europe/Amsterdam' })"
18/03/2022, 14:30:20
node -p "new Date(new Date().toLocaleString('en-GB', { timeZone: 'Europe/Amsterdam' }));"
Invalid Date

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior?

nvm use 12
Now using node v12.22.10 (npm v6.14.16)
node -p "new Date().toLocaleString('en-GB', { timeZone: 'Europe/Amsterdam' })"
3/18/2022, 2:29:41 PM
node -p "new Date(new Date().toLocaleString('en-GB', { timeZone: 'Europe/Amsterdam' }));"
2022-03-18T13:33:38.000Z

For the record, so far I have only found en-GB to have this problem, en-US works as expected, see below:

nvm use 13
Now using node v13.14.0 (npm v6.14.4)
node -p "new Date().toLocaleString('en-US', { timeZone: 'Europe/Amsterdam' })"
3/18/2022, 2:52:37 PM
node -p "new Date(new Date().toLocaleString('en-US', { timeZone: 'Europe/Amsterdam' }));"
2022-03-18T13:52:47.000Z

What do you see instead?

Invalid Date

Additional information

The day and month are swapped as of Node 13 for the en-GB locale.

For en-GB Node 13 seems to use the correct format day/month/year, whereas Node 12 uses month/day/year.

The problem is: in Node 12 you could create a Date instance based on the output of .toLocaleString('en-GB', ...). As of Node 13 this returns Invalid Date.

Node 12: the following results in a valid Date instance.

"new Date(new Date().toLocaleString('en-GB', { timeZone: 'Europe/Amsterdam' }));"

Node 13: the following results in an "Invalid Date" error.

"new Date(new Date().toLocaleString('en-GB', { timeZone: 'Europe/Amsterdam' }));"
@Spekpannenkoek
Copy link

Node 13 added supports for the locale option in the toLocaleString method. Before that, it was ignored and would always use the US formatting. As opposed the the US, the United Kingdom does not use mm/dd/yyyy as a date format:

Most style guides follow the DMY convention by recommending d mmmm yyyy (sometimes written dd/mm/yyyy) format in articles (Wikipedia)

As such, Node 13's behavior is correct. You're asking for a UK formatted date & getting one.


When doing the reverse:

The new Date() constructor will not accept just any arbitrary string as a date: it relies on what Date.parse() will recognize, which is basically ISO 8601 (YYYY-MM-DDThh:mm:ss) and "take a wild guess as a fallback"—which is not locale-aware and also implementation dependent. As it is impossible to tell if 01/02/2000 is DMY or MDY, no attempt is made to support both D/M/Y and M/D/Y, just the latter. You cannot tell Date.parse explicitly that you're feeding it a GB localized date.

MDN has an apt warning:

Note: Parsing of date strings with the Date constructor (and Date.parse(), which works the same way) is strongly discouraged due to browser differences and inconsistencies.

(Feeding it 2000-02-01T01:02:03Z would be fine)

There is no Date.parseFromLocaleString in the standard library. Perhaps a function to do this will be added to the spec in the future under the Intl.DateTimeFormat namespace. Third party libraries do have functions to help you with this, such as Day.js.

@GrosSacASac
Copy link
Contributor

I recommend to never use a locale string as input for new Date(). Instead use a format made for it
new Date(new Date().toJSON());

@srl295 srl295 added the i18n-api Issues and PRs related to the i18n implementation. label Dec 12, 2023
@srl295
Copy link
Member

srl295 commented Dec 12, 2023

close as working as designed? @nodejs/i18n-api

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
i18n-api Issues and PRs related to the i18n implementation.
Projects
None yet
Development

No branches or pull requests

4 participants
X Tutup