Intl
Luxon uses the native Intl API to provide easy-to-use internationalization. A quick example:
DateTime.local().setLocale('el').toLocaleString(DateTime.DATE_FULL); //=> '24 Σεπτεμβρίου 2017'
How locales work
Luxon DateTimes can be configured using BCP 47 locale strings specifying the language to use generating or interpreting strings. The native Intl API provides the actual internationalized strings; Luxon just wraps it with a nice layer of convenience and integrates the localization functionality into the rest of Luxon. The Mozilla MDN Intl docs have a good description of how the locale
argument. In Luxon, the methods are different but the semantics are the same, except in that Luxon allows you to specify a numbering system and output calendar independently of the locale string (i.e. Luxon does the string munging for you).
The rest of this document will concentrate on what Luxon does when provided with locale information.
Setting locale
locale
is a property of Luxon object, and it defaults to 'en-US'. Thus, locale is a sort of setting on the DateTime object, as opposed to an argument you provide the different methods that need internationalized.
You can generally set it at construction time:
var dt = DateTime.fromISO('2017-09-24', { locale: 'fr' })
dt.locale //=> 'fr'
In this case, the specified locale didn't change the how the parsing worked (there's nothing localized about it), but it did set the locale property in the resulting instance. For other factory methods, such as fromString
, the locale argument does affect how the string is parsed. See further down for more.
You can change the locale of a DateTime instance (meaning, create a clone DateTime with a different locale) using setLocale
:
DateTime.local().setLocale('fr').locale //=> 'fr'
setLocale
is just a convenience for reconfigure
:
DateTime.local().reconfigure({ locale: 'fr' }).locale; //=> 'fr'
Checking what you got
The local environment may not support the exact locale you asked for. The native Intl API will try to find the best match. If you want to know what that match was, use resolvedLocaleOpts
:
DateTime.fromObject({locale: 'fr-co'}).resolvedLocaleOpts(); //=> { locale: 'fr',
// numberingSystem: 'latn',
// outputCalendar: 'gregory' }
Methods affected by the locale
Formatting
The most important method affected by the locale setting is toLocaleString
, which allows you to produce internationalized, human-readable strings.
dt.setLocale('fr').toLocaleString(DateTime.DATE_FULL) //=> '25 septembre 2017'
That's the normal way to do it: set the locale as property of the DateTime itself and let the toLocaleString
inherit it. But you can specify the locale directly to toLocaleString
too:
dt.toLocaleString( Object.assign({ locale: 'es' }, DateTime.DATE_FULL)) //=> '25 de septiembre de 2017'
Ad-hoc formatting also respects the locale:
dt.setLocale('fr').toFormat('MMMM dd, yyyy GG'); //=> 'septembre 25, 2017 après Jésus-Christ'
Parsing
You can parse localized strings:
DateTime.fromString('septembre 25, 2017 après Jésus-Christ', 'MMMM dd, yyyy GG', {locale: 'fr'})
Listing
Some of the methods in the Info class let you list strings like months, weekdays, and eras, and they can be localized:
Info.months('long', { locale: 'fr' }) //=> [ 'janvier', 'février', ...
Info.weekdays('long', { locale: 'fr' }) //=> [ 'lundi', 'mardi', ...
Info.eras('long', { locale: 'fr' }) //=> [ 'avant Jésus-Christ', 'après Jésus-Christ' ]
numberingSystem
DateTimes also have a numberingSystem
setting that lets you control what system of numerals is used in formatting. In general, you shouldn't override the numbering system provided by the locale. For example, no extra work is needed to get Arabic numbers to show up in Arabic-speaking locales:
var dt = DateTime.local().setLocale('ar')
dt.resolvedLocaleOpts() //=> { locale: 'ar',
// numberingSystem: 'arab',
// outputCalendar: 'gregory' }
dt.toLocaleString() //=> '٢٤/٩/٢٠١٧'
For this reason, Luxon defaults its own numberingSystem
property to null, by which it means "let the Intl API decide". However, you can override it if you want. This example is admittedly ridiculous:
var dt = DateTime.local().reconfigure({ locale: 'it', numberingSystem: 'beng' })
dt.toLocaleString(DateTime.DATE_FULL) //=> '২৪ settembre ২০১৭'