luxon
luxon copied to clipboard
DateTime.fromFormat is not able to correctly parse the result of DateTime.toFormat()
The following code results in an invalid DateTime:
const x = new Date();
DateTime.fromFormat(DateTime.fromJSDate(x).toFormat('D T'), 'D T')
error on the resulting DateTime object:
invalid: {…}
explanation: "you specified 20 (of type number) as a month, which is invalid"
reason: "unit out of range"
I'm using firefox 84.0.2 on windows 10, lang in browser set to en-GB, windows region format set to Polish, windows display language set to en-GB, windows apps and websites land set to en-US.
Odd. What does DateTime.local().locale
return in this environment?
'en-GB'
Managed to reproduce this at this codesandbox (with the system locale being en-GB).
luxon.DateTime.fromFormat('14/02/2021 21:00', 'D T')
is invalid but
luxon.DateTime.fromFormat('14/02/2021 21:00', 'D T', {locale: 'en-GB'})
parses correctly.
The issue is that, in the browser, Settings.defaultLocale
. is null. This makes fromFormat default to parsing in en-US. which makes the day/month the wrong way round in the parsing.
In using fromFormat
I'd expect it to use the first available of:
- An explicitly provided locale in opts
- Settings.defaultLocale
- The system locale
- en-US
But 3 / 4 appear to be switched as it stands.
I've managed to get a unit test for this up and running (by moving systemLocale
to a separate module and mocking it). Flipping defaultToEN
in fromFormat
to false makes the test pass, and all other tests continue to pass.
I'm a little nervous about it though, as I assume that flag was explicitly set to true for a reason.
Forcing the parse to default to EN is indeed on purpose. Imagine you're building a web app and you're requesting data off of some backend, and it formats dates like, say, 05/15/21 9:15am
, which you parse with fromFormat
. You don't want your parsing code to break because the user changes their locale.
However, the localized macro tokens really should localized with the default locale. I had thought they did
I confirm that passing the locale explicitly in the options resolves this issue.
The reason I reported it though is that when running on defaults for both fromFormat
and toFormat
, I'd expect this to use the same locale whereas it seems that's not the case.
I think if I was expecting US formatted dates from a backend, I'd expect to have to specify en-US explicitly in fromFormat
. That is, I'd find having to do that that less unintuitive than this bug.
If that's the expected behaviour though, I guess this one can be closed?