JavaScript 中Date

问题描述

做一个项目过程中需要使用到时间戳,自然前端选择使用Date对象生成当前时间的实例。然而偶然发现当通过Date实例的两个方法生成时间戳的时候得到了不同的结果,这两个方法是
getTime 和静态方法Date.UTC. 那么两者之间的时间为什么会有差异以及由这个时间问题为出发点引出的所有的关于Date对象的时间处理问题,下面对这些问题一一进行说明。

Date 构造函数问题

我们知道在JavaScript里面获取当前时间使用new Date() 就能够实现,当传递参数为空的时候,返回的是当前的时间对象。同时不使用关键字new 也有返回内容,但是此时返回的是一个时间的字符串。

var date1 = new Date();
var date2 = Date();
console.log('type date1 '+typeof(date1));
console.log('type date2 '+typeof(date2));
console.log('date1 is '+date1);
console.log('date2 is '+date2);
console.log('date1 GMT '+date1.toGMTString());
console.log('date1 UTC '+date1.toUTCString());
console.log('date1 toString '+date1.toString());
console.log('date1 toLocaleString '+date1.toLocaleString());

结果是

logs.js:13 type date1 object
logs.js:14 type date2 string
logs.js:15 date1 is Thu Oct 12 2017 22:04:59 GMT+0800 (China Standard Time)
logs.js:16 date2 is Thu Oct 12 2017 22:04:59 GMT+0800 (China Standard Time)
logs.js:17 date1 GMT Thu, 12 Oct 2017 14:04:59 GMT
logs.js:18 date1 UTC Thu, 12 Oct 2017 14:04:59 GMT
logs.js:19 date1 toString Thu Oct 12 2017 22:04:59 GMT+0800 (China Standard Time)
logs.js:20 date1 toLocaleString 10/12/2017, 10:04:59 PM

可以总结出以下几点:第一,new Date()和Date() 返回结果不同。其中 new Date()返回的是一个时间对象实例,而Date()返回的是一个字符串。其次,关于转换成字符串的结果,上面调用了4个输出字符串的方法,返回了三种不同的结果。首先是toString方法,纯粹输出一个时间字符串,这个字符串不是任何的标准时间格式的字符串,使用价值不大,然后是toGMTString 和 toUTCString。只要是看过Date的相关API都知道现在UTC的方法已近替代了GMT的方法,两者输出内容也不足为怪,然后是LocaleString 返回的是本地的时间,这个时间一般用于在前端显示。
然后是Date作为构造函数构建时间对象实例的时候传递的参数问题,一般通过构造函数构建时间对象实例时有如下的4种构建方法:

new Date();
new Date(value);
new Date(dateString);
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

第一种方法已经使用过,直接获取当前时间对应的Date对象实例。下面说第二个构造函数,传递的是一个整数,单位为毫秒,表示的是从GMT的起始时间到当前时间经历的毫秒数。但是这个计时的起点并不是1970年1月1日的0点,需要考虑时区的偏差。
比如:

console.log(new Date(0));

输出结果为:

Thu Jan 01 1970 08:00:00 GMT+0800 (China Standard Time)

可以看到是早上八点而不是零点,因为地理位置在东八区。由此可见Date构造函数调用生成的时间对象都和地理位置相关。
第三个构造函数传递的参数是string,到底是什么样格式的String官方没有说明,
可以将toString toUTCString 以及 toLocaleString的结果传入查看输出。

var date3 = new Date()
var date4 = new Date(date3.toString())
var date5 = new Date(date3.toUTCString())
var date6 = new Date(date3.toLocaleString())
console.log('date3 is '+date3)
console.log('date4 is '+date4)
console.log('date5 is'+date5)
console.log('date6 is'+date6)

输出结果:

date3 is Thu Oct 12 2017 22:58:53 GMT+0800 (China Standard Time)
logs.js:28 date4 is Thu Oct 12 2017 22:58:53 GMT+0800 (China Standard Time)
logs.js:29 date5 isThu Oct 12 2017 22:58:53 GMT+0800 (China Standard Time)
logs.js:30 date6 isThu Oct 12 2017 22:58:53 GMT+0800 (China Standard Time)

结果来看只要时间格式正确,无论是本地字符串格式,UTC字符串格式,那么都能够正常生成时间对象。
最后一个构造函数,传递年月日时分秒作为参数构建,但是这些参数的范围需要注意。
而且这些参数都是代表的当地时间参数。举个例子,以北京时间2017年10月12日11:00:00 pm时间构建Date对象实例:

var date7 = new Date(2017,9,12,23,0,0)// 月份取值是0(1月)到11(12月) 且小时按照24小时计算,这是两个容易犯错的地方。
console.log('date7 is'+date7)

输出结果:

date7 isThu Oct 12 2017 23:00:00 GMT+0800 (China Standard Time)

综上所述,使用Date() 构建时间对象时,最终都是返回当地的时间对象。其实也可以理解为啥会这样,毕竟提供了getUTC***的调用方法帮助获取UTC时间。所以getHours 和 getUTCHours的差别就是一个获取本地的时间的小时取值,一个获取UTC时间的小时取值,两者相减可以计算时区。

两个静态函数Date.parse() 和 Date.UTC()

首先是Date.parse() 函数,文档说明很简洁,给定一个字符串,返回1970/01/01午夜到给定字符串时间的毫秒数。其实就是计算所谓的时间戳,但是这个静态函数的好处在于传递的字符串可以是UTC时间字符串,或者是本地时间字符都能够正确的计算出时间戳测试代码:

var date8 = new Date('10/12/2017, 11:30:00 PM');
console.log('date8 getTime '+date8.getTime());
console.log(Date.parse(date8.toUTCString()));
console.log(Date.parse(date8.toString()));
console.log(Date.parse(date8.toLocaleString()));

输出:

date8 getTime 1507822200000
logs.js:36 1507822200000
logs.js:37 1507822200000
logs.js:38 1507822200000

Date.UTC() 也是计算时间戳,但是传递的参数必须是UTC时间,这一点和Date.parse()不一样。例子如下:

var date9 = new Date()
console.log('current date9'+date9)
console.log('date 9 timestamp is'+date9.getTime())
var y = date9.getUTCFullYear();
var m = date9.getUTCMonth();
var d = date9.getUTCDate();
var h = date9.getUTCHours();
var M = date9.getUTCMinutes();
var s = date9.getUTCSeconds();
var ms = date9.getUTCMilliseconds();
console.log('utc is'+y+' '+m+' '+d+' '+h+' '+M+' '+s+' '+ms);
var timestamp = Date.UTC(y,m,d,h,M,s,ms);
console.log('use utc calculate timestamp'+timestamp);

输出结果:

current date9Thu Oct 12 2017 23:49:17 GMT+0800 (China Standard Time)
logs.js:42 date 9 timestamp is1507823357692
logs.js:50 utc is2017 9 12 15 49 17 692
logs.js:52 use utc calculate timestamp1507823357692

最初的问题

为什么getTime 和Date.UTC() 返回时间有差异极大可能是两者构造函数传递参数一样导致的。UTC方法必须传递UTC时间而Date构造函数传递多参数构建对象时传递的是本地时间,如下代码错误的参数传递计算出了时区:

var date10 = new Date(2017,9,10,12,0,0)
var times1 = Date.UTC(2017,9,10,12,0,0)
console.log((date10.getTime()-times1)/3600000)

输出结果为-8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值