查看原文
其他

【第1718期】前端国际化利器 - Intl

梁天培_Tim 前端早读课 2019-10-10

前言

产品国际化,你目前是采用什么方案呢?今日早读文章由@梁天培_Tim翻译授权分享。

@梁天培(Tim),现任 Shopee 高级前端工程师一职,曾就职于京东凹凸实验室,Taro 掘金小册编纂者之一

正文从这开始~~

Intl 是一个全局对象,它的主要用途就是展示国际化信息,可以将字符串,数字和日期和时间转换为指定地区的格式。

国际化是应用程序中用来适应各种语言和区域而无需进行编码的一种方式。

JavaScript 开发者无需在代码包中加入数以 KB 计的翻译文件。Intl 有各种构造函数和方法,这些构造函数和方法将 locale 作为参数并可以根据您的需要格式化数据。下面是 Intl 的构成:

全局变量 Intl

Collator,DateTimeFormat,ListFormat,NumberFormat,PluralRules,RelativeTimeFormat是命名空间 Intl 中的构造函数。它们接受两个参数 - locales 和 options。locale 必须是符合 BCP 47 语言标记规范的字符串或数组。如果您有兴趣了解有关 BCP 47 语言标签的更多信息,请参阅 MDN 的摘录:

BCP 47 语言标记用于定义一种语言,它包含了该语言的主要信息。在正常情况下,它按顺序包含:语言代码,脚本代码和国家或地区代码,这些信息都用连字符分隔。虽然这些标签不区分大小写,但建议用标题大小写来写脚本代码,用大写来写国家和地区代码,用小写来写其他内容。

locale 参数的默认值为运行时的语言环境。语言环境一般写成这样 - en(英语),hi(印地语),ta-in(泰米尔语 - 印度)。options 参数是可选的,其结构因不同的构造函数而异,主要用于提供格式化的自定义参数。

在本文中,我们将介绍在命名空间 Intl 中添加的一些新 API。这些新 API 已经在 Google I/O '19 中公布。下面让我们来详细了解一下这些 API。

Intl.RelativeTimeFormat

RelativeTimeFormat 构造函数用于将时间戳转换为人性化短语。它将可读性差的日期对象转换为其相对当前时间字符串。让我们来看下面这个栗子:

Intl.RelativeTimeFormat 将时间转换为英语短语

上面的栗子中,Intl.RelativeTimeFormat 构造函数的第一个参数为 en 。配置项 options 中的 numeric 可能取值 always 或 auto ---- 其中 always 不会将数字格式化为短语,举个栗子:rtf.format(-1, 'month') 会格式化为 1 month ago。

如果您想将他们格式化为泰语,可以像下图这样传参:

Intl.RelativeTimeFormat 构造函数 with ta-in locale

像昨天、今天、明天这样的短语可以给用户提供更好的可读性!相关功能可在 Chrome 71 和 FireFox 65 以上版本体验。

Intl.ListFormat

ListFormat 构造函数用于把字符串连接成有意义的短语。

Intl.ListFormat 用默认配置格式化为英语

format 方法可以很好地连接 characters 数组中的字符串。如果不使用 ListFormat API,我们必须编写函数来把 , 和 and 插入适当的位置。

我们可以通过更改 options 中的配置项来自定义格式化的内容:

Intl.ListFormat 用 disjunction 参数格式化为英语

将 type 设置为 disjunction 会使用 or 来连接字符串。下面是 options 的一些属性的可选值:

type:可选值为 conjunction,disjunction 和 unit,其中 conjunction 为默认值, unit 类型用于不需要连接词的情况,如下图:

Intl.ListFormat 用 unit 参数格式化为英语

style: 可选值为 long and short (或者 narrow)

ListFormat API 在 Chrome 72 以上版本可体验。

Intl.NumberFormat

与其他高级语言不同,JavaScript 为变量的数据类型提供了灵活性。int、float、string 或 object 都是使用 var 声明的(let 和 const 用于块级作用域)。

但是我们怎么才能确定一个数字有多大?

  1. 123456789123456789 * 11 // Prints 1358024680358024700

上述操作结果的单位不应该为0!看起来我们需要为大数做点额外的操作。好消息是,我们已经有 BigInt 用于处理大数。让我们使用 BigInt 来再试一遍:

  1. 123456789123456789n * 11n // Prints 1358024680358024679n

现在看起来正常多了!

大数的可读性一般都比较差。这种情况下我们可能需要用到 Intl.NumberFormat API!它用于通过添加特定于语言环境的数字分隔符来格式化数字。让我们看看它的效果:

Intl.NumberFormat 构造函数

数字格式化会根据你的区域设置而不同。设置为 en 时使用逗号分隔符,设置为 fr 时使用空格分隔。

我们可以通过更改 options 对象中的配置项来自定义格式化的内容。options 上的一些参数的可选值如下:style: 可选值为 decimal, currency, 和 percent , 默认值为 decimal

currency: 用于指定货币样式。例如: USD, INR

currencyDisplay: 可选值为 symbol and code , 默认值为 symbol

你可以点击这里查看所有的可配置项。

Intl.NumberFormat 现在在 Chrome、 FireFox 和 Safari 中可用。

列表中还有一个更令人兴奋的 API:Intl.DateTimeFormat

Intl.DateTimeFormat

Intl.DateTimeFormat API 用于将日期和时间格式化为指定语言的格式。这个 API 上的新方法 formatRange ,可以像下面这样使用:

  1. const df = new Intl.DateTimeFormat('en', {

  2. year: 'numeric',

  3. month: 'short',

  4. day: 'numeric'

  5. })

  6. const startDate = new Date('01-06-2019')

  7. const endDate = new Date('10-06-2019')

  8. df.formatRange(startDate, endDate) // Prints Jun 1-10 2019

注意:formatRange 函数会将同一个月的日期组合在一起展示。

使用这个 API 后,您就可以从代码中删除仅用于格式化日期范围的方法!

options 中有许多配置项,例如 timeZone,era,year,month,day,hour,minute,second等等。

结语

本文介绍了新增 API Intl 的一些内容:

  1. Intl.RelativeTimeFormat API可用于为时间戳生成相对于当前时间的人性化短语。

  2. Intl.ListFormat API可用于使用 conjunction,disjunction和unit 参数把数组元素连接成短语。

  3. Intl.NumberFormat可用于使用将大数格式化为指定的语言格式。

  4. Intl.DateTimeFormat API上的 formatRange 方法可用于生成时间范围的字符串

关于本文 译者:@梁天培_Tim 译文:https://juejin.im/post/5d58bf496fb9a06ace524da8 作者:@Ankita Masand 原文:https://blog.bitsrc.io/new-intl-apis-in-javascript-c50dc89d2cf3

Ta曾分享过


【第1658期】 Chrome 专家调试法 - 介绍 Chrome 开发者工具的最佳用法

为你推荐

【第1352期】map和reduce,处理数据结构的利器

【第1099期】Eruda: 手机网页调试利器

【第1538期】聊聊前端国际化文案该如何处理

【第1032期】前端国际化

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存