跳到主要内容

Date类型

根据 ES 规范,JS 的Date类型的值本质上是一个Number类型的整数,表示从 UTC 时间1970年01月01日00时00分00秒到该日期的毫秒数。虽然 Date 对象的核心时间值是 UTC 时间戳,但获取日期和时间或其组成部分的基本方法都是在本地(即主机系统)时区和偏移量下工作的。

根据 ES 文档的规定,日期范围是从 April 20, 271821 BCE ~ September 13, 275760 CE(BCE:公元前,CE:公元)。

Time Values and Time Range

构造函数

要创建一个Date类型的对象,必须使用new调用构造函数Date

new Date(year, month, [day, hours, minutes, seconds, ms])

@param year 必传,只有 1900~1999 之间的年份可以用 两位数形式[0, 99]代表

@param month 必传 [0, 11]

@param day 可选[1, 31],默认是 1

@param hours 可选[0, 23],默认是 0

@param minutes 可选[0, 59],默认是 0

@param seconds 可选[0, 59],默认是 0

@param ms 可选[0, 999],默认是 0

@return Date 日期对象

依次传入年月日时分秒,毫秒来初始化创建一个日期对象;在这种形式下,yearmonth必传。

let date = new Date(1995, 11, 17, 3, 24, 0, 233);
// Sun Dec 17 1995 03:24:00 GMT+0800 (中国标准时间)

new Date(dateString)

传入一个时间的字符串形式,来创建一个对象;这个参数和Date.parse()这个方法的参数一致,按照 ES 规范文档应该使用 ISO 8601 形式的字符串。而不同浏览器解析字符串的实现不一样,大部分都兼容 RFC 2282 形式的字符串。

// ISO 8601
let date = new Date('1995-12-17T03:24:00');

// RFC 2282
let date = new Date('Fri 20 Jul 2018 00:00:00 +0800');

new Date(timestamp)

传入一个 Unix 时间戳整数来创建一个对象

let date = new Date(1595938968);
// Mon Jan 19 1970 19:18:58 GMT+0800 (中国标准时间)

如果单独使用构造函数,只会返回一个表示本地时区当前时间的字符串,并且无论Date()这种形式的单独调用,括号里面传不传参数,传任何参数,都只会返回当前时区的时间字符串。

Date(); //String : Tue Jul 28 2020 20:16:28 GMT+0800 (中国标准时间)

构造函数的静态方法

Date.UTC()

Date.UTC(year, [month, day, hours, minutes, seconds, ms])

@param year 必传,只有 1900~1999 之间的年份可以用 两位数形式[0, 99]代表

@param month 可选 [0, 11],默认是 0

@param day 可选[1, 31],默认是 1

@param hours 可选[0, 23],默认是 0

@param minutes 可选[0, 59],默认是 0

@param seconds 可选[0, 59],默认是 0

@param ms 可选[0, 999],默认是 0

@return Number 毫秒数

返回指定日期距离1, 1970, 00:00:00 UTC之间的毫秒数,其实也就是生成一个时间戳。

在最新的 ES 规范中,year必传,其它可选。

console.log(Date.UTC(96, 1, 2, 3, 4, 5)); //823230245000

Date.now()

Date.now()

@return Number 毫秒数

返回当前 UTC 时间到1, 1970, 00:00:00 UTC之间的毫秒数

console.log(Date.now()); //1595943465351

Date.parse()

Date.parse(dateString)

@param dateString ISO8601 形式时间字符串,也兼容 RFC 2282 形式的字符串

@return Number 毫秒数

// ISO 8601
Date.parse('1995-12-17T03:24:00');

// RFC 2282
Date.parse('Fri 20 Jul 2018 00:00:00 +0800');

实例方法

以下返回日期对象的指定部分

方法结果
dateObj.getDay()根据本地时间返回指定日期的星期几,[0, 6]
dateObj.getDate()根据当地时间返回指定日期在月中的第几天,[1, 31]
dateObj.getMonth()根据本地时间返回指定日期的月份,[0, 11]
dateObj.getFullYear()根据当地时间返回指定日期的年份,[0000, 9999]
要注意两位数[0, 99]只能代表1900~1999
dateObj.getHours()根据当地时间返回指定日期的小时,[0, 23]
dateObj.getMinutes()根据当地时间返回指定日期的分钟,[0, 59]
dateObj.getSeconds()根据当地时间返回指定日期的秒,[0, 59]
dateObj.getMilliseconds()根据当地时间返回指定日期的毫秒,[0, 999]
dateObj.getTime()基于标准 UTC 此刻的时间,返回 unix 时间戳,没有时区的区别
dateObj.getUTCDate()基于指定日期加减偏移量后得到的 UTC 时间在月中的第几天,[1, 31]

