阅读 838

Date.prototype.toLocaleString()

背景

因为我们开发的项目在多个国家和地区使用,不同国家和地区对于日期的显示习惯是不同的。例如:我们习惯使用 年-月-日 的方式显示日期,而英国习惯使用 日-月-年 的方式显示日期。因此在这里介绍一下日期本地化函数 toLocaleString。

简介

toLocaleString() 方法返回日期对象的字符串,该字符串因语言环境、配置的选项不同而不同。新增的参数 localesoptions 使程序能够指定语言环境、选项。在旧版浏览器中, localesoptions 参数被忽略。

let event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

// 英国使用 日-月-年 的顺序,24小时制,不带 AM/PM
event.toLocaleString('en-GB', { timeZone: 'UTC' }); // 20/12/2012, 03:00:00

// 韩国使用 年-月-日 的顺序,12小时制 + AM/PM
event.toLocaleString('ko-KR', { timeZone: 'UTC' }); // 2012. 12. 20. 오전 3:00:00

复制代码

语法

dateObj.toLocaleString([locales [, options]])
复制代码

查看 浏览器兼容性,看下哪些浏览器支持 locales 和 options 参数,还可以参看 例子:检测 localesoptions 参数支持情况

参数

  • locales:

    可选,值是遵循 BCP47 规范的语言标记字符串或此类字符串数组,如果想使用浏览器默认的语言环境,忽略这个参数或者传 undefined 即可。

    支持 Unicode 扩展。例如:'en-US-u-ca-buddhist',其中 'en-US' 是 BCP47 语言标记,表示美国使用的英语;'u' 代表 Unicode,表示其后是 Unicode 扩展;'ca' 代表 Calendar,'buddhist' 是 ca 的值。允许使用以下 Unicode 扩展密钥:

    • nu

      Numbering system. Possible values include: 'arab', 'arabext', 'bali', 'beng', 'deva', 'fullwide', 'gujr', 'guru', 'hanidec', 'khmr', 'knda', 'laoo', 'latn', 'limb', 'mlym', 'mong', 'mymr', 'orya', 'tamldec', 'telu', 'thai', 'tibt'

    • ca

      Calendar. Possible values include: 'buddhist', 'chinese', 'coptic', 'ethiopia', 'ethiopic', 'gregory', 'hebrew', 'indian', 'islamic', 'islamic', 'iso8601', 'japanese', 'persian', 'roc'.

    • hc

      Hour cycle. Possible values include: 'h11', 'h12', 'h23', 'h24'.

    const event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
    event.toLocaleString('en-US', { timeZone: 'UTC' }); // '12/20/2012, 3:00:00 AM'
    event.toLocaleString('en-US-u-ca-buddhist', { timeZone: 'UTC' }); // '12/20/2555, 3:00:00 AM'
    复制代码

    更多信息请参考 Intl page

  • options: 可选,对象,有以下属性:

    • dateStyle:可选值:'full', 'long', 'medium', 'short'

      const event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
      event.toLocaleString('en-GB', { timeZone: 'UTC' }); // '20/12/2012, 03:00:00'
      event.toLocaleString('en-GB', { timeZone: 'UTC', dateStyle: 'full' }); // 'Thursday, 20 December 2012'
      event.toLocaleString('en-GB', { timeZone: 'UTC', dateStyle: 'long' }); // '20 December 2012'
      event.toLocaleString('en-GB', { timeZone: 'UTC', dateStyle: 'medium' }); // '20 Dec 2012'
      event.toLocaleString('en-GB', { timeZone: 'UTC', dateStyle: 'short' }); // '20/12/2012'
      复制代码
    • timeStyle:可选值:'full', 'long', 'medium', 'short'

      const event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
      event.toLocaleString('en-GB', { timeZone: 'UTC' }); // '20/12/2012, 03:00:00'
      event.toLocaleString('en-GB', { timeZone: 'UTC', timeStyle: 'full' }); // '03:00:00 Coordinated Universal Time'
      event.toLocaleString('en-GB', { timeZone: 'UTC', timeStyle: 'long' }); // '03:00:00 UTC'
      event.toLocaleString('en-GB', { timeZone: 'UTC', timeStyle: 'medium' }); // '03:00:00'
      event.toLocaleString('en-GB', { timeZone: 'UTC', timeStyle: 'short' }); // '03:00'
      复制代码
    • localeMatcher:locale 匹配策略;可选值是:'lookup', 'best fit';默认值是 'best fit'。更多信息请参考 Intl page.

    • timeZone: 指定时区;可选值是:'UTC';默认值是当前浏览器的默认时区。浏览器也能识别出 IANA 时区数据库 的时区名称,例如:'Asia/Shanghai', 'Asia Kolkata', 'America/New_York'。

    • hour12: 是否使用12小时制时间(对应的是 24小时制);可选值:true, false。默认值和 locale 有关,它比 locales 中 Unicode 扩展标记中的 hchourCycle 优先级都高。

    • hourCycle: 要使用的小时循环。可选值:'h11', 'h12', 'h23', 'h24'。它比 locales 中 Unicode 扩展标记中的 hc 优先级高,比 hour12 优先级低。

    • formatMatcher: 格式化匹配策略;可选值是 'lookup', 'best fit';默认值是 'best fit'

    • weekday:星期的表示,可选值如下:

      • 'long' (e.g. Thursday)
      • 'short' (e.g. Thu)
      • 'narrow' (e.g. T) 注意一些地区的简写可能是相同的,比如:Thursday & Thursday。
    • era:时代的表示,可选值如下:

      • 'long' (e.g. Anno Domini) 公元
      • 'short' (e.g. AD)
      • 'narrow' (e.g. A)
    • year:年的表示,可选值如下:

      • 'numeric' (e.g. 2012)
      • '2-digit' (e.g. 12)
    • month:月的表示,可选值如下:

      • 'numeric' (e.g. 2)
      • '2-digit' (e.g. 02)
      • 'long' (e.g. March)
      • 'short' (e.g. Mar)
      • 'narrow' (e.g. M) 注意一些地区的月的 'narrow' 简写可能是相同的,比如:March & May。
    • day:日的表示,可选值如下:

      • 'numeric' (e.g. 1)
      • '2-digit' (e.g. 01)
    • hour:小时的表示,可选值是:'numeric' & '2-digit'

    • minute:分钟的表示,可选值是:'numeric' & '2-digit'

    • second:秒的表示,可选值是:'numeric' & '2-digit'

    • timeZoneName:时区名的表示,可选值如下:

      • 'long' (e.g. British Summer Time)
      • 'short' (e.g. GMT+1)

