在一个阴雨绵绵的早上,正在和基友们讨论昨晚的多人运动应该团战谁背锅的问题。这时接到两个需求:html
一、针对移动端写一个显示将来7天的日历前端
二、当用户查看一场会议时,根据用户访问的时间端不一样,作出相应的指令。通俗点就是判断时间差,当前访问时间与会议开始时间之间的差。(以分钟为基础单位)bash
两个需求都有涉及到,对于时间Date的相关操做。函数
因此为了晚上可以顺利进行多人运动,所以我便开始了我时间管理求知之路。oop
因此依照往常惯例,我打开求知路上的老朋友MDN
。打算从新过一遍关于Date
对象的相关文档说明以后,再开始时间管理。ui
Date语法:spa
new Date();prototype
new Date(value);3d
new Date(dateString);code
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
哦豁,不查都忘记了,原来Date()
构造函数有四种基本形式。
没有参数,新建立的Date对象表示实例化时刻的日期和时间,第一种没有参数的方法估计前端平常开发中频率最高使用方法。
例如我对于Date()
直接获取当前日期显示项目右上角或者左上角。再或者就是进一步经过getDay()
获取星期的阿拉伯数字,而后转成中文日一二三四五六
相关操做而已。 再稍微复杂一点的时间选择需求,就是直接上一个第三方日历组件了。
这里的value填写的一个Unix 时间戳,表示自1970年1月1日00:00:00 UTC(the Unix epoch)以来的毫秒数,忽略了闰秒。
例如我如今写blog的时候是北京时间 2020-05-31 14:16:03
那么与之对应的时间戳就是:159095764
(小贴士,这里的value类型是整数字)
也就是符合即符合 IETF-compliant RFC 2822 timestamps 或 version of ISO8601 规则下的时间字符串。 例如说:
December 17, 1995 03:24:00
1995-12-17T03:24:00
这些字符串都是dateString
, 固然有人可能说我不清楚是否我输入了dateString
是不是正确。这时能够借用Date.parse()
做为基本的验证。
Date.parse('2020-05-31T14:43:00') //输出:1590907380000
复制代码
Date.parse()
方法解析一个表示某个日期的字符串,并返回从1970-1-1 00:00:00 UTC 到该日期对象(该日期对象的UTC时间)的毫秒数,若是该字符串没法识别,或者一些状况下,包含了不合法的日期数值(如:2015-02-31),则返回值为NaN。
至关于咱们常见的new Date(dateString).getTime()
关于Date.parse()
更多详细的文档说明,能够移步到MDN - Date.parse()
关于标题栏部分,为何只填写两个词语。由于year,monthIndex是必填项, 其他的day
,hour
等一些选项都是非选项。
new Date(2020,4) // 输出 Fri May 01 2020 00:00:00 GMT+0800 (中国标准时间) {}
复制代码
当不填这些非选项时,会返回当月1号,00:00:00。(月份须要+1,这里就不在叙说了,这个我相信你们都熟悉了。)
而后前面new Date()
, 感受意犹未尽。总以为只习得new Date()
这一招感受不够用,想着寻思有没有相似直接给天数,而后可以自动算出后面的日期内置方法。
结果随手一翻,还真找到一个setDate()
有相似的做用。
语法:
dateObj.setDate(dayValue) setDate()
方法:根据本地时间来指定一个日期对象的天数。
其中参数的dayValue
,一个整数,表示该月的第几天。
let theDay = new Date(2020, 4, 30); // Sat May 30 2020 00:00:00 GMT+0800 (中国标准时间) {}
let setValue = theDay.setDate(20); // 这里直接返回new Date(2020, 4, 20).getTime()
console.log(setValue === ( new Date(2020, 4, 20).getTime())); // true
复制代码
这里有小伙伴可能就要问了,既然这个dayvalue
是整数。那我这边要是填写 32
or -10
, setDate()
也可以正常解析嘛?
这也是setDate()
好玩的地方,若是 dayValue 超出了月份的合理范围,setDate 将会相应地更新 Date 对象。
例如:
dayValue
指定0,那么日期就会被设置为上个月的最后一天。
dayValue
被设置为负数,日期会设置为上个月最后一天往前数这个负数绝对值天数后的日期。-1会设置为上月最后一天的前一天.
dayValue
设置超出该月份最大数值,则日期设置会下一个月开始依次计算。
let theDay = new Date(2020, 4, 30); // Sat May 30 2020 00:00:00 GMT+0800 (中国标准时间) {}
let bigValue = theDay.setDate(32); // theDay被设置成6月1号,
console.log(bigValue === (new Date(2020, 5, 1).getTime())) // 输出:true
let smallValue = theDay.setDate(-1) // 又被设置成 5月30日
console.log(smallValue === (new Date(2020, 4, 30).getTime())) // 输出:true
复制代码
过了一遍文档以后,那么接下来就是摩拳擦掌整需求了。
需求一列日期,默认当天显示在第一位。而后依次列出后面7天的日期和星期。
最上面一排星期却是好算,获取当天的星期,递增循环+一个临界值判断就能刷刷的写出来了。 有趣的是算日期,若是没有细看前面的文档,直接计算可能就须要判断是不是闰年,属于几月会稍微有点麻烦。
可是咱们把前面文档,那么掌控这个日期时间就是手到勤来了。一个for循环,解决日期和星期。
const Calendar = []
const WeekStr = ['日','一', '二','三','四','五','六']
for(let i = 0; i< 8 ; i++) {
Calendar[i] = {}
let loopDate = new Date();
let loopDay = loopDate.getDate() + i;
let loopValue = loopDate.setDate(loopDay)
let newDate = new Date(loopValue)
Calendar[i].day = newDate.getDate()
Calendar[i].week = WeekStr[newDate.getDay()]
}
复制代码
有趣,我都爱上我本身了。
关于时间差的需求。我一开始是没有看文档的。
脑中默认的想到就是获取当前当前时刻的getTime()
,而后会议开始时间的getTime()
进行相减,而后再根据差值范围进行条件判断。
例如:
let start = new Date(2020,5,2,16, 30).getTime()
let now = new Date(2020, 5, 2, 15, 30).getTime()
console.log(start - now) // 3600000, 换算就是60min
复制代码
后面翻阅了文档发现,还有Date.now()
属性和getTime()
也有殊途同归之效
let start = new Date(2020,5,2,16, 30).now()
let now = new Date(2020, 5, 2, 15, 30).now()
console.log(start - now) // 3600000, 换算就是60min
复制代码
最后应用到项目上时,我使用成熟的解决方案dayjs
, 固然与之相似的还有monent.js
。
简单的两个需求让我从新回顾了Date()
, 了解new Date()
更多的用法,以及setDate()
组合出神奇化学反应。
至于时间差需求,明明能够直接算出来的方法。却还须要引用第三方库day.js
一类呢?
由于因为不一样日期、月份、年份长度的不一样(日期长度不一样来自夏令时的切换),使用大于秒、分钟、小时的单位表示通过的时间会遇到不少问题,在使用前须要通过详尽的调研。
研究琢磨一番却是能够,可是立刻拿到项目中,这种成熟稳定第三方库难道不香嘛? 我可不是为了偷懒要去多人运动
最后带我王者嘛! 墨三炮贼溜。