Date对象是 JavaScript 原生的时间库。它以1970年1月1日00:00:00作为时间的零点, 可以表示的时间范围是前后各1亿天(单位为毫秒)。

一、普通函数的用法

Date对象可以作为普通函数直接调用,返回一个代表当前时间的字符串。


注意,即使带有参数,Date作为普通函数使用时,返回的还是当前时间。

上面代码说明,无论有没有参数,直接调用Date总是返回当前时间。

二、构造函数的用法

Date还可以当作构造函数使用。对它使用new命令,会返回一个Date对象的实例。如果不加参数,实例代表的就是当前时间。


Date实例有一个独特的地方。其他对象求值的时候,都是默认调用.valueOf()方法,但是Date实例求值的时候,默认调用的是toString()方法。这导致对Date实例求值,返回的是一个字符串,代表该实例对应的时间。

上面代码中,today是Date的实例,直接求值等同于调用toString方法。

作为构造函数时,Date对象可以接受多种格式的参数,返回一个该参数对应的时间实例。


关于Date构造函数的参数,有几点说明。

第一点,参数可以是负整数,代表1970年元旦之前的时间。

第二点,只要是能被Date.parse()方法解析的字符串,都可以当作参数。

上面多种日期字符串的写法,返回的都是同一个时间。

第三,参数为年、月、日等多个整数时,年和月是不能省略的,其他参数都可以省略的。也就是说,这时至少需要两个参数,因为如果只使用“年”这一个参数,Date会将其解释为毫秒数。


上面代码中,不管有几个参数,返回的都是2013年1月1日零点。

最后,各个参数的取值范围如下。

年:使用四位数年份,比如2000。如果写成两位数或个位数,则加上1900,即10代表1910年。
     如果是负数,表示公元前。
 月:0表示一月,依次类推,11表示12月。
 日:1到31。
 小时:0到23。
 分钟:0到59。
 秒:0到59
 毫秒:0到999。
复制代码

注意,月份从0开始计算,但是,天数从1开始计算。另外,除了日期的默认值为1,小时、分钟、秒钟和毫秒的默认值都是0。

这些参数如果超出了正常范围,会被自动折算。比如,如果月设为15,就折算为下一年的4月。


上面代码的第二个例子,日期设为0,就代表上个月的最后一天。

参数还可以使用负数,表示扣去的时间。

上面代码中,分别对月和日使用了负数,表示从基准日扣去相应的时间。

三、日期的运算

类型自动转换时,Date实例如果转为数值,则等于对应的毫秒数;如果转为字符串,则等于对应的日期字符串。所以,两个日期实例对象进行减法运算时,返回的是它们间隔的毫秒数;进行加法运算时,返回的是两个字符串连接而成的新字符串。


四、静态方法

4.1 Date.now()

Date.now方法返回当前时间距离时间零点(1970年1月1日 00:00:00 UTC)的毫秒数,相当于 Unix 时间戳乘以1000。


4.2 Date.parse()

Date.parse方法用来解析日期字符串,返回该时间距离时间零点(1970年1月1日 00:00:00)的毫秒数。

日期字符串应该符合 RFC 2822 和 ISO 8061 这两个标准,即YYYY-MM-DDTHH:mm:ss.sssZ格式,其中最后的Z表示时区。但是,其他格式也可以被解析,请看下面的例子。

如果解析失败,返回NaN。


4.3 Date.UTC()

Date.UTC方法接受年、月、日等变量作为参数,返回该时间距离时间零点(1970年1月1日 00:00:00 UTC)的毫秒数。

该方法的参数用法与Date构造函数完全一致,比如月从0开始计算,日期从1开始计算。区别在于Date.UTC方法的参数,会被解释为 UTC 时间(世界标准时间),Date构造函数的参数会被解释为当前时区的时间。

// 格式
 Date.UTC(year, month[, date[, hrs[, min[, sec[, ms]]]]])
复制代码


五、实例方法

Date的实例对象,有几十个自己的方法,除了valueOf和toString,可以分为以下三类。

to类:从Date对象返回一个字符串,表示指定的时间。
 get类:获取Date对象的日期和时间。
 set类:设置Date对象的日期和时间。
复制代码

5.1 Date.prototype.valueOf()

valueOf方法返回实例对象距离时间零点(1970年1月1日00:00:00 UTC)对应的毫秒数,该方法等同于getTime方法。


预期为数值的场合,Date实例会自动调用该方法,所以可以用下面的方法计算时间的间隔。

var start = new Date();
 // ...
 var end = new Date();
 var elapsed = end - start;
复制代码

5.2 to类方法

(1)Date.prototype.toString()

toString方法返回一个完整的日期字符串。


因为toString是默认的调用方法,所以如果直接读取Date实例,就相当于调用这个方法。

(2)Date.prototype.toUTCString()

