想实现一个需求:显示某个活动网页离开始日期还有几天,或者如果已经开始了,离结束日期还有几天。相关的时间变量有三个:
- 开始时间: startDate
- 结束时间: endDate
- 当前时间: currentDate
本来打算用 moment.js 来实现,但是折腾了半天竟然没有找到简单求差的函数…… 然后请教了一下 eleme 的前端同事乔治,不消片刻就甩给我这段代码:
1 | Math.ceil((new Date('2016-03-10').getTime() - 8*3600*1000 - Date.now()) / 86400000) |
突然意识到自己好弱啊 ʅ(‾◡◝) 然后打起精神去做了下 Research:
1. 向正无穷取整 Math.ceil()
这个函数的作用是「向正无穷取整」,比如:
1 | Math.ceil(.95); // 1 |
所以上面的公式是对 ( 开始时间 - UTC+8时差 - 当前时间 ) 向正无穷取整。其中 new Date().getTime() === Date.now()
,据乔治同学说貌似前者兼容性更好。
2. 引入时差校正 getTimezoneOffset()
上面乔治给的代码里引入的 8*3600*1000
便是为了校正 UTC+8 的时差:8 hours * 3600 seconds * 1000 milliseconds,因为 Date.now() 即便跑在客户端,返回的也是 UTC0 格林威治时间。所以这里引入 **getTimezoneOffset()**,此方法可返回格林威治时间和本地时间之间的时差(以分钟为单位),如此便可以通适不同的时区了(前提是 startDate 是当地时区的时间)。
1 | var now = new Date(); |
3. 文字显示条件判断
- 开始时间 > 当前时间:里开始还有 X 天
- 开始时间 <= 当前时间 && 结束时间 > 当前时间:离结束还有 X 天
- 结束时间 = 当前时间:最后一天
- 结束时间 < 当前时间:已结束
大致就是以上的逻辑,有空封装成函数放 github 上。