Behebung von NodeJS Intl.DateTimeFormat formatiert nicht korrekt für Locales
Symptom:
NodeJS ab Version v9.x unterstützt das ES6-Intl.DateTimeFormat
Wenn du es mit der ’en-US’-Locale verwendest, funktioniert es einwandfrei und gibt "August 13, 2018" aus:
const df = new Intl.DateTimeFormat('en-US', {day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC'});
console.log(df.format(new Date("2018-08-13T04:00:00.000Z")));Die Verwendung mit einer anderen Locale schlägt jedoch fehl:
const df = new Intl.DateTimeFormat('de', {day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC'});
console.log(df.format(new Date("2018-08-13T04:00:00.000Z")));Während man erwarten würde, dass dies "13. August 2018" ausgibt, gibt es "2018 M08 13" aus
Ursache:
Standardmäßig wird NodeJS nur mit small-icu-Support gebaut, wodurch nur die en-US-Locale installiert wird um die Installationsdateigröße zu reduzieren.
Lösung 1 (bevorzugt):
Du kannst das intl-Polyfill-Modul verwenden, um die Intl-Implementierung von NodeJS vollständig zu ersetzen:
Installation:
npm i --save intlVerwendung:
// Intl durch Polyfill ersetzen
Intl = require("intl")
const df = new Intl.DateTimeFormat('de', {day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC'});
console.log(df.format(new Date("2018-08-13T04:00:00.000Z")));Dies gibt wie erwartet 13. August 2018 aus.
Lösung 2 (alternativ):
Du kannst das full-icu-Paket verwenden, um die NodeJS-ICU-Implementierung weiterhin zu verwenden (d.h. kein Polyfill), aber nur die ICU-Daten zu installieren.
Während dies die gesamte Installationsdateigröße reduziert, ist die Installation langsam und die genaue Methode hängt von der NodeJS-Version ab und erfordert mehr Aufwand als nur die Verwendung des intl-Polyfills.
Um zu installieren, verwende
npm i --save full-icuDies wird einige Zeit dauern, um die Daten zu kompilieren, und gibt dann Anweisungen wie diese aus:
√ icudt62l.dat (link)
Node will use this ICU datafile if the environment variable NODE_ICU_DATA is set to “node_modules/full-icu”
or with node --icu-data-dir=node_modules/full-icu YOURAPP.js
For package.json:
{"scripts":{"start":"node --icu-data-dir=node_modules/full-icu YOURAPP.js"}}
By the way, if you have full data, running this in node:
> new Intl.DateTimeFormat('es',{month:'long'}).format(new Date(9E8));
... will show “enero”. If it shows “January” you don't have full data.
News: Please see https://github.com/icu-project/full-icu-npm/issues/6Um full-icu tatsächlich zu verwenden, musst du das Argument --icu-data-dir=node_modules/full-icu jedes Mal verwenden, wenn du node ausführst. Um Node interaktiv zu starten, verwende
node --icu-data-dir=node_modules/full-icuWenn du Skripte in deiner Anwendung verwendest (z.B. das start-Skript, d.h. was ausgeführt wird, wenn du npm start ausführst), musst du die Konfiguration in package.json anpassen:
Anstatt
// [...]
"scripts": {
"start": "node --icu-data-dir=node_modules/full-icu index.js"
}
// [...]
verwende
// [...]
"scripts": {
"start": "node --icu-data-dir=node_modules/full-icu index.js"
}
// [...]
Je nach Anwendung musst du möglicherweise einen anderen Skriptnamen als index.js verwenden — häufige Namen sind server.js und start.js