前阵子写了一个周年优惠券倒计时的需求,假设优惠券过期时间为2019-07-23 23:59:59,则有代码如下:
let deadline = Date.parse('2019-07-23T23:59:59')
countdownTimer = setInterval(() => {
const time = getCountDownTime(deadline)
setDay(lp((Math.floor(time.hours / 24)), 2, 0))
setHours(lp(time.hours % 24, 2, 0))
setMinutes(lp(time.minutes, 2, 0))
setSeconds(lp(time.seconds, 2, 0))
}, 1000)
一顿操作猛如虎,写完直接上线,结果发现IOS的时间居然多了8个小时????
于是借此机会,梳理一下Date()对象。
- 本篇涉及的内容有
- GMT & UTC
- 时区 & Date().getTimezoneOffset()
- Date对象的四种参数
- Date.parse() 与 Date.UTC()
- 小小的坑
GMT & UTC
-
GMT: 格林威治标准时间,指位于伦敦郊区的皇家格林威治天文台的标准时间,因为本初子午线被定义在通过那里的经线。
-
UTC: 协调世界时,以原子时秒长为基础,在时刻上接近于格林威治标准时间的一种时间计量系统。
由于地球的自转有些不规则,并且正在缓慢减速,格林威治时间不再作为标准时间使用,而使用协调世界时UTC。
为了方便,在不需要精确到秒的情况下,通常将GMT和UTC视为等同。
时区 & Date().getTimezoneOffset()
-
时区:时区是地球上的区域使用同一个时间定义。全球被划分为24个时区,每个时区横跨经度15度,时间刚好为1小时。所以每差一个时区,区时相差一小时。
那么如何获得当前所在经纬度的区时呢?这时可以使用Date对象的getTimezoneOffset()方法。
-
getTimezoneOffset(): getTimezoneOffset()方法返回UTC相对于当前时区的时间差值,单位为分钟。
const time = new Date() console.log(time.getTimezoneOffset()) // -480 (0时区-(+8时区))* 60min = -480
如果计算出来的时间比预期的时间多出8小时,可能就是时区差哦
Date对象的四种参数
- 没有参数: 返回的Date对象表示实例化时刻的日期和时间
const time = new Date()
// Tue Jul 23 2019 10:14:27 GMT+0800 (中国标准时间)
- 时间戳: 是指格林威治时间1970年01月01日00时00分00秒至指定时间的总秒数
new Date().getTime()
// 1563848320776 时间戳
new Date(1563848320776)
// Tue Jul 23 2019 10:18:40 GMT+0800 (中国标准时间)
-
表示日期的字符串值
** 标准日期字符串
- "2019-07-23" (仅日期表单)
- "2019-07-23T12:00:00" (日期时间表单)
- "2019-07-23T12:00:00.000+08:00"(具有毫秒和时区的日期时间表单)
- "2019-01-01T00:00:00.000Z"(指定UTC时区,Z是协调世界时0时区的标志)
**非标准日期字符串(根据不同浏览器的实现不同,详情请阅MDN说明)
-
分别提供日期与时间的每一个成员
至少需要提供年份与月份,没有提供参数将使用其最小值
- year: 表示年份的整数值
- monthIndex: 表示月份的整数值,从0(1月)到11(12月)
- day: 表示一个月中第几天的整数值
- hours: 表示一天中的小时数的整数值
- minutes: 表示分钟部分的整数值
- seconds: 表示秒部分的整数值
- milliseconds: 表示毫秒部分的整数值
Date.parse() 与 Date.UTC()
-
new Date('2019-07-24') 等价于 Date.parse('2019-07-24')
Date.parse()方法接受一个表示日期的字符串参数,然后尝试根据这个字符串返回相应日期的毫秒数。
如果直接将日期字符串传递给Date构造函数,也会在后台调用Date.parse()
-
new Date(2019, 6, 24) 不等价于 new Date(Date.UTC(2019, 6, 24))
Date.UTC()同样返回表示日期的毫秒数,但参数是日期与时间的每一个成员。
注意: new Date(2019, 6, 24) 是基于本地时间,而new Date(Date.UTC(2019, 6, 24))是基于UTC时间
new Date(2019, 6, 24) // Wed Jul 24 2019 00:00:00 GMT+0800 (中国标准时间) Date(Date.UTC(2019, 6, 24)) // Tue Jul 23 2019 11:58:00 GMT+0800 (中国标准时间)
小小的坑
参数为日期表单,时间却多了8个小时??
let time1 = Date.parse('2019-07-24')
// 1563926400000
let time2 = new Date().getTime()
// 1563850261989 本地时间为10AM
(time1 - time2) * 3600
// 21 (3600 = 60分钟 * 60秒 *1000毫秒到秒的转换)
官方原话为:如果不存在时区偏移,则仅日期表单将被解释为UTC时间,而日期时间表单将被解释为本地时间。 故'2019-07-24'被解释为UTC时间,并且js在本地存储时,不会存储实例化该日期时的时区信息,因此比预期多了8个小时。
参数为日期时间表单,Safari浏览器上多了8个小时??
大概是Safari浏览器将日期时间表单也解释为UTC时间吧。😊
小结
- 为保证各浏览器表现形式一样,推荐日期字符串使用具有时区的日期时间表单或者标志UTC时区的日期时间表单