

JavaScript新日期时间API Temporal简介 - 2ality
source link: https://www.jdon.com/56770
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

JavaScript 的当前日期时间 API 是出了名的难以使用。ECMAScript 提案“Temporal”是一个新的更好的日期时间 API,目前处于第 3 阶段。
这篇博文有两个目标:
- 让您了解 Temporal 的工作原理
- 帮助您开始使用
Temporal 日期时间 API 可通过全局变量访问:
- 所有对象都是不可变的。改变它们会产生新的值,类似于字符串在 JavaScript 中的工作方式。
- 支持时区和非公历。
- 时间值有几个专门的类(带时区的日期时间值、不带时区的日期时间值、不带时区的日期值等)。这有几个好处:
- 值的上下文(时区与否等)更容易理解。
- 如何完成给定的任务通常更为明显。
- .toString() 可以用更少的考虑。
- January是第 1 个月。
时区
Temporal 的时区基于IANA 时区数据库(简称:tz 数据库)。IANA 代表互联网号码分配机构。在该数据库中,每个时区都有一个标识符和定义 UTC 时间偏移的规则。如果时区具有标准时间和夏令时,则偏移量在一年中会发生变化:
const standardTime = Temporal.ZonedDateTime.from({ timeZone: 'Europe/Zurich', year: 1995, month: 11, day: 30, hour: 3, minute: 24, }); assert.equal( standardTime.toString(), '1995-11-30T03:24:00+01:00[Europe/Zurich]'); // (A) const daylightSavingTime = Temporal.ZonedDateTime.from({ timeZone: 'Europe/Zurich', year: 1995, month: 5, day: 30, hour: 3, minute: 24, }); assert.equal( daylightSavingTime.toString(), '1995-05-30T03:24:00+02:00[Europe/Zurich]'); // (B)
在标准时间中,Europe/Zurich时区的时间偏移为+1:00(A 线)。在夏令时,时间偏移为 +2:00(B 行)。
日历
Temporal 支持的日历基于标准的Unicode Unicode Common Locale Data Repository (CLDR) ——其中包括:
- buddhist: 泰国佛历
- chinese: 中国传统日历
- coptic:科普特日历
- dangi: 韩国传统日历
- ethiopic:埃塞俄比亚历法,Amote Mihret(约公元 8 年)
- gregory: 公历
- hebrew: 传统的希伯来历
- indian: 印度历
- islamic: 伊斯兰历
- iso8601:ISO 日历(使用 ISO 8601 日历周规则的公历)
- japanese: 日本皇历
- persian: 波斯历
- roc: 民国历
iso8601是多数西方国家都使用的,并通过诸如Temporal.now.zonedDateTimeISO()(返回系统时区和 ISO-8601 日历中的当前日期和挂钟时间)等方法在 Temporal 中获得额外支持。
ECMAScript 扩展 ISO-8601/RFC 3339 字符串
标准 ISO-8601 和 RFC 3339 指定了如何在字符串中表示日期。目前,Temporal增加这些功能:
- 将月日数据表示为字符串
- 在日期时间字符串中表示 IANA 时区名称
- 在日期时间字符串中表示日历系统
目标是最终使这些添加标准化(超越 ECMAScript)。
> Temporal.PlainMonthDay.from('12-24').toString() '12-24'
以下代码显示了完整的日期时间字符串的样子。在实践中,其中许多部分经常会丢失:
const zdt = Temporal.ZonedDateTime.from({ timeZone: 'Africa/Nairobi', year: 2019, month: 11, day: 30, hour: 8, minute: 55, second: 0, millisecond: 123, microsecond: 456, nanosecond: 789, }); assert.equal( zdt.toString({calendarName: 'always', smallestUnit: 'nanosecond'}), '2019-11-30T08:55:00.123456789+03:00[Africa/Nairobi][u-ca=iso8601]');
上例中日期时间字符串的部分内容:
- 日期: '2019-11-30'
- 年'-'月'-'日
- 日期和时间之间的分隔符: 'T'
- 时间: '08:55:00.123456789'
- 小时':'分':'秒
- '.' (秒和几分之一秒之间的分隔符)
- 毫秒(3 位数)
- 微秒(3 位)
- 纳秒(3 位数字)
- 相对于 UTC 的时间偏移: '+03:00'
- 替代:'Z'这意味着'+0:00'
- 时区: '[Africa/Nairobi]'
- 日历: '[u-ca=iso8601]'
Temporal API 概述
本节概述了 Temporal API 的类。它们都可以通过全局变量访问Temporal(Temporal.Instant,Temporal.ZonedDateTime,等)。
- 挂钟时间与精确时间
时间区分两种时间。给定全局时间:
- 挂钟时间(也称为本地时间或时钟时间)在全球范围内变化,具体取决于时钟的时区。
- 精确时间(也称为UTC 时间)在任何地方都是相同的。
纪元时间是表示精确时间的一种方式:它是在Unix 纪元(1970 年 1 月 1 日午夜 UTC )之前或之后计算时间单位(例如纳秒)的数字。
Temporal 中的所有日期和/或时间类都支持两种直接创建方式。
一方面,构造函数接受完全指定日期时间值所需的最少数据量。例如,在精确时间Instant和两个类的情况下ZonedDateTime,时间本身是通过纪元纳秒指定的。
const epochNanoseconds = 6046761644163000000n; const timeZone = 'America/Los_Angeles'; // San Francisco const zdt1 = new Temporal.ZonedDateTime(epochNanoseconds, timeZone); assert.equal( zdt1.toString(), '2161-08-12T09:00:44.163-07:00[America/Los_Angeles]');
静态工厂方法.from()被重载。大多数类支持其参数的三种值。
首先,如果参数是同一类的实例,则克隆该实例:
const zdt2 = Temporal.ZonedDateTime.from(zdt1); assert.equal( zdt2.toString(), '2161-08-12T09:00:44.163-07:00[America/Los_Angeles]');
其次,所有其他对象都被解释为指定具有时间相关信息的各种字段:
const zdt3 = Temporal.ZonedDateTime.from({ timeZone: 'America/Los_Angeles', year: 2161, month: 8, day: 12, hour: 9, minute: 0, second: 44, millisecond: 163, microsecond: 0, nanosecond: 0, }); assert.equal( zdt3.toString(), '2161-08-12T09:00:44.163-07:00[America/Los_Angeles]');
第三,所有原始值都被强制转换为字符串并解析:
const zdt4 = Temporal.ZonedDateTime.from( '2161-08-12T09:00:44.163[America/Los_Angeles]'); // (A) assert.equal( zdt4.toString(), '2161-08-12T09:00:44.163-07:00[America/Los_Angeles]'); // (B)
请注意,我们不需要在 A 行中指定偏移量,而是在 B 行中。
更多点击标题,黑客新闻讨论
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK