JS 的新一代日期/时间 API Temporal

news2024/11/29 6:32:07

众所周知,JS的Date是出了名的难用,一直以来我们都在使用momentjs,dayjs等第三方库来处理日期和时间格式,于是 TC39 组织开始了对 Date 的升级改造,他们找到了 moment.js 库的作者,Maggie ,由她来担任新特性 Temporal的主力设计。

  • 特性
    • 所有的对象都是不可改变的。改变它们会产生新的值,类似于JavaScript中字符串的工作方式。
    • 它支持时区和非格雷戈尔式的日历。
    • 有几个专门针对时间值的类(带时区的日期时间值,不带时区的日期时间值,不带时区的日期值,等等)。这有几个好处。
      • 一个值的上下文(是否有时区,等等)更容易理解。
      • 如何实现一个给定的任务往往更加明显。
      • .toString() ,使用时可以少考虑很多。
    • 1月是第1个月。
    • Temporal 支持的日历基于标准的Unicode Unicode Common Locale Data Repository (CLDR) 也就是说支持农历、民国历等等
npm install @js-temporal/polyfill

import { Temporal} from '@js-temporal/polyfill';

Temporal是一个全局对象,像 Math 、Promise 一样位于顶级命名空间中,为 Javascript 语言带来了现代化的日期、时间接口。

对比Date和Temporal的使用

  • Temporal被设计为三部分

    • ISO 8601 格式的日期和时间;具体时间

    • 时区(中国北京);哪个时区的

    • 日历(中国农历);使用什么历法

  • 对比 Date

    new Date()
    //Mon May 16 2022 10:11:27 GMT+0800 (中国标准时间)
    

Date 采用 GMT格式(旧的时间表示格式) 的时间,使用方面不如 ISO 8601 通用,同时不包含 时区和历法。

