luxon icon indicating copy to clipboard operation
luxon copied to clipboard

DateTime.fromFormat is not able to correctly parse the result of DateTime.toFormat()

Open spooky opened this issue 4 years ago • 12 comments

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.

spooky avatar Jan 19 '21 23:01 spooky

Odd. What does DateTime.local().locale return in this environment?

icambron avatar Jan 22 '21 17:01 icambron

'en-GB'

spooky avatar Jan 25 '21 17:01 spooky

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:

  1. An explicitly provided locale in opts
  2. Settings.defaultLocale
  3. The system locale
  4. en-US

But 3 / 4 appear to be switched as it stands.

dan-overton avatar Feb 14 '21 21:02 dan-overton

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.

dan-overton avatar Feb 14 '21 22:02 dan-overton

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

icambron avatar Feb 15 '21 12:02 icambron

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.

spooky avatar Feb 19 '21 08:02 spooky

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?

dan-overton avatar Feb 21 '21 20:02 dan-overton