加载中...

5.3 Date 类型


ECMAScript 中的Date 类型是在早期Java 中的java.util.Date 类基础上构建的。为此,Date类型使用自UTC(Coordinated Universal Time,国际协调时间)1970 年1 月1 日午夜(零时)开始经过的毫秒数来保存日期。在使用这种数据存储格式的条件下,Date 类型保存的日期能够精确到1970 年1月1 日之前或之后的285 616 年。

要创建一个日期对象,使用new 操作符和Date 构造函数即可,如下所示。

var now = new Date();
运行一下
在调用Date 构造函数而不传递参数的情况下,新创建的对象自动获得当前日期和时间。如果想根据特定的日期和时间创建日期对象,必须传入表示该日期的毫秒数(即从UTC 时间1970 年1 月1 日午夜起至该日期止经过的毫秒数)。为了简化这一计算过程,ECMAScript 提供了两个方法:Date.parse()和Date.UTC()。

其中,Date.parse()方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应日期的毫秒数。ECMA-262 没有定义Date.parse()应该支持哪种日期格式,因此这个方法的行为因实现而异,而且通常是因地区而异。将地区设置为美国的浏览器通常都接受下列日期格式:

  • “月/日/年”,如6/13/2004;
  • “英文月名 日,年”,如January 12,2004;
  • “英文星期几 英文月名 日 年 时:分:秒 时区”,如Tue May 25 2004 00:00:00 GMT-0700。
  • ISO 8601 扩展格式YYYY-MM-DDTHH:mm:ss.sssZ(例如2004-05-25T00:00:00)。只有兼容ECMAScript 5 的实现支持这种格式。

例如,要为2004 年5 月25 日创建一个日期对象,可以使用下面的代码:

var someDate = new Date(Date.parse("May 25, 2004"));
运行一下

如果传入Date.parse()方法的字符串不能表示日期,那么它会返回NaN。实际上,如果直接将表示日期的字符串传递给Date 构造函数,也会在后台调用Date.parse()。换句话说,下面的代码与前面的例子是等价的:

var someDate = new Date("May 25, 2004");

这行代码将会得到与前面相同的日期对象。

日期对象及其在不同浏览器中的实现有许多奇怪的行为。其中有一种倾向是将超出范围的值替换成当前的值,以便生成输出。例如,在解析"January 32, 2007"时,有的浏览器会将其解释为"February 1, 2007"。而Opera 则倾向于插入当前月份的当前日期,返回"January 当前日期,2007"。也就是说,如果在2007 年9 月21 日运行前面的代码,将会得到"January 21, 2007"(都是21 日)。

Date.UTC()方法同样也返回表示日期的毫秒数,但它与Date.parse()在构建值时使用不同的信息。Date.UTC()的参数分别是年份、基于0 的月份(一月是0,二月是1,以此类推)、月中的哪一天(1 到31)、小时数(0 到23)、分钟、秒以及毫秒数。在这些参数中,只有前两个参数(年和月)是必需的。如果没有提供月中的天数,则假设天数为1;如果省略其他参数,则统统假设为0。以下是两个使用Date.UTC()方法的例子:

// GMT 时间2000 年1 月1 日午夜零时
var y2k = new Date(Date.UTC(2000, 0));
// GMT 时间2005 年5 月5 日下午5:55:55
var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));
运行一下

这个例子创建了两个日期对象。第一个对象表示GMT 时间2000 年1 月1 日午夜零时,传入的值一个是表示年份的2000,一个是表示月份的0(即一月份)。因为其他参数是自动填充的(即月中的天数为1,其他所有参数均为0),所以结果就是该月第一天的午夜零时。第二个对象表示GMT 时间2005年5 月5 日下午5:55:55,即使日期和时间中只包含5,也需要传入不一样的参数:月份必须是4(因为月份是基于0 的)、小时必须设置为17(因为小时以0 到23 表示),剩下的参数就很直观了。