使用方法

  • 如何获取本地时区的当前日期和时间?
    请注意,如果您只需要日期而不是时间,则应使用Temporal.PlainDate. 如果两者都需要,请使用Temporal.PlainDateTime.

    const date = Temporal.Now.plainDateISO();
    date.toString();
    
    Temporal.Now.plainDateTimeISO().toString();
    
  • 如何获得 Unix 时间戳?

    const timeStamp = Temporal.Now.instant();
    
    // Timestamp in Milliseconds
    timeStamp.epochMilliseconds;
    // Timestamp in Seconds
    timeStamp.epochSeconds;
    
  • Temporal在类型和遗留之间转换Date

    • 旧版Date=>Temporal.Instant和/或Temporal.ZonedDateTime
    const legacyDate = new Date('1970-01-01T00:00:01Z');
    const instant = legacyDate.toTemporalInstant();  // 转换为 temporal 格式
    
    assert.equal(instant.epochMilliseconds, legacyDate.getTime()); // 和 Date 对比
    assert.equal(instant.toString(), '1970-01-01T00:00:01Z');
    
    const zoned = instant.toZonedDateTimeISO(Temporal.Now.timeZone());
    
    assert.equal(zoned.epochMilliseconds, legacyDate.getTime());
    
    const zoned2 = instant.toZonedDateTimeISO('Asia/Shanghai');
    
    assert.equal(zoned2.epochMilliseconds, legacyDate.getTime());
    assert.equal(zoned2.timeZone.id, 'Asia/Shanghai');
    
    • 仅日期值:legacy Date=>Temporal.PlainDate
      要正确地将 date-only 转换Date为 aTemporal.PlainDate而不会受到偏离一天错误的影响,您必须确定使用哪个时区的午夜来构造Date,然后在从 转换为 时使用相同的时Temporal.Instant区Temporal.PlainDate。
    	let date = new Date(2000, 0, 1);
    	let plainDate = date
    	  .toTemporalInstant()                         // => 2000-01-01T08:00:00Z
    	  .toZonedDateTimeISO(Temporal.Now.timeZone()) // => 2000-01-01T00:00:00-08:00[America/Los_Angeles]
    	  .toPlainDate();                              // => 2000-01-01
    	  
    	assert.equal(plainDate.toString(), '2000-01-01');
    	
    	date = new Date(Date.UTC(2000, 0, 1)); // => Fri Dec 31 1999 16:00:00 GMT-0800 (Pacific Standard Time)
    	date = new Date('2000-01-01T00:00Z');  // => Fri Dec 31 1999 16:00:00 GMT-0800 (Pacific Standard Time)
    	plainDate = date
    	  .toTemporalInstant()       // => 2000-01-01T00:00:00Z
    	  .toZonedDateTimeISO('UTC') // => 2000-01-01T00:00:00+00:00[UTC]
    	  .toPlainDate();            // => 2000-01-01
    	
    	assert.equal(plainDate.toString(), '2000-01-01');
    
    • Temporal类型 => 遗留Date
    // To convert Instant to legacy Date, use the epochMilliseconds property.
    
    const instant = Temporal.Instant.from('2020-01-01T00:00:01.000999Z');
    const result = new Date(instant.epochMilliseconds);
    
    assert.equal(result.getTime(), 1577836801000); // ms since Unix epoch
    assert.equal(result.toISOString(), '2020-01-01T00:00:01.000Z');
    
    // Same thing for ZonedDateTime.
    // Note that legacy Date will not preserve the ZonedDateTime's time zone.
    
    const zoned = Temporal.ZonedDateTime.from('2020-01-01T00:00:01.001[Asia/Tokyo]');
    const result2 = new Date(zoned.epochMilliseconds);
    
    assert.equal(result2.getTime(), 1577804401001); // note, different time
    assert.equal(result2.toISOString(), '2019-12-31T15:00:01.001Z');
    
    // For most use cases, new Date(x.epochMilliseconds) is fine.
    // You may need to add an extra round() step if you want other
    // rounding behaviour than truncation. For example, here the 999
    // microseconds is rounded to 1 millisecond.
    
    const result3 = new Date(instant.round({ smallestUnit: 'millisecond' }).epochMilliseconds);
    
    assert.equal(result3.getTime(), 1577836801001);
    assert.equal(result3.toISOString(), '2020-01-01T00:00:01.001Z');
    
  • 类型之间的转换

    • 将日历日期 ( Temporal.PlainDate) 和挂钟时间 ( Temporal.PlainTime) 组合成Temporal.PlainDateTime. 就是将日期加上时间组合起来
    const date = Temporal.PlainDate.from('2020-05-14');
    
    const noonOnDate = date.toPlainDateTime(Temporal.PlainTime.from({ hour: 12 }));
    
    assert(noonOnDate instanceof Temporal.PlainDateTime);
    
    assert.equal(noonOnDate.toString(), '2020-05-14T12:00:00');
    
    
    • 将日历上的一天 ( Temporal.PlainMonthDay) 和一年组合成Temporal.PlainDate 就是将天和年组合起来
    const birthday = Temporal.PlainMonthDay.from('12-15');
    
    const birthdayIn2030 = birthday.toPlainDate({ year: 2030 });
    
    birthdayIn2030.dayOfWeek; // => 7
    
    assert(birthdayIn2030 instanceof Temporal.PlainDate);
    
    assert.equal(birthdayIn2030.toString(), '2030-12-15');
    
  • 序列化

    • 要将精确时间序列Temporal.Instant化为字符串,请使用toString(). 没有任何参数,这会给你一个 UTC 时间的字符串。

    • 如果您需要您的字符串包含 UTC 偏移量,则使用该timeZone选项Temporal.Instant.prototype.toString()将返回该时区中与确切时间相对应的挂钟时间的字符串序列化。

    • 这会丢失有关字符串所在时区的信息,因为它只保留该特定确切时间与时区的 UTC 偏移量。如果您需要您的字符串包含时区名称,请改用Temporal.ZonedDateTime它保留此信息。

    const instant = Temporal.Instant.from('2022-05-16T10:41:51Z');
    // 使用 toString 获得字符串
    const result = instant.toString(); // '2022-05-16T10:41:51Z'
    // 使用 toString 获得某时区字符串
    const result2 = instant.toString({ timeZone: 'America/Yellowknife' });
    
    // 使用 toZonedDateTimeISO 转换时区
    const zoned = instant.toZonedDateTimeISO('Asia/Seoul');
    const result3 = zoned.toString();
    
    // ZonedDateTime
    assert(zoned.equals(Temporal.ZonedDateTime.from(result3)));
    
  • 同时Temporal 支持排序, 四舍五入, 时区转换, 时间的计算等等功能

    • 具体API查看上面链接的Doc文档