getDategetUTCDate为例,区别 UTC 时间和时区偏移量时间,当地是中国时区,相对于 UTC 时间偏移量是UTC+0800,也就是比 UTC 快 8 小时。

// getUTCDate需要以UTC时间为参考,如果日期对象不是以UTC为基准建立的,必须减去偏移量得到UTC时间才行,1995-12-17T03:24:00 减去偏移量 8小时 也就是前一天 1995-12-16T19:24:00Z 左右,则 getUTCDate返回这个日期表示的天数就是 16
let date = new Date('1995-12-17T03:24:00');

console.log(date.getDate()); // 17
console.log(date.getUTCDate()); // 16

//而如果在建立日期对象的时候指定其为UTC时间,也就是下面第三个例子,那么就不用减去偏移量,因为系统认定这个时间就是UTC时间,所以直接看其日期部分,得到 17
let date = new Date('1995-12-17T03:24:00Z');

console.log(date.getDate()); // 17
console.log(date.getUTCDate()); // 17

//而如果指定了偏移量,则直接根据这个偏移量得到UTC时间了,1995-12-17T03:24:00 减去偏移量 2小时 也就是 1995-12-17T01:24:00Z,仍然在当天
let date = new Date('1995-12-17T03:24:00+0200');

console.log(date.getDate()); // 17
console.log(date.getUTCDate()); // 17

DateToString

以下是Date实例上的转字符串方法

方法转换结果示例
dateObj.toString获取日期,时间,时区字符串的串接结果Fri Jul 24 2020 22:22:44 GMT+0800 (中国标准时间)
dateObj.toDateString获取日期部分Fri Jul 24 2020
dateObj.toTimeString获取时间部分10:34:53 GMT+0800 (中国标准时间)
dateObj.toISOString获取 ISO 格式的字符串2020-07-24T14:22:44.600Z
dateObj.toUTCString获取 RFC 7231 定义的 HTTP-date 的形式Fri, 24 Jul 2020 14:22:44 GMT
dateObj.toJSON获取 ISO 格式的字符串2020-07-24T14:22:44.600Z
dateObj.toLocaleDateString下午 10:22:44(浏览器语言设定是中文)
dateObj.toLocaleTimeString下午 10:22:44(浏览器语言设定是中文)
dateObj.toLocaleString2020/7/24 下午 10:22:44(浏览器语言设定是中文)

在 Chrome 的 devtool 执行console命令打印出来的日期字符串实际上是Date类型执行toString()方法得到的,所以看起来和 UTC 时间格式并不一致,注意不要和 UTC 标准时间格式搞混淆。

DateToNumber

方法结果
Date.now()返回自 1970 年 1 月 1 日 00:00:00 (UTC) 到当前 UTC 时间的毫秒数
new Date().valueOf()返回自 1970 年 1 月 1 日 00:00:00 (UTC) 指定 UTC 时间的毫秒数
Number(new Date())强制类型转换
+new Date()一元+操作符会对后面的操作数执行 ToNumber 的转换

Date不是原始类型,属于Object类型,要对Date转换成Number类型的的时候,会按照以下步骤进行:

  • 先执行规范定义的抽象操作ToPrimitive(dateObj,number)Date转原始类型,ToPrimitive 内部会获取类型的@@toPrimitive方法,也就是获取Date.prototype[@@toPrimitive]
  • 接下来Date.prototype[@@toPrimitive]内部执行的时候会将传入的转换类型参数number再传递给 ES 规范定义的抽象操作OrdinaryToPrimitive去执行;
  • OrdinaryToPrimitive 根据传入number,便先执行实例上的valueOf方法,然后再执行toString方法,所以使用Number+操作符执行的强制类型转换可以将Date类型的值转换成Number

所以,理论上所有能对操作数调用抽象操作ToNumber的都能将Date类型的值转换成Number