Demos

不带参数

没有指定语言环境(locales)时,返回一个使用默认语言环境和格式设置(options)的格式化字符串。

// toLocaleString 不包含参数的返回值取决于当前浏览器的默认语言环境(locales)和默认时区(time zone),我机器的语言环境是简体中文(cn-ZH),时区是东八区
const event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
event.toLocaleString(); // '2012/12/20 上午11:00:00'

// 如果是在 en-US 语言环境和 America/Los_Angeles 时区运行返回值为 '12/19/2012, 7:00:00 PM'
event.toLocaleString('en-US', { timeZone: 'America/Los_Angeles' }); // '12/19/2012, 7:00:00 PM'
复制代码

localesoptions 参数不是所有的浏览器都支持。为了检测浏览器是否支持它们,可以使用不合法的语言标签,如果实现环境支持该参数,则会抛出一个 RangeError 异常,反之会忽略参数。

function toLocaleStringSupportsLocales() {
    try {
        new Date().toLocaleString('i');
    } catch (e) {
        return e.name === 'RangeError';
    }
    return false;
}
复制代码

使用 locales 参数

下例展示了使用 locales 参数指定语言环境后,输出的日期字符串。

const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

// en-US 使用 month-day-year 的顺序展示年月日
date.toLocaleString('en-US', { timeZone: 'America/Los_Angeles' }); // '12/19/2012, 7:00:00 PM'

// en-GB 使用 day-month-year 顺序展示年月日
date.toLocaleString('en-GB', { timeZone: 'UTC' }); // // '20/12/2012 03:00:00'

// 韩语使用 year-month-day 顺序展示年月日
date.toLocaleString('ko-KR', { timeZone: 'Asia/Seoul' }); // '2012. 12. 20. 오후 12:00:00'

// 在日本,程序可能想指定使用日本日历,
// 2012是平成24年(平成是日本天皇明仁的年号, 由1989年1月8日起开始计算直至现在)
date.toLocaleString('ja-JP-u-ca-japanese', { timeZone: 'Asia/Tokyo' }); // '24/12/20 12:00:00'

// 当请求一个语言可能不支持,如巴厘(ban),若有备用的语言印尼语(id),那么将使用印尼语(id)
date.toLocaleString(['ban', 'id']); // '20/12/2012 11.00.00'
复制代码

使用 options 参数

可以使用 options 参数来自定义 toLocaleString 方法返回的字符串。

const date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

// options 包含参数 weekday,并且该参数的值为 long
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
date.toLocaleString('en-US', options); // 'Thursday, December 20, 2012'

// 指定 timeZone 为 'UTC'
options.timeZone = 'UTC';
// 不指定 timeZoneName 仍然显示的是世界标准时间,但是 UTC 三个字母不会显示
options.timeZoneName = 'short';
date.toLocaleString('en-US', options); // 'Thursday, December 20, 2012, UTC'

// 使用24小时制
date.toLocaleString('en-US', { hour12: false }); // '12/19/2012, 19:00:00'
复制代码

其他文章链接

TypeScript 踩坑之旅

[译文]一步步构建发布一个 TypeScript NPM 包

npm install package-lock.json 的更新策略

[译]浏览器语言首选项

Date.prototype.toLocaleString()

文章分类
阅读
文章标签