Behebung von NodeJS Intl.DateTimeFormat formatiert nicht korrekt für Locales

English Deutsch

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:

example-en.js
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:

example-de.js
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:

install-intl.sh
npm i --save intl

Verwendung:

use-intl-polyfill.js
// 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

install-full-icu.sh
npm i --save full-icu

Dies wird einige Zeit dauern, um die Daten zu kompilieren, und gibt dann Anweisungen wie diese aus:

full-icu-instructions.txt
 √ 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/6

Um 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-with-icu.sh
node --icu-data-dir=node_modules/full-icu

Wenn 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

package.start.json
// [...]
"scripts": {
    "start": "node --icu-data-dir=node_modules/full-icu index.js"
}
// [...]

verwende

package.json
// [...]
"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


Check out similar posts by category: Allgemein, Javascript, NodeJS