Luxon: Error: Invalid language tag

Created on 16 Mar 2018  路  13Comments  路  Source: moment/luxon

I am using Luxon in a nodejs project, developing firebase functions.

The code looks something like this:

const lyxonFromJsDate = luxon.DateTime.fromJSDate(inputJSDateObject);
const monthLong = luxonFromJsDate.monthLong;

It works without problems on my local computer (Mac OS, node v. 8.9.4).

However when I deploy to firebase functions I get the following error:

RangeError: Invalid language tag: en-US-u-va-posix-u-ca-gregory
    at new DateTimeFormat (native)
    at Object.DateTimeFormat (native)
    at Locale.listingMode

The (relevant) Package.json looks like this:

"dependencies": {
   "full-icu": "^1.2.0",
   "luxon": "^0.5.8",
}

I also found this link on Google cloud functions execution environment, maybe it can help?
https://cloud.google.com/functions/docs/concepts/exec

bug

Most helpful comment

I believe I've fixed this in fc038d5492f572117819cd602a90f4690b99d46b. Released in 1.4.2.

All 13 comments

Ok i fixed it.
Just had to provide a locale:

const lyxonFromJsDate = luxon.DateTime.fromJSDate(inputJSDateObject, {locale: 'en-us'});

Maybe the error message could be improved in the future - to suggest this?

Going to reopen this because I don't really understand it. Can you run this for me in your environment and tell me the result?

import { DateTime } from "luxon";
DateTime.local().resolvedLocaleOpts();

I'm wondering if your default locale is something wild and Luxon isn't handling it right.

Hi @icambron thanks for reponing.

I just added the line you provided, and it gives me the following:
{ locale: 'en', numberingSystem: 'latn', outputCalendar: 'gregory' }

Hmm, that's normal. But here's another guess: that your env doesn't support en-US, and Luxon is assuming it can default to that in some cases. Try this:

new Intl.DateTimeFormat("en-US").resolvedOptions();

I'm hoping that will say something abnormal. I'm basically trying to track down where en-US-u-va-posix-u-ca-gregory is coming from.

Also, fwiw, you can probably fix this globally like this:

import { Settings } from "luxon";
Settings.defaultLocale = "en";

Not something you should have to do though, so I still want to sort out the root issue.

@icambron I'm also seeing this issue on a client device, reporting itself as Samsung Internet for Android 6.4. Judging from the stacktrace, it seems to happen when Luxon calls new DateTimeFormat.

Should the workaround be to set Luxon's defaultLocale to 'en'?

I'm hoping that will say something abnormal. I'm basically trying to track down where en-US-u-va-posix-u-ca-gregory is coming from.

@icambron I'm also experiencing this with Samsung Internet (using version 6.4.10.5 for Galaxy S8 on BrowserStack) and this comes from:

new Intl.DateTimeFormat().resolvedOptions().locale === 'en-US-u-va-posix'

To work around this issue I'm monkey-patching the Intl api:

if (navigator.userAgent.match(/SamsungBrowser/gi) && 'Intl' in window) {
  const native = Intl.DateTimeFormat.prototype.resolvedOptions

  Intl.DateTimeFormat.prototype.resolvedOptions = function resolvedOptions () {
    const options = native.call(this)
    options.locale = options.locale.replace('-u-va-posix', '')
    return options
  }
}

And it is working fine so far.

I haven't been able to find if this locale string returned on SamsungInternet is standard compliant or if it is a bug. In any case, I think the intlConfigString function might be improved to prevent these edge cases. Like having it to check the presence of unicode extension before concatenating the options:

  if (!l.match(/-u\b/)) {
    // add stuff to locale string
  } else {
    // return locale as it is
    return l
  }

I'm not sure about your suggested fix, because while that would avoid immediate errors, it will now ignore the outputCalendar and numberSystem settings set explicitly by the user.

So perhaps we just strip off all the -u stuff from the string altogether.

That would also fix another bug in Luxon:

DateTime.fromObject({ locale: "en-US-u-ca-ethiopic", outputCalendar: "islamicc"}).toLocaleString()
// Uncaught RangeError: Invalid language tag: en-US-u-ca-ethiopic-u-ca-islamicc

In theory we should do more than that; we should strip out all the -u stuff at object creation time, but parse the ones we know about (we know -ca- and -nu- but not -va-), and set outputCalendar and numberingSystem according to them (if they're not explicitly set by the user), so that when this code here runs it basically just puts them back in. Then we don't end up ignoring legit locale codes just because they have u-ca- extensions. But I'd be fine just stripping out -u-etc for now

I'm not sure about your suggested fix, because while that would avoid immediate errors, it will now ignore the outputCalendar and numberSystem settings set explicitly by the user.

Right @icambron , had the idea this bit was only for getting the system locale string.

But I'd be fine just stripping out -u-etc for now

Would be nice for a quick fix; but indeed, ideally should preserve those bits if present.

This just popped up on one of my apps too. Also from "Samsung Internet" on Android 8.

I believe I've fixed this in fc038d5492f572117819cd602a90f4690b99d46b. Released in 1.4.2.

Was this page helpful?
0 / 5 - 0 ratings