Temporal 小结

1.Date不支持除用户本地时间以外的时区。Temparal 支持开发人员通过 TimeZone 来设置本地时间以外的时区。
2.计算 API 缺失。除了时区和日历类型外,其他类型都可以进行 算术运算,即时间的比较,增加,减少等。
3.不支持非公历,Calendar 类型支持 Temparal 选择日历。
4.解析器行为不可靠以至于无法使用,在 Temporal 里,new 构造函数() 或者From 方法,对参数的要求都更加规范,同时From 方法支持 日期溢出 后的逻辑处理,可以防止系统崩溃。

在这里插入图片描述

左侧绿色区域的 Instant 类型,用来表达某个瞬间的时间,不包含时区和日历的信息。右侧黄色区域的 PlainXX系列(5个),用来表达日历日期或者钟表时间,包含日历信息,而中间的 ZonedDateTime 则横跨左右两个区域,包含时区和日历信息,可以作为一个通道,连接左侧的 Instant 和右侧的 Plain系列,负责类型之间转换的桥梁,同时中间的 Timezone 时区类型 Calendar 日历类型,不单独使用,配合上方的 ZonedDateTime 类型来辅助转换。最下面的 Duration 与所有类型没有直接关系,不参与类型转换,表示一段持续时间,并且这段时间可以用来进行算术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习】实验5答案:滴滴出行-交通场景目标检测

DL_class 学堂在线《深度学习》实验课代码报告(其中实验1和实验6有配套PPT),授课老师为胡晓林老师。课程链接:https://www.xuetangx.com/training/DP080910033751/619488?channeli.area.manual_search。 持续更新中。 所有代码…

代码随想录刷题| 01背包理论基础 LeetCode 416. 分割等和子集

目录 01背包理论基础 二维dp数组 1、确定dp数组以及下标的含义 2、确定递推公式 3、dp数组如何初始化 4、确定遍历顺序 5、打印dp数组 最终代码 一维dp数组 1、确定dp数组的定义 2、确定递推公式 3、初始化dp数组 4、遍历顺序 5、打印dp数组 最终代码 416. 分割…

一次搞懂SpringBoot核心原理:自动配置、事件驱动、Condition

前言 SpringBoot是Spring的包装,通过自动配置使得SpringBoot可以做到开箱即用,上手成本非常低,但是学习其实现原理的成本大大增加,需要先了解熟悉Spring原理。如果还不清楚Spring原理的,可以先查看博主之前的文章&…

Vue实现简易购物车功能

用Vue写一个列表案例,页面布局什么的dom,不需要自己事先全部排好,而是通过li遍历,把数据遍历出来;先定义好div标签,li根据数组的长度datalist进行遍历,图片的链接要用“:”&#xff…

算法设计与分析 SCAU8597 石子划分问题

8597 石子划分问题 时间限制:1000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC;VC;JAVA Description 给定n个石子,其重量分别为a1,a2,a3,…,an。 要求将其划分为m份,每一份的划分费用定义为这份石子中最大重量与最小重量差…

nRF52832闪存FDS使用(SDK17.1.0)

陈拓 2022/10/29-2022/11/22 1. 简介 对于Nordic芯片内部FLASH存储管理有两种方式,FS (Flash Storage)和FDS (Flash Data Storage) 。FS是FDS的底层实现,FDS是对FS的封装,使用更容易。 Flash Data Storage(FDS)模块是…

容器与容器编排系统

Docker公司发明的「容器镜像」技术,创造性地解决了应用打包的难题。改变了一大批诸如容器编排、服务网格和云原生等技术,深刻影响了云计算领域的技术方向。 一、Docker 容器技术 概括起来,Docker 容器技术有3个核心概念容器、镜像和镜像仓库…

当3A射击游戏遇上Play to Earn,暴躁兔带你了解MetalCore

MetalCore是一款具有机甲风格的战斗射击类的Play to Earn & Free to Play游戏,暴躁兔对这款游戏之前也有做过分析,MetalCore在近期启动了alpha开放世界测试,之前有NFT的玩家获得key code之后可以在PC端下载后进行体验。alpha阶段在10月20…

