修复 NodeJS Intl.DateTimeFormat 不能正确格式化区域设置
症状:
NodeJS 从 v9.x 版本开始支持 ES6 Intl.DateTimeFormat
当你在 ’en-US’ 区域设置中使用它时,它正常工作并打印 "August 13, 2018":
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")));但是,使用不同的区域设置会失败:
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")));虽然你期望这会打印 "13. August 2018",但它会打印 "2018 M08 13"
原因:
默认情况下,NodeJS 仅构建了 small-icu 支持,因此仅安装了 en-US 区域设置以减少安装文件大小。
解决方案 1(首选):
你可以使用 intl polyfill 模块完全替换 NodeJS 的 intl 实现:
安装:
install-intl.sh
npm i --save intl用法:
使用-intl-polyfill.js
// 用 polyfill 替换 Intl
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")));这将按预期打印 13. August 2018。
解决方案 2(替代):
你可以使用 full-icu 包继续使用 NodeJS ICU 实现(即不用 polyfill),但只安装 ICU 数据。
虽然这减少了总安装文件大小,但安装速度慢,确切方法取决于 NodeJS 版本,并且比仅使用 intl polyfill 需要更多工作。
要安装,使用
install-full-icu.sh
npm i --save full-icu这将需要一些时间来编译数据,然后会打印类似这样的说明:
full-icu-instructions.txt
√ icudt62l.dat (link)
Node will 使用 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为了实际使用 full-icu,你每次运行 node 时都需要使用 --icu-data-dir=node_modules/full-icu 参数。要以交互方式运行 node,使用
node-with-icu.sh
node --icu-data-dir=node_modules/full-icu如果你在应用程序中使用脚本(例如 start 脚本,即运行 npm start 时执行的内容),你需要调整 package.json 中的配置:
而不是
package.start.json
// [...]
"scripts": {
"start": "node --icu-data-dir=node_modules/full-icu index.js"
}
// [...]
使用
package.json
// [...]
"scripts": {
"start": "node --icu-data-dir=node_modules/full-icu index.js"
}
// [...]
Depending on your application, you might need to 使用 a different script name than index.js - common names include server.js and start.js
Check out similar posts by category:
Allgemein, Javascript, NodeJS
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow