第 20 章. 日期
目录
购买本书
(广告,请不要屏蔽。)

第 20 章. 日期

JavaScript 的 Date 构造函数有助于解析、管理和显示日期。本章介绍它的工作原理。

日期 API 使用术语 UTC(协调世界时)。在大多数情况下,UTC 是 GMT(格林威治标准时间)的同义词,大致是指英国伦敦的时区。

日期构造函数

有四种调用 Date 构造函数的方法:

new Date(year, month, date?, hours?, minutes?, seconds?, milliseconds?)

根据给定的数据构造一个新的日期。时间是相对于当前时区解释的。Date.UTC() 提供了类似的功能,但相对于 UTC。参数具有以下范围

  • year:对于 0 ≤ year ≤ 99,将添加 1900。
  • month:0-11(0 表示一月,1 表示二月,等等)
  • date:1-31
  • hours:0-23
  • minutes:0-59
  • seconds:0-59
  • milliseconds:0-999

以下是一些示例

> new Date(2001, 1, 27, 14, 55)
Date {Tue Feb 27 2001 14:55:00 GMT+0100 (CET)}
> new Date(01, 1, 27, 14, 55)
Date {Wed Feb 27 1901 14:55:00 GMT+0100 (CET)}

顺便说一句,JavaScript 从 Java 继承了将 0 解释为一月、1 解释为二月等等的稍微奇怪的约定。

new Date(dateTimeStr)

这是一个日期时间字符串,它被转换为一个数字,并使用该数字调用 new Date(number)日期时间格式 解释了日期时间格式。 例如:

> new Date('2004-08-29')
Date {Sun Aug 29 2004 02:00:00 GMT+0200 (CEST)}

非法的日期时间字符串会导致将 NaN 传递给 new Date(number)

new Date(timeValue)

创建一个日期,以自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数表示。例如

> new Date(0)
Date {Thu Jan 01 1970 01:00:00 GMT+0100 (CET)}

此构造函数的反函数是 getTime() 方法,它返回毫秒数

> new Date(123).getTime()
123

您可以使用 NaN 作为参数,这将生成 Date 的一个特殊实例,“无效日期”

> var d = new Date(NaN);
> d.toString()
'Invalid Date'
> d.toJSON()
null
> d.getTime()
NaN
> d.getYear()
NaN
new Date()
为当前日期和时间创建一个对象;它的工作方式与 new Date(Date.now()) 相同。

日期构造函数方法

构造函数 Date 具有以下方法:

Date.now()
以毫秒为单位返回当前日期和时间(自 1970 年 1 月 1 日 00:00:00 UTC 起)。它产生的结果与 new Date().getTime() 相同。
Date.parse(dateTimeString)

dateTimeString 转换为自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。日期时间格式 解释了 dateTimeString 的格式。结果可用于调用 new Date(number)。以下是一些示例

> Date.parse('1970-01-01')
0
> Date.parse('1970-01-02')
86400000

如果无法解析字符串,则此方法返回 NaN

> Date.parse('abc')
NaN
Date.UTC(year, month, date?, hours?, minutes?, seconds?, milliseconds?)

给定数据转换为自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。它与具有相同参数的 Date 构造函数在两个方面有所不同:

  • 它返回一个数字,而不是一个新的日期对象。
  • 它将参数解释为 UTC,而不是本地时间。

日期原型方法

本节介绍 Date.prototype 的方法。

时间单位获取器和设置器

时间单位获取器和设置器具有以下签名:

  • 本地时间

    • Date.prototype.get«Unit»() 返回 Unit,根据本地时间。
    • Date.prototype.set«Unit»(number) 设置 Unit,根据本地时间。
  • 世界时

    • Date.prototype.getUTC«Unit»() 返回 Unit,根据世界时。
    • Date.prototype.setUTC«Unit»(number) 设置 Unit,根据世界时。

Unit 是以下单词之一

  • FullYear:通常为四位数字
  • Month:月份(0-11)
  • Date:日期(1-31)
  • Day(仅限获取器):星期几(0-6);0 表示星期日
  • Hours:小时(0-23)
  • Minutes:分钟(0-59)
  • Seconds:秒(0-59)
  • Milliseconds:毫秒(0-999)

例如

> var d = new Date('1968-11-25');
Date {Mon Nov 25 1968 01:00:00 GMT+0100 (CET)}
> d.getDate()
25
> d.getDay()
1

各种获取器和设置器

以下方法使您能够获取和设置自 1970 年 1 月 1 日以来的毫秒数以及更多内容:

不建议使用单位 Year,而建议使用 FullYear

  • Date.prototype.getYear() 已弃用;请改用 getFullYear()
  • Date.prototype.setYear(number) 已弃用;请改用 setFullYear()

将日期转换为字符串

请注意,转换为字符串高度依赖于实现。以下日期用于计算以下示例中的输出(在 Firefox 中,在编写本书时,它具有最完整的支持):

new Date(2001,9,30, 17,43,7, 856);
时间(人类可读)
  • Date.prototype.toTimeString():

    17:43:07 GMT+0100 (CET)

    当前时区中的时间。

  • Date.prototype.toLocaleTimeString():

    17:43:07

    以特定于区域设置的格式表示的时间。此方法由 ECMAScript 国际化 API 提供(请参阅 ECMAScript 国际化 API),如果没有它,则没有多大意义。

日期(人类可读)
  • Date.prototype.toDateString():

    Tue Oct 30 2001

    日期。

  • Date.prototype.toLocaleDateString():

    10/30/2001

    以特定于区域设置的格式表示的日期。此方法由 ECMAScript 国际化 API 提供(请参阅 ECMAScript 国际化 API),如果没有它,则没有多大意义。

日期和时间(人类可读)
  • Date.prototype.toString():

    Tue Oct 30 2001 17:43:07 GMT+0100 (CET)

    日期和时间,在当前时区中。对于任何没有毫秒(即,秒数完整)的 Date 实例,以下表达式为真

    Date.parse(d.toString()) === d.valueOf()
  • Date.prototype.toLocaleString():

    Tue Oct 30 17:43:07 2001

    以特定于区域设置的格式表示的日期和时间。此方法由 ECMAScript 国际化 API 提供(请参阅 ECMAScript 国际化 API),如果没有它,则没有多大意义。

  • Date.prototype.toUTCString():

    Tue, 30 Oct 2001 16:43:07 GMT

    日期和时间,以 UTC 表示。

  • Date.prototype.toGMTString():

    已弃用;请改用 toUTCString()

日期和时间(机器可读)
  • Date.prototype.toISOString():

    2001-10-30T16:43:07.856Z

    所有内部属性都显示在返回的字符串中。格式符合 日期时间格式;时区始终为 Z

  • Date.prototype.toJSON():

    此方法在内部调用 toISOString()。它由 JSON.stringify()(请参阅 JSON.stringify(value, replacer?, space?))使用,用于将日期对象转换为 JSON 字符串。

日期时间格式

节介绍将时间点表示为字符串的格式。有很多方法可以做到这一点:仅指示日期、包括时间、省略时区、指定时区等等。在对日期时间格式的支持方面,ECMAScript 5 严格遵循 ISO 8601 扩展格式标准。JavaScript 引擎相对完整地实现了 ECMAScript 规范,但仍然存在一些差异,因此您必须保持警惕。

最长的日期时间格式是

YYYY-MM-DDTHH:mm:ss.sssZ

每个部分代表日期时间数据的几位十进制数字。例如,YYYY 表示格式以四位数年份开头。以下小节解释了每个部分的含义。格式与以下方法相关

  • Date.parse() 可以解析这些格式。
  • new Date() 可以解析这些格式。
  • Date.prototype.toISOString() 以上述“完整”格式创建一个字符串

    > new Date().toISOString()
    '2014-09-12T23:05:07.414Z'

日期格式(无时间)

以下日期格式可用:

YYYY-MM-DD
YYYY-MM
YYYY

它们包括以下部分

  • YYYY 指年份(公历)。
  • MM 指月份,从 01 到 12。
  • DD 指日期,从 01 到 31。

例如