如同模仿Date.parse()一样,Date 构造函数也会模仿Date.UTC(),但有一点明显不同:日期和时间都基于本地时区而非GMT 来创建。不过,Date 构造函数接收的参数仍然与Date.UTC()相同。

因此,如果第一个参数是数值,Date 构造函数就会假设该值是日期中的年份,而第二个参数是月份,以此类推。据此,可以将前面的例子重写如下。

// 本地时间2000 年1 月1 日午夜零时
var y2k = new Date(2000, 0);
// 本地时间2005 年5 月5 日下午5:55:55
var allFives = new Date(2005, 4, 5, 17, 55, 55);
运行一下

以上代码创建了与前面例子中相同的两个日期对象,只不过这次的日期都是基于系统设置的本地时区创建的。

ECMAScript 5 添加了Date.now()方法,返回表示调用这个方法时的日期和时间的毫秒数。这个方法简化了使用Date 对象分析代码的工作。例如:

//取得开始时间
var start = Date.now();
//调用函数
doSomething();
//取得停止时间
var stop = Date.now(),
result = stop – start;

支持Date.now()方法的浏览器包括IE9+、Firefox 3+、Safari 3+、Opera 10.5 和Chrome。在不支持它的浏览器中,使用+操作符把Date 对象转换成字符串,也可以达到同样的目的。

//取得开始时间
var start = +new Date();
//调用函数
doSomething();
//取得停止时间
var stop = +new Date(),
result = stop - start;

5.3.1 继承的方法

与其他引用类型一样,Date 类型也重写了toLocaleString()、toString()和valueOf()方法;

但这些方法返回的值与其他类型中的方法不同。Date 类型的toLocaleString()方法会按照与浏览器设置的地区相适应的格式返回日期和时间。这大致意味着时间格式中会包含AM 或PM,但不会包含时区信息(当然,具体的格式会因浏览器而异)。而toString()方法则通常返回带有时区信息的日期和时间,其中时间一般以军用时间(即小时的范围是0 到23)表示。下面给出了在不同浏览器中调用toLocaleString()和toString()方法,输出PST(Pacific Standard Time,太平洋标准时间)时间2007年2 月1 日午夜零时的结果。

Internet Explorer 8
toLocaleString() — Thursday, February 01, 2007 12:00:00 AM
toString() — Thu Feb 1 00:00:00 PST 2007
Firefox 3.5
toLocaleString() — Thursday, February 01, 2007 12:00:00 AM
toString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
Safari 4
toLocaleString() — Thursday, February 01, 2007 00:00:00
toString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
Chrome 4
toLocaleString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
toString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
Opera 10
toLocaleString() — 2/1/2007 12:00:00 AM
toString() — Thu, 01 Feb 2007 00:00:00 GMT-0800

显然, 这两个方法在不同的浏览器中返回的日期和时间格式可谓大相径庭。事实上,toLocaleString()和toString()的这一差别仅在调试代码时比较有用,而在显示日期和时间时没有什么价值。

至于Date 类型的valueOf()方法,则根本不返回字符串,而是返回日期的毫秒表示。因此,可以方便使用比较操作符(小于或大于)来比较日期值。请看下面的例子。

var date1 = new Date(2007, 0, 1); //"January 1, 2007"
var date2 = new Date(2007, 1, 1); //"February 1, 2007"
alert(date1 < date2); //true
alert(date1 > date2); //false
运行一下

从逻辑上讲,2007 年1 月1 日要早于2007 年2 月1 日,此时如果我们说前者小于后者比较符合常理。而表示2007 年1 月1 日的毫秒值小于表示2007 年2 月1 日的毫秒值,因此在首先使用小于操作符比较日期时,返回的结果是true。这样,就为我们比较日期提供了极大方便。

5.3.2 日期格式化方法

Date 类型还有一些专门用于将日期格式化为字符串的方法,这些方法如下。
  • toDateString()——以特定于实现的格式显示星期几、月、日和年;
  • toTimeString()——以特定于实现的格式显示时、分、秒和时区;
  • toLocaleDateString()——以特定于地区的格式显示星期几、月、日和年;
  • toLocaleTimeString()——以特定于实现的格式显示时、分、秒;
  • toUTCString()——以特定于实现的格式完整的UTC 日期。

