添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

49.md

File metadata and controls

40.日期( Date

原文: http://exploringjs.com/impatient-js/ch_dates.html

贡献者: facebesidewyj

本章介绍 JavaScript 用于处理日期的 API - Date

40.1。最佳实践:不要使用当前的内置 API

JavaScript Date API 使用起来很麻烦。因此,最好依靠第三方库来处理与日期相关的任何事情。热门第三方库包括:

  • Moment.js
  • Day.js
  • Luxon
  • js-joda
  • date-fns
  • 请参阅博客文章 “为什么你不应该使用 Moment.js ......” 了解这些第三方库的优缺点。

    此外,TC39(技术委员会(Technical Committee)第 39 号,它是 ECMA 的一部分,ECMA 是 “ECMAScript” 规范下的 JavaScript 语言标准化的机构。) 正在开发 JavaScript 的新日期 API: temporal

    41.1.1。一些要在日期库中寻找的内容

    要记住两件很重要的事:

    Tree-shaking 可以帮助减少库的大小,是一种仅将库的导出部署到Web服务器的技术,可以在某处导入。Tree-shaking对函数的影响比类更大。

    支持时区:Date对象默认不支持时区,这会带来一些问题并且这是一个关键的弱点。确保您的日期库支持时区。

    40.2。时区

    41.2.1。背景:UTC与GMT

    UTC(协调世界时)和 GMT(格林威治标准时间)具有相同的当前时间,但它们是不同的东西:

    UTC:是所有时区所基于的时间标准。它们是相对于它指定的。也就是说,没有状态或地区将 UTC 作为其本地时区。

    GMT:是一些欧洲和非洲国家使用的时区。它是UTC加零小时,因此与UTC的时间相同。

    资料来源: “TimeTndDate.com 上的 GMT 和 UTC 之间的差异”

    41.2.2。JavaScript日期对象仅支持UTC和本地时区

    我们无法为JavaScript日期指定任意时区。

    它使用两个时间系统:

  • UTC(协调世界时)
  • 本地时区(从操作系统自动获取)
  • Date实例将其时间存储在UTC中。无论何时在日期和其他数据之间进行转换,我们都需要注意是否使用了UTC或本地时区。例如: new Date() 使用本地时区,而 .toISOString() 使用UTC

    new Date(2077, 0, 27).toISOString()
    '2077-01-26T23:00:00.000Z'

    JavaScript日期对象将0解释为1月。本地时区的当月是27日,但UTC是26日。

    日期操作:UTC与本地时区

    对于本章中记录的每个操作,它在日期和其他数据之间进行转换,请注意是使用UTC还是本地时区。

    41.2.3 无法指定时区的缺点

    无法指定时区,存在两个问题:

  • 无法支持多个时区。
  • 可能导致特定位置的bug。例如,前面的示例会根据执行的位置生成不同的结果。在这种特殊情况下,输入为CET,而输出则是UTC。这就是为什么这个月的日期不同(27对26)。
  • 40.3。背景:日期时间格式(ISO)

    日期时间格式描述:

  • 接受的字符串:
  • Date.parse()
  • new Date()
  • 返回的字符串(总是最长的格式):
  • Date.prototype.toISOString()
  • 以下是 .toISOString() 返回的日期时间字符串的示例:

    '2033-05-28T15:59:59.123Z'

    日期时间格式具有以下结构:

    日期格式:Y =年份; M =月; d =天

    YYYY-MM-DD
    YYYY-MM
    

    时间格式:T =分隔符(字符串'T'); H =小时; M =分钟; s =秒和毫秒; Z =时区是 UTC(字符串'Z'

    THH:mm:ss.sss
    THH:mm:ss.sssZ
    THH:mm:ss
    THH:mm:ssZ
    THH:mm
    THH:mmZ

    日期时间格式:日期格式后跟时间格式。

  • 例如(最长):YYYY-MM-DDTHH:mm:ss.sssZ
  • Z的替代方案 - 相对于 UTC 的时区:

  • +hh:mm
  • -hh:mm
  • 40.4。时间值

    _ 时间值 _ 表示自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数的日期。

    时间值可用于创建日期:

    const timeValue = 0;
    assert.equal(
      new Date(timeValue).toISOString(),
      '1970-01-01T00:00:00.000Z');

    将日期强制转换为数字会返回其时间值:

    > Number(new Date(123))
    

    比较运算符将他们的操作数强制转换为数字。因此,您可以使用这些运算符来比较日期:

    assert.equal(new Date('1972-05-03') < new Date('2001-12-23'), true);
    // Internally:
    assert.equal(73699200000 < 1009065600000, true);

    40.4.1。创建时间值

    以下方法创建时间值:

    Date.now(): number

    返回当前时间作为时间值。

    Date.parse(dateTimeString): number(当地时区)

    解析dateTimeString并返回相应的时间值。

    Date.UTC(year, month, date?, hours?, minutes?, seconds?, milliseconds?): number

    返回指定的 UTC 日期时间的时间值。

    40.4.2。获取和设置时间值

    Date.prototype.getTime(): number

    返回与 Date 对应的时间值。

    Date.prototype.setTime(timeValue)

    this设置为timeValue编码的日期。

    40.5。创建日期

    new Date(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, milliseconds?: number)(当地时区)

    > new Date(2077,0,27, 21,49,58, 888).toISOString() // CET (UTC+1)
    '2077-01-27T20:49:58.888Z'

    new Date(dateTimeStr: string)(UTC)

    > new Date('2077-01-27').toISOString()
    '2077-01-27T00:00:00.000Z'

    new Date(timeValue: number)

    > new Date(0).toISOString()
    '1970-01-01T00:00:00.000Z'

    new Date()(与new Date(Date.now())相同)

    41.5.1 构造函数的陷阱

    new Date()的构造函数会产生两个问题:

  • 对于month,0是一月
  • 如果0≤year≤99,则为1900+yaer
  • > new Date(12, 1, 22, 19, 11).getFullYear()
    

    这就是为什么,在本章的其他地方,我们总是使用时间单位fullYear。但在这种情况下,我们别无选择。

    40.6。Getters 和 Setters

    40.6.1。时间单位Getters和Setters

    日期有时间单位的 getter 和 setter。例如:

  • Date.prototype.getFullYear()
  • Date.prototype.setFullYear(num)
  • 这些 getter 和 setter 符合以下模式:

  • 当地时间:
  • Date.prototype.get«Unit»()
  • Date.prototype.set«Unit»(num)
  • 世界时间:
  • Date.prototype.getUTC«Unit»()
  • Date.prototype.setUTC«Unit»(num)
  • 这些是支持的时间单位:

  • FullYear
  • Month:月(0-11)。 陷阱: 0 是 1 月等
  • Date:每月的某一天(1-31)
  • Day(仅限吸气剂):星期几(0-6); 0 是星期天
  • Hours:小时(0-23)
  • Minutes:分钟(0-59)
  • Seconds:秒(0-59)
  • Milliseconds:毫秒(0-999)
  • 还有一个getter不符合前面提到的模式:

    Date.prototype.getTimezoneOffset()

    返回本地时间和 UTC 之间的时差,以分钟为单位。例如,对于 CET,它返回-60

    40.7。将日期转换为字符串

    示例日期:

    const d = new Date(0);

    40.7.1。带时间的字符串

    Date.prototype.toTimeString()(当地时区)

    > d.toTimeString()
    '01:00:00 GMT+0100 (Central European Standard Time)'

    Date.prototype.toLocaleTimeString()(参见 ECMAScript 国际化 API

    40.7.2。带日期的字符串

    Date.prototype.toDateString()(当地时区)

    > d.toDateString()
    'Thu Jan 01 1970'

    Date.prototype.toLocaleDateString()ECMAScript 国际化 API

    40.7.3。带有日期和时间的字符串

    Date.prototype.toString()(当地时区)

    > d.toString()
    'Thu Jan 01 1970 01:00:00 GMT+0100 (Central European Standard Time)

    Date.prototype.toLocaleString()(参见 ECMAScript 国际化 API

    Date.prototype.toUTCString()(UTC)

    > d.toUTCString()
    'Thu, 01 Jan 1970 00:00:00 GMT'

    Date.prototype.toISOString()(UTC)

    > d.toISOString()
    '1970-01-01T00:00:00.000Z'

    练习:创建日期字符串

    exercises/dates/create_date_string_test.js