> new Date('2001-02-22')
Date {Thu Feb 22 2001 01:00:00 GMT+0100 (CET)}

时间格式(无日期)

以下时间格式可用。如您所见,时区信息 Z 是可选的:

THH:mm:ss.sss
THH:mm:ss.sssZ

THH:mm:ss
THH:mm:ssZ

THH:mm
THH:mmZ

它们包括以下部分

  • T 是格式时间部分的前缀(文字 T,而不是数字)。
  • HH 指小时,从 00 到 23。您可以使用 24 作为 HH 的值(指第二天 00 点),但随后所有剩余部分必须为 0。
  • mm 指分钟,从 00 到 59。
  • ss 指秒,从 00 到 59。
  • sss 指毫秒,从 000 到 999。
  • Z 指时区,以下两者之一

    • Z”表示 UTC
    • +”或“-”后跟时间“hh:mm

某些 JavaScript 引擎允许您仅指定时间(其他引擎需要日期)

> new Date('T13:17')
Date {Thu Jan 01 1970 13:17:00 GMT+0100 (CET)}

日期时间格式

日期格式和时间格式也可以组合使用。在日期时间格式中,您可以使用日期或日期和时间(或者,在某些引擎中,仅使用时间)。例如:

> new Date('2001-02-22T13:17')
Date {Thu Feb 22 2001 13:17:00 GMT+0100 (CET)}

时间值:自 1970-01-01 以来的毫秒数表示的日期

日期 API 所谓的 time 在 ECMAScript 规范中称为 时间值。它是一个原始数字,将日期编码为自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。每个日期对象都将其状态存储为时间值,存储在内部属性 [[PrimitiveValue]] 中(包装器构造函数 BooleanNumberString 的实例用于存储其包装的原始值的相同属性)。

警告

在时间值中忽略闰秒。

以下方法使用时间值

  • new Date(timeValue) 使用时间值创建日期。
  • Date.parse(dateTimeString) 解析包含日期时间字符串的字符串并返回时间值。
  • Date.now() 以时间值的形式返回当前日期时间。
  • Date.UTC(year, month, date?, hours?, minutes?, seconds?, milliseconds?) 解释相对于 UTC 的参数并返回时间值。
  • Date.prototype.getTime() 返回存储在接收器中的时间值。
  • Date.prototype.setTime(timeValue) 更改通过时间值指定的日期。
  • Date.prototype.valueOf() 返回存储在接收器中的时间值。此方法确定如何将日期转换为基元,如下一小节中所述。

JavaScript 整数的范围(53 位加上符号位)足够大,可以表示从公元前 285,616 年左右开始到公元 285,616 年左右结束的时间跨度。

以下是一些将日期转换为时间值的示例

> new Date('1970-01-01').getTime()
0
> new Date('1970-01-02').getTime()
86400000
> new Date('1960-01-02').getTime()
-315532800000

Date 构造函数使您能够将时间值转换为日期

> new Date(0)
Date {Thu Jan 01 1970 01:00:00 GMT+0100 (CET)}
> new Date(24 * 60 * 60 * 1000)  // 1 day in ms
Date {Fri Jan 02 1970 01:00:00 GMT+0100 (CET)}
> new Date(-315532800000)
Date {Sat Jan 02 1960 01:00:00 GMT+0100 (CET)}

将日期转换为数字

日期通过 Date.prototype.valueOf() 转换为数字,该方法返回一个时间值。 这允许您比较日期:

> new Date('1980-05-21') > new Date('1980-05-20')
true

您还可以执行算术运算,但要注意闰秒会被忽略

> new Date('1980-05-21') - new Date('1980-05-20')
86400000

警告

使用加号运算符 (+) 将日期添加到另一个日期或数字会导致字符串,因为转换为基元的默认行为是将日期转换为字符串(有关加号运算符工作原理的说明,请参阅加号运算符 (+)

> new Date('2024-10-03') + 86400000
'Thu Oct 03 2024 02:00:00 GMT+0200 (CEST)86400000'
> new Date(Number(new Date('2024-10-03')) + 86400000)
Fri Oct 04 2024 02:00:00 GMT+0200 (CEST)

下一页:21. 数学