謹慎使用toLocaleString!!!

¿

美麗的API都是帶刺的玫瑰html

1. toLocaleString相關背景

掘金 - 想偷懶的話,toLocaleString 瞭解一下?node

MDN - Date​.prototype​.toLocale​String() linux

MDN - Number​.prototype​.toLocale​String() npm

其實就是在說: 這個API能夠省不少事兒, 方便的對時間/數字按照必定格式進行轉換, 不用你寫正則, 不用你拖庫json

1.1 經常使用時間轉換

以經常使用時間格式: YYYY-MM-DD HH:mm:ss爲例, 一般用庫day.js或者moment.js來完成api

format('YYYY-MM-DD HH:mm:ss')
複製代碼

使用toLocaleString的話瀏覽器

new Date()
  .toLocaleString('zh', { hour12: false }) // "2019/4/21 13:00:09"
  .replace(/\//g, '-') // "2019-4-21 13:00:23"
複製代碼

1.2 經常使用數字轉換

例如: 整數部分每三位加一個逗號, 一般用正則完成bash

const number = 123456789
number.toString().replace(/\B(?=(\d{3})+\b)/g, ',') // "12,345,678"
複製代碼

使用toLocaleString的話app

const number = 123456789
number.toLocaleString() // "12,345,678"
複製代碼

2. 坑

上面的一切看着都很美好, 雖然它有瀏覽器兼容問題, 可是我以爲在node.js中使用的話, 應該是能夠把這份美好延續下去的post

可是在一次提交中, 升級了node版本, 涉及到toLocaleString的地方都出現了不少問題

FROM node:8.9-alpine

// 更改成
FROM node:lts-alpine
複製代碼

打破了這份美好, 測試代碼以下

// index.js 
console.log("en: " + new Date().toLocaleString('en', { hour12: false }))
console.log("zh: " + new Date().toLocaleString('zh', { hour12: false }))


// Dockerfile
FROM node:8.9-alpine
COPY . /app
CMD ["node", "/app/index.js"]

複製代碼

鏡像node:8.9-alpine輸出

en:   4/21/2019, 06:42:03
zh:   2019-4-21 06:42:03  (預期)
複製代碼

鏡像node:10.15-alpine輸出

en:   4/21/2019, 06:43:13
zh:   4/21/2019, 06:43:13
複製代碼

鏡像node:11.14-alpine輸出

en:   4/21/2019, 06:43:59
zh:   4/21/2019, 06:43:59
複製代碼

鏡像node:11.14輸出

en:   4/21/2019, 06:46:54
zh:   4/21/2019, 06:46:54
複製代碼

本地node.js 11.13輸出, 怪不得本地調試是好的....

en:   4/21/2019, 14:49:27
zh:   2019-4-21 14:49:27
複製代碼

Chrome瀏覽器

en:   4/21/2019, 14:51:33
zh:   2019/4/21 14:51:33
複製代碼

3. 具體緣由: 國際化支持

Node.js / JavaScript的許多功能是提供國際化支持的, 例如

  • String.prototype.normalize()

  • String.prototype.toLowerCase()

  • Date.prototype.toLocaleString()

  • require('buffer').transcode()

  • ...略

Node.js(及其底層V8引擎)使用ICU實現這些功能

可是要支持世界上全部的語言環境須要一份很是大的ICU數據文件, 而大多數用戶僅會使用ICU功能的一小部分, 所以默認狀況下Node.js僅提供完整ICU數據集的子集

3.1 構建Node.js的ICU選項

  • --with-intl=none/--without-intl: 禁用全部國際化功能

  • --with-intl=system-icu: 取決於系統, 大多數linux發行版都安裝了ICU

  • --with-intl=small-icu(默認): 完整ICU的一部分, 基本等價於: 僅限英文

  • --with-intl=full-icu: 完整的支持

3.2 在運行時提供ICU數據

  1. npm模塊: full-icu: 安裝完整的ICU數據
  • 經過npm i full-icu, 數據文件將會拷貝在./node_modules/full-icu,
  1. 經過設置環境變量NODE_ICU_DATA指定運行時的ICU選項
  • env NODE_ICU_DATA=/some/directory node

3.3 測試

  • npm install full-icu, 確保package.json中有full-icu

  • 編寫以下的Dockerfile

FROM node:lts-alpine

WORKDIR /app

COPY package.json /app

RUN yarn --registry=https://registry.npm.taobao.org

COPY . /app

ENV NODE_ICU_DATA /app/node_modules/full-icu

CMD ["node", "/app/index.js"]
複製代碼

輸出

en:   4/21/2019, 09:13:13
zh:   2019/4/21 09:13:13
複製代碼

雖然和預期2019-4-21 09:13:13有點區別... 仍是能說明有效吧- -

4. 小結

  1. 對於toLocaleString這個API, 瀏覽器環境下不兼容問題更多, Node環境下也會出現不一致的問題, 但能夠經過設置ICU來解決

  2. 從開發角度來講: API 雖然酷炫, 可是相比之下仍是day.js / momemnt.js更穩定

  3. 涉及Node國際化支持的相關知識, 這部分能夠參考官方文檔Internationalization Support

相關文章
相關標籤/搜索