与toLocaleString()和toString()方法一样,以上这些字符串格式方法的输出也是因浏览器而异的,因此没有哪一个方法能够用来在用户界面中显示一致的日期信息。

除了前面介绍的方法之外,还有一个名叫toGMTString()的方法,这是一个与toUTCString()等价的方法,其存在目的在于确保向后兼容。不过,ECMAScript 推荐现在编写的代码一律使用toUTCString()方法。

5.3.3 日期/时间组件方法

到目前为止,剩下还未介绍的Date 类型的方法(如下表所示),都是直接取得和设置日期值中特定部分的方法了。需要注意的是,UTC 日期指的是在没有时区偏差的情况下(将日期转换为GMT 时间)的日期值。

setUTCMonth(月)
设置UTC日期中的分钟数。传入的值超过59则增加小时数

实例请前往JavaScript Date 对象参考手册

方 法
说 明
getTime()
返回表示日期的毫秒数;与valueOf()方法返回的值相同
setTime(毫秒)
以毫秒数设置日期,会改变整个日期
getFullYear()
取得4位数的年份(如2007而非仅07)
getUTCFullYear()
返回UTC日期的4位数年份
setFullYear(年)
设置日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
setUTCFullYear(年)
设置UTC日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
getMonth()
返回日期中的月份,其中0表示一月,11表示十二月
getUTCMonth()
返回UTC日期中的月份,其中0表示一月,11表示十二月
setMonth(月)
设置日期的月份。传入的月份值必须大于0,超过11则增加年份
getDate()
返回日期月份中的天数(1到31)
getUTCDate()
返回UTC日期月份中的天数(1到31)
setDate(日)
设置日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
setUTCDate(日)
设置UTC日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
getDay()
返回日期中星期的星期几(其中0表示星期日,6表示星期六)
getUTCDay()
返回UTC日期中星期的星期几(其中0表示星期日,6表示星期六)
getHours()
返回日期中的小时数(0到23)
getUTCHours()
返回UTC日期中的小时数(0到23)
setHours(时)
设置日期中的小时数。传入的值超过了23则增加月份中的天数
setUTCHours(时)
设置UTC日期中的小时数。传入的值超过了23则增加月份中的天数
getMinutes()
返回日期中的分钟数(0到59)
getUTCMinutes()
返回UTC日期中的分钟数(0到59)
setMinutes(分)
设置日期中的分钟数。传入的值超过59则增加小时数
setUTCMinutes(分)
返回日期中的分钟数(0到59)
getSeconds()
返回日期中的秒数(0到59)
getUTCSeconds()
返回UTC日期中的秒数(0到59)
setSeconds(秒)
设置日期中的秒数。传入的值超过了59会增加分钟数
setUTCSeconds(秒)
设置UTC日期中的秒数。传入的值超过了59会增加分钟数
getMilliseconds()
返回日期中的毫秒数
getUTCMilliseconds()
返回UTC日期中的毫秒数
setMilliseconds(毫秒)
设置日期中的毫秒数
setUTCMilliseconds(毫秒)
设置UTC日期中的毫秒数
getTimezoneOffset()
返回本地时间与UTC时间相差的分钟数。例如,美国东部标准时间返回300。在某地进入夏令时的情况下,这个值会有所变化


第 1-3 条, 共 3 条.
小白 2017-10-19 16:44:41
6666回复
汉王 2017-05-05 14:23:06
@小虾米:ECMAScript 5 添加了Data.now()方法,返回表示调用这个方法时的日期和时间的毫秒数。
修改下错误:Date.now()回复
感谢已修改回复
小虾米 2017-05-05 11:59:23
ECMAScript 5 添加了Data.now()方法,返回表示调用这个方法时的日期和时间的毫秒数。
修改下错误:Date.now()回复