toUTCString方法返回对应的 UTC 时间,也就是比北京时间晚8个小时。


(3)Date.prototype.toISOString()

toISOString方法返回对应时间的 ISO8601 写法。

注意,toISOString方法返回的总是 UTC 时区的时间。


(4)Date.prototype.toJSON()

toJSON方法返回一个符合 JSON 格式的 ISO 日期字符串,与toISOString方法的返回结果完全相同。


(5)Date.prototype.toDateString()

toDateString方法返回日期字符串(不含小时、分和秒)。


(6)Date.prototype.toTimeString()

toTimeString方法返回时间字符串(不含年月日)。


(7)Date.prototype.toLocaleDateString()

toLocaleDateString方法返回一个字符串,代表日期的当地写法(不含小时、分和秒)。


(8)Date.prototype.toLocaleTimeString()

toLocaleTimeString方法返回一个字符串,代表时间的当地写法(不含年月日)。


5.3 get类方法

Date对象提供了一系列get*方法,用来获取实例对象某个方面的值。

getTime():返回实例距离1970年1月1日00:00:00的毫秒数,等同于valueOf方法。
 getDate():返回实例对象对应每个月的几号(从1开始)。
 getDay():返回星期几,星期日为0,星期一为1,以此类推。
 getYear():返回距离1900的年数。
 getFullYear():返回四位的年份。
 getMonth():返回月份(0表示1月,11表示12月)。
 getHours():返回小时(0-23)。
 getMilliseconds():返回毫秒(0-999)。
 getMinutes():返回分钟(0-59)。
 getSeconds():返回秒(0-59)。
 getTimezoneOffset():返回当前时间与 UTC 的时区差异,以分钟表示,返回结果考虑到了夏令时因素。
复制代码

所有这些get*方法返回的都是整数,不同方法返回值的范围不一样。

分钟和秒:0 到 59
 小时:0 到 23
 星期:0(星期天)到 6(星期六)
 日期:1 到 31
 月份:0(一月)到 11(十二月)
 年份:距离1900年的年数
复制代码


上面代码中,最后一行返回-480,即 UTC 时间减去当前时间,单位是分钟。-480表示 UTC 比当前时间少480分钟,即当前时区比 UTC 早8个小时。

上面这些get*方法返回的都是当前时区的时间,Date对象还提供了这些方法对应的 UTC 版本,用来返回 UTC 时间

getUTCDate()
 getUTCFullYear()
 getUTCMonth()
 getUTCDay()
 getUTCHours()
 getUTCMinutes()
 getUTCSeconds()
 getUTCMilliseconds()
复制代码


上面代码中,实例对象d表示当前时区(东八时区)的7月16日0点0分0秒,这个时间对于当前时区来说是7月16日,所以getDate方法返回16,对于 UTC 时区来说是7月15日,所以getUTCDate方法返回15。

5.4 set类方法

Date对象提供了一系列set*方法,用来设置实例对象的各个方面。

setDate(date):设置实例对象对应的每个月的几号(1-31),返回改变后毫秒时间戳。
 setYear(year): 设置距离1900年的年数。
 setFullYear(year [, month, date]):设置四位年份。
 setHours(hour [, min, sec, ms]):设置小时(0-23)。
 setMilliseconds():设置毫秒(0-999)。
 setMinutes(min [, sec, ms]):设置分钟(0-59)。
 setMonth(month [, date]):设置月份(0-11)。
 setSeconds(sec [, ms]):设置秒(0-59)。
 setTime(milliseconds):设置毫秒时间戳。
复制代码

这些方法基本是跟get*方法一一对应的,但是没有setDay方法,因为星期几是计算出来的,而不是设置的。另外,需要注意的是,凡是涉及到设置月份,都是从0开始算的,即0是1月,11是12月。


set*方法的参数都会自动折算。以setDate为例,如果参数超过当月的最大天数,则向下一个月顺延,如果参数是负数,表示从上个月的最后一天开始减去的天数。

set类方法和get类方法,可以结合使用,得到相对时间。

var d = new Date();
 // 将日期向后推1000天
 d.setDate(d.getDate() + 1000);
 // 将时间设为6小时后
 d.setHours(d.getHours() + 6);
 // 将年份设为去年
 d.setFullYear(d.getFullYear() - 1);
复制代码

set*系列方法除了setTime()和setYear(),都有对应的 UTC 版本,即设置 UTC 时区的时间。

setUTCDate()
 setUTCFullYear()
 setUTCHours()
 setUTCMilliseconds()
 setUTCMinutes()
 setUTCMonth()
 setUTCSeconds()
复制代码



上面代码中,本地时区(东八时区)的7月16日0点0分,是 UTC 时区的前一天下午16点。设为 UTC 时区的22点以后,就变为本地时区的上午6点。