如何使IOT2050成为PN设备

Profinet Driver(PNDriver)从V2.3开始支持IO设备(IOD)功能,支持通用网络接口和Linux操作系统,最小支持2ms的通讯周期。本文介绍如何编译PNDriver并运行在IOT2050上。 1. 编译PNDriver 因为PNDriver只支持32位模式,因…

TiDB ——TiKV

TiDB ——TiKV TiKV持久化 TiKV架构和作用TiKV数据持久化和读取TiKV如何提供MVCC和分布式事务支持TiKV基于Raft算法的分布式一致性TiKV的coprocessor TiKV架构和作用 数据持久化分布式一致性MVCC分步式事务Coprocessor RocksDB 单机持久化引擎,单机key-value的…

L2十档行情API接口的开发原理是什么?

L2十档行情API接口的开发原理不知道大家有没有了解过,其实在现实的股市量化交易中,就有不少的投资者也在思考这个问题,并且也有的部分交易者会选择自己开发来使用,不仅支持A股所有的股票数据,也能对期货、外汇、黄金等…

个人项目-部署手册

前言 一、RDS和ECS购买与配置 https://www.aliyun.com/?spm5176.12818093.top-nav.dlogo.3be916d0u0Ncp9 购买RDS(MYSQL)和ECS(规格族:突发性能实例 t6 )的时候尽量选择一个大区》如:华东(杭州)配置不需要太高(够自己使用就行了…

干货分享 | B站SLO由失败转成功,B站SRE做对了什么?

最近几年,Google SRE在国内非常流行。 Google SRE方法论中提出了SLO是SRE实践的核心,SLO为服务可靠性设定了一个目标级别,它是量化线上质量的关键因素,它是用来回答一个服务到底“什么时候叫做挂了”的根本依据,也是可…

Python网络爬虫入门篇

1. 预备知识 学习者需要预先掌握Python的数字类型、字符串类型、分支、循环、函数、列表类型、字典类型、文件和第三方库使用等概念和编程方法。 2. Python爬虫基本流程 a. 发送请求 使用http库向目标站点发起请求,即发送一个Request,Request包含&am…

xxl-job 执行成功,但是报“任务结果丢失,标记失败“错误

问题1:使用xxl定时更新数据,发现执行结果是失败的 打开日志查看,发现没报错,结果是200 打开备注,上面写着"结果丢失". 再仔细对比下,发现外面日志列表中的执行时间是00:20:18;而日志记录中的最后时间是00:39:32;也就是说线程还没执行完,就先报结果错误了. 对比日志时…

[附源码]Python计算机毕业设计宠物寄养管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

Jmeter压力测试教程(上)

JMeter压力测试一、 简介1.1优点1.2缺点二、安装2.1下载2.2解决中文乱码问题2.5配置环境变量2.4启动入门案例三、线程组相关3.1 创建多个线程组3.2 并发和顺序执行3.3 两个特殊的线程组(setUp/tearDown)线程细节设置默认http请求新增接口信息头管理器四、…

SAP ADM100-1.2之系统登录过程(ABAP)

1、SAP登录过程 为了在前端最终用户和SAP系统实例之间创建连接,sapgui.exe程序需要启动参数。参数字符串是由saplogon .exe程序使用为登录选择的SAP GUI的信息创建。 SAP登录信息有以下两个来源:SAP Logon的配置文件,以及对所选系统的消息服务器的直接请求(下图中的步骤1和…

使用Go+Lua解决Redis秒杀中库存与超卖问题

1、简介 Go语言连接go-redis进行数据库的连接,如果你对这部分尚不了解,建议你先学习这部分知识。另外,本秒杀主要解决两个问题,第一个就是超卖问题,另一个就是库存问题。没有设计专门的页面来模拟并发,我们…

布谷蓝途:易知微「可视大脑助力智慧教育」主题分享精彩实录

如今,大数据技术在教育领域的应用与普及正驶入“快车道”,但仍然存在资源管理分散、数据各自为阵、运营模式传统等痛点,如何借助新技术、新机遇并充分发挥大数据在教育教学中的支撑作用成为重中之重。 布谷蓝途作为国内前沿的大数据方案与服…