JavaScript日期

Sarkuya,

本地化

根据本地规则来进行显示、比较的一组规则。先看一例:

var str1 = "伍";
var str2 = "陈";

console.log(str1 > str2);  // false

var res = str1.localeCompare(str2);
console.log(res);  // 1

"伍"与"陈"进行排序。在中文习惯中,"伍"应排在"陈"的后面。

但在第一种比较中,却显示"伍"排在前面。这是因为默认情况下,是根据汉字的Unicode编码来排序的,而不是根据汉字拼音。

而在中文环境中,对汉字的排序一般根据汉字拼音来排序。第二种情况通过str1.localeCompare()方法,采用了本地化的比较方法,就得出了正确的结果。

农历日期支持

var date = new Date();
console.log(new Intl.DateTimeFormat("zh-Hans-CN-u-ca-chinese").format(date));  // 37/4/27

在六十甲子纳音表中,序号为37的干支是"庚子"。4代表农历四月,27代表农历廿七。合起来,则表示"农历庚子年四月廿七"。喔!

var date = new Date("2020/05/27 09:15:00");
console.log(new Intl.DateTimeFormat("zh-Hans-CN-u-ca-chinese").format(date));  // 37/闰4/5

没错,庚子年闰四月初五。

Intl对象

Intl是专用于国际化的一个对象。可提供与语言相关的字符串比较、数字格式化,以及日期时间格式化。

new Intl.DateTimeFormat([locales[, options]])

Intl的构造器属性

有以下构造器属性:

  • Intl.Collator()
  • Intl.DateTimeFormat()
  • Intl.DisplayNames()
  • Intl.ListFormat()
  • Intl.Locale()
  • Intl.NumberFormat()
  • Intl.PluralRules()
  • Intl.RelativeTimeFormat()

Intl.Collator()构造器

var array = ['一', '二', '三'];

array.sort(new Intl.Collator("zh-Hans-CN-u-co-pinyin").compare);  // 使用中文拼音排序
console.log(array);  // ["二", "三", "一"]

array = ['1', '2', '10'];

array.sort(new Intl.Collator("zh-Hans-CN-u-kn-false").compare);  // 表示数字的字符串不按其所代表的数值来排序
console.log(array);  // ["1", "10", "2"]

array = ['1', '2', '10'];

array.sort(new Intl.Collator("zh-Hans-CN-u-kn-true").compare);  // 表示数字的字符串按其所代表的数值来排序
console.log(array);  // ["1", "2", "10"]

其语法为:

new Intl.Collator([locales[, options]])

locales是一个BCP 47语言的标签,或是一个这样的字符串的数组。支持Unicode扩展的关键字。

BCP 47语言的标签表示的一些标识:

zh-Hans-CN: 中国-简体汉字-大陆,语言-方言-地区

// 以下的表示是相等的
zh = zh-Hans = zh-CN = zh-Hans-CN

zh-Hant-HK: 中国-繁体汉字-香港,语言-方言-地区
zh-Hant-MO: 中国-繁体汉字-澳门,语言-方言-地区
zh-Hant-TW: 中国-繁体汉字-台湾,语言-方言-地区

zh-Hans-CN-u-ca-chinese: 中国汉字大陆,使用扩展,日历为中国日历,即农历
co
比较方法。支持的值有: "big5han", "dict", "gb2312", "pinyin"等。
kn
是否应用数值比较法来比较表示数值的字符串,如"1"<"2"<"10"。支持的值有: "true", "false"。
kf
先比较大写,还是先比较小写。支持的值有: "upper", "lower", "false"。

options,属性集。

Intl.Locale()构造器

const korean = new Intl.Locale('ko', {
    script: 'Kore', region: 'KR', hourCycle: 'h24', calendar: 'gregory'
});

const chinese = new Intl.Locale('zh-Hans-CN-u-ca-chinese');

但Safari及IE均不支持Intl.Locale对象。Chrome及Firefox支持。

Locale有一些属性及方法。由于支持不普遍,这里不列举。

Intl.DateTimeFormat()构造器

最简单的使用方法。

var date = new Date();
console.log(new Intl.DateTimeFormat("zh").format(date));  // 2020/5/20

使用扩展数字系统(numbering system)。

var date = new Date();

console.log(new Intl.DateTimeFormat("zh-Hans-CN-u-nu-fullwide").format(date));  // 2020/5/20
console.log(new Intl.DateTimeFormat("zh-Hans-CN-u-nu-hanidec").format(date));  // 二〇二〇/五/二〇

使用扩展日历

var date = new Date();

console.log(new Intl.DateTimeFormat("zh-Hans-CN-u-ca-chinese").format(date));
// 37/4/28, 37代表庚子,农历四月廿八

console.log(new Intl.DateTimeFormat("zh-Hans-CN-u-ca-chinese-nu-hanidec").format(date));
// 三七/四/二八, 用大写数字来表示农历

语法

new Intl.DateTimeFormat([locales[, options]])

locales的用法如上面的一些例子。

options包含一些格式化因式。下面是一些例子。

var date = new Date("2020/05/03 19:15:00");
var options = {
    dateStyle: "full",
    timeStyle: "full",
    calendar: "chinese",
    numberingSystem: "handidec",
    
    year: "numeric",
    month: "numeric",
    day: "numeric",
    hour: "numeric",
    minute: "numeric",
    
    weekday: "long",
    
    dayPeriod: "long",
    
    hour12: false,
    hourCycle: "h24"
};
console.log(new Intl.DateTimeFormat("zh-Hans-CN-u-ca-chinese", options).format(date));
// 37年4月11日 星期日 19时 : 打开 weekday
// 37/4/11 19:15 : 打开 minute
// 37/4/11 19时 : 关闭 weekday

Intl的方法

  • getCanonicalLocales()

getCanonicalLocales()

对于本地化的字符,有时大小写容易混淆,可用此方法来返回规范的写法。

console.log(Intl.getCanonicalLocales('zh-cn'));  // ["zh-CN"]
console.log(Intl.getCanonicalLocales(['zh-cn', 'EN-US', 'FR']));  // ["zh-CN", "en-US", "fr"]

References