JS 了解Date对象

前阵子写了一个周年优惠券倒计时的需求,假设优惠券过时时间为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()对象。ui

  • 本篇涉及的内容有
    • GMT & UTC
    • 时区 & Date().getTimezoneOffset()
    • Date对象的四种参数
    • Date.parse() 与 Date.UTC()
    • 小小的坑

GMT & UTC

  • GMT: 格林威治标准时间,指位于伦敦郊区的皇家格林威治天文台的标准时间,由于本初子午线被定义在经过那里的经线。spa

  • UTC: 协调世界时,以原子时秒长为基础,在时刻上接近于格林威治标准时间的一种时间计量系统。code

    因为地球的自转有些不规则,而且正在缓慢减速,格林威治时间再也不做为标准时间使用,而使用协调世界时UTC。orm

    为了方便,在不须要精确到秒的状况下,一般将GMT和UTC视为等同。对象

时区 & Date().getTimezoneOffset()

  • 时区:时区是地球上的区域使用同一个时间定义。全球被划分为24个时区,每一个时区横跨经度15度,时间恰好为1小时。因此每差一个时区,区时相差一小时。ip

    那么如何得到当前所在经纬度的区时呢?这时可使用Date对象的getTimezoneOffset()方法。字符串

  • getTimezoneOffset(): getTimezoneOffset()方法返回UTC相对于当前时区的时间差值,单位为分钟。get

    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时区的日期时间表单
相关文章
相关标签/搜索