内置于浏览器中的国际化API[每日前端夜话0xBA]

你的程序很有可能需要支持多种语言。其中包括对语言敏感的日期处理。一个广受欢迎的库Moment.js【https://www.npmjs.com/package/moment】有助于实现这一目标,它的功能之一是国际化。其源代码【https://github.com/moment/moment/blob/develop/locale/en-gb.js】中包含对许多不同语言的本地化。现在这可能已经不是最好的方法了,因为我们有 ECMAScript 国际化 API。

国际化 API 旨在提供许多应用所需的语言敏感功能。它可以帮助你完成需要考虑语言的任务。浏览器将所有上述功能保留在 Intl 全局对象中,以避免发生命名冲突。

使用 DateTimeFormat 处理日期

Intl.DateTimeFormat 是一个构造函数,它允许我们进行语言敏感的日期处理。

const date = Date.now();
console.log(new Intl.DateTimeFormat('en-US').format(date)); //  8/30/2019
console.log(new Intl.DateTimeFormat('zh-ch').format(date)); //  2019/8/30

它不仅仅能够对日期中数字的规则进行格式化。通过提供额外的选项,还可以委托它翻译诸如周和月的字符串。

new Intl.DateTimeFormat(
  'zh-CN',
  { 
    weekday: 'short',
    month: 'long',
    day: '2-digit'
  }
).format(date)

输出:9月05日周四

通过选择传递给 DateTimeFormat 构造函数的内容,我们可以根据需要对结果进行调整。我们可以将工作日、时代和月份等属性设置为 longshortnarrow。年和日的数值可以设置为 numeric(例如,1)或 2-digit(例如,01)。月份可以表示为数字或字符串。

我们还可以指定是否要用 12 小时制。此处的默认设置取决于区域设置。

new Intl.DateTimeFormat(
  'zh-CN',
  { 
    day: '2-digit',
    month: 'long',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
    hour12: true
  }
).format(date)

2019年9月05日 上午11:41

你还可以使用其他一些选项。有关完整列表,请转到MDN进行查看。

MDN Docs 还提到了 dateStyletimeStyle。那些属性目前处于阶段-3【https://github.com/tc39/proposal-intl-datetime-style】

相对时间格式

通过 ECMAScript 国际化 API,还可以根据所提供的语言处理相对时间的格式。

const formatter = new Intl.RelativeTimeFormat('en');
formatter.format(-1, 'day'); // 1 day ago

通过将 numeric 设置为 auto,我们也可以使用字符串值(如果可用的话)。

const formatter = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
formatter.format(-1, 'day'); // yesterday

通过将 style 设置为 long,short 或 narrow,可以配置消息的长度。

const formatter = new Intl.RelativeTimeFormat('en', { style: 'long' });
formatter.format(5, 'year'); // in 5 years
const formatter = new Intl.RelativeTimeFormat('en', { style: 'short' });
formatter.format(5, 'year'); // in 5 yr.

narrow 风格可能类似于某些地区的短风格。

用 Luxon 替换 Moment.js

你可能不愿意用原生 Date API 替换 Moment.js 库的许多有用功能。Luxon 是一个有趣的选择。这个项目是由 Moment.js 维护者之一发起的,他们希望提供一些不同的 API,但不想在 Moment.js 中破坏任何东西。通过从头编写新库,他能够改变一些重要的事情。最重要的是 Luxon 使用了国际化 API。多亏了这一点,它不必像Moment 那样发布国际化文件。

我们还需要考虑浏览器支持。Sine Luxon 专注于使用原生 API,但并非每个浏览器都能完整的支持。如果你对此担心的话,也可以考虑使用 polyfill。有关详细信息,请查看support matrix【https://github.com/moment/luxon/blob/master/docs/matrix.md】。

国际化 API 其他很酷的功能

ECMAScript Internationalization API提供了其他有用的功能。其中之一是格式化列表的能力。

使用 Intl.ListFormat 格式化列表

const list = ['Cat', 'Dog', 'Rat'];
new Intl.ListFormat('en-GB', { style: 'long', type: 'conjunction' }).format(list);

Cat, Dog and Rat

const list = ['Cat', 'Dog', 'Rat'];
new Intl.ListFormat('en-US', { style: 'long', type: 'conjunction' }).format(list);

Cat, Dog, and Rat

注意,此 API 非常精确,甚至考虑到了相当微妙的差异,例如在英国和美国英语的 and 之前使用 serial comma【https://en.wikipedia.org/wiki/Serial_comma】。

语言敏感的字符串比较

另一个很有用的功能是 collator 功能。在比较可能包含某些特定于语言的字符的字符串时会派上用场。字母 “ä” 是一个很好的例子,因为它出现在德语和瑞典语的字母表中时的顺序可能不同。

new Intl.Collator('de').compare('ä', 'z'); // -1
new Intl.Collator('sv').compare('ä', 'z'); // 1

你可以把许多选项传递给 collator 函数。在 MDN docs 中可以找到一个列表 【https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator】

多个规则

通过使用 Intl.PluralRules,我们可以使用多个敏感格式。

例如,你可以用它来确定在指定语言中使用的复数形式。

new Intl.PluralRules('en-US').select(1); // one

函数返回“one”,所以正确的形式将是“one dog”。

new Intl.PluralRules('en-US').select(41); // other

函数返回“other”,所以正确的形式将是“fourty one dogs”。

另一个用例是找出序数。

new Intl.PluralRules('en-US', { type: 'ordinal' }).select(41); // one

由于函数的结果为“one”,序数为:41

new Intl.PluralRules('en-US', { type: 'ordinal' }).select(32); // two

因为结果为“2”,序数为:32

格式化数字

格式编号中的规则因语言和国家地区而异。使用 Intl.NumberFormat 可以为给定国家/地区使用正确的格式。

const number = 1025.15;
new Intl.NumberFormat('en-US').format(number); // 1,025.15
new Intl.NumberFormat('ar-EG').format(number); // 输出奇怪的阿拉伯文

你还可以使用许多不同的选项【https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat】。

const number = 125.5678;
new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY' }).format(number); //¥1,025.15
new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP' }).format(number); // £125.57

总结

在本文中,我们了解了 ECMAScript Internationalization API 的基本功能。它可能在很多场合对你有用。我相信知道它能够提供什么是有必要,这样我们就不必再去寻找能够做同样事情的外部库。并非所有浏览器都支持上述功能,记得在使用钱先进行检查,在必要时可以使用polyfills【https://www.npmjs.com/package/intl】。

原文:https://wanago.io/2019/09/02/internationalization-api/

原文发布于微信公众号 - 前端先锋(jingchengyideng)

原文发表时间:2019-09-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券