很高兴我们能够通过不同空间,不同时间,通过这篇博客相识,那一定是一种缘分,一种你和狗哥的缘分。今天我希望通过这篇博客对我所熟知的前端世界里的日期时间做一个汇总,不止是代码上的汇总哦!
目录
一、时区
1. 时区产生的原因
2. 本初子午线
3. 日不落帝国
二、不同时区电脑上的时间显示
1. 相同的时间戳
2. 不同时区的时差造成的问题
三、 JS中常用的日期时间方法
1. 年月日时分秒
2. 展示中文星期
3. 今年是平年还是闰年
4. 时间格式的兼容性
四、前端项目常用的日期时间处理库
1. moment库
2. 其他时间转换库
五、前端时间日期组件库
1. EXTJS
2. easyui
3. elementui
4. 其他
六、做为开发对于时间的思考
一、时区
在说开发世界里的日期之前,我们必须了解一下所谓的时区。正因为时区的不同,我们和世界上其他时区的人们可能看见的时间也不同。
1. 时区产生的原因
当我们半夜12点终于快要加班熬不住的时候,印尼人民说都11点了,我都睡醒一觉了,伦敦同事感觉下午才4点,还要等一等才下班。所以如果每个国家和地区都采用他们当地的时间标准,那会给我们的生活带来很多不便,而这种世界性痛点就交给了天文学家,他们商量出的解决方案就很好:将地球的经度每隔15度划分一个区域,于是划分出了24个时区,大家都采用相同的时间标准,也就是所谓的时区。
2. 本初子午线
(不知道袁本初的名字跟这个本初子午线是不是有关系)地球上每隔经度15度做为一个时区,几乎也就是太阳每隔一小时走过的经度。这样一天24小时,正好被划分为24个时区。各时区的“中央经线”规定为0°,即本初子午线;东西经15°、东西经30°、东西经45°……直到180°经线,在每条中央经线东西两侧各7.5°范围内的所有地点,一律使用该中央经线的地方时作为标准时刻。“区时系统”在很大程度上解决了各地时刻的混乱现象,使得世界上只有24种不同时刻存在, 而且由于相邻时区间的时差恰好为1个小时,这样各不同时区间的时刻换算变得极为简单。因此,一百年来,世界各地仍沿用这种区时系统。
3. 日不落帝国
天空的雾来得漫不经心
河水像油画一样安静
和平鸽慵懒步伐押着韵
心偷偷的放晴
祈祷你像英勇的禁卫军
动也不动的守护爱情
你在回忆里留下的脚印
是我爱的风景
我要送你 日不落的想念
寄出代表爱的明信片
你是否记得这首蔡依林的《日不落》,MV就是在伦敦拍的。所以给大多数人的感觉日不落帝国说的就是英国。“日不落帝国”最早源于西班牙国王卡洛斯一世的语录:在朕的国土上,太阳永不落下。由于最早的航海发展和殖民统治,最早的日不落帝国当属西班牙。
二、不同时区电脑上的时间显示
既然中国当前是下午2023年2月21日8点,印尼时间是2023年2月21日7点,那么他们怎么把不同的时间展示到网页上的呢?
1. 相同的时间戳
在前端开发中,不同时区可能显示的日期时间是不同的,但有一点,同一时刻,他们的时间戳是相同的。比如同一时刻获取时间戳的方法可以以下几种:
// 1 Date.now()
console.log(Date.now())
// 2 Date.parse()
Date.parse(new Date())
// 3 valueOf()
(new Date()).valueOf()
// 4 getTime()
new Date().getTime()
// 5 Number
Number(new Date())
2. 不同时区的时差造成的问题
其实不同时区因为时间上造成的问题主要是客户端,例如浏览器端造成的。比如我们有一个场景,有一个平台要做出海业务,C端用户平台在泰国,但可恨的是配置管理平台在中国。而泰国时间晚上12点要促销,开始降价,但中国的运营人员呢,就从本地浏览器选择了12点,然后提交了商品信息,满意的以为12点要开始促销了,泰国的用户要开始抢购一空了。但等到了运营人员以为的12点,其实泰国人家才11点。原本等着泰国到了12点开始秒杀也还行,但偏偏这个平台中国也能访问,结果主要给泰国人民准备的好货,还没到时间呢,被中国人秒了。
所以这个时候前端给服务端的接口提供的入参就不能是纯日期时间格式了,例如这样:
fetch(url, {
// data: '2023-02-12 00:00:00' // 这样存到服务器还是12点
data: 1676963491162 // 这里应该入参是个时间戳
})
而前端用户界面再展示的时候呢,需要从服务端获取保存的时间戳,再获取当前的时区,就可以正确显示啦,代码如下:
// 获取当前时区
var timeZone = new Date().getTimezoneOffset() / -60;
// 根据时区获取当前时间显示
function ShowTime(zone){
var time = new Date();
// 获取格林威治时间再乘以60000就是本地时间的偏移量时间
var offsetDateTime = new Date().getTimezoneOffset() * 60000;
// 获取格林威治时间
var utcTime = time.getTime() + offsetDateTime;
// 拿格林威治时间去反推指定地区时间
var newTime = utcTime + (3600000 * zone);
var returnTime = new Date(newTime);
return returnTime;
},
ShowTime(timeZone)
三、 JS中常用的日期时间方法
日期时间可以说是开发中比较常用的一个知识点,平均大概一个星期左右就会碰到一次类似的需求。而一些简单的日期时间需求呢,使用最基础的API就足以搞定啦。
1. 年月日时分秒
初学前端开发必须要掌握的几个关于日期时间的API,大概就是获取年月日时分秒,以及一些相关的周边知识。例如
var date = new Date() | 定义一个日期时间对象 |
var dateStamp = date.getTime() | 获取毫秒数(或者叫时间戳也行) |
var year = date.getFullYear() | 获取年份,4位数 |
var month = date.getMonth() | 获取月份,0-11,所以真实情况应该加1 |
var day = date.getDate() | 获取日,1-31 |
var hour = date.getHours() | 获取小时,0-23 |
var minutes = date.getMinutes() | 获取分钟,0-59 |
var seconds = date.getSeconds() | 获取秒数,0-59 |
var week = date.getDay() | 获取星期,0-6 |
所以以上月份,小时,分钟,秒数,如果在真实需求中,要求数值不足10的时候,前面要补0.
var hour = date.getHours();
hour = (hour < 10) ? '0'+hour : hour;
2. 展示中文星期
比如我们明明知道获取星期的API返回的是0-6,但真实要显示的却是 星期一 星期二 星期日这样,所以就需要多定义一个支持星期的数组变量,代码如下:
var chineseWeek = ['日', '一', '二', '三', '四', '五', '六'];
var weekDay = date.getDay();
var weekShow = `星期${chineseWeek[weekDay]}`;
3. 今年是平年还是闰年
我记得有个口诀是4年一润,百年不润,400年又一润。所以判断代码就是
if(year % 4 == 0 && year % 100 != 0 || year % 400 ==0){
console.log(year+"是闰年")
}else{
console.log(year+"是平年")
}
4. 时间格式的兼容性
如果服务端给我们返回了‘2023-03-05’这样的日期,如果我们想通过 new Date(time)的方式初始化日期,在IOS或者safari上很可能会出现异常情况,所以在new Date()初始化之前应该对日期格式做一个统一的处理,也就是如下代码段:
var time = '2023-05-04';
time = time.replace(/-/g, '/');
// 转换为2023/05/04的格式较好
其实我记得之前还在用jquery的时候,不想用easyui,公司的需求要求支持每年的节假日,所以我就自己写了一个,还有好多时间相关的转换,我都在里面手写了。比如今天是今年的第几周,这个月第一天是周几之类的,感兴趣的可以去看看这个9年前的古董支持每年法定节假日的日历。
四、前端项目常用的日期时间处理库
其实我们做项目嘛,大多数时候还是拷过来,拷过去,想想其实也挺没意思的,但是又想到你CV的过程中,慢慢的,慢慢的就到了发工资的时间,也就没有那么无趣了。事实证明,人世间各种你不情我不愿,但只要给钱,我就可。
1. moment库
moment库支持html文档中标签引入,你也可以通过npm 安装,使用也很方便,而我们最常用的恐怕就是format格式处理了。上手容易,使用简单,大家可以试一试
let time1 = moment().format("YYYY-MM-DD");
let now = moment(new Date()).format("YYYY-MM-DD HH:mm:ss");
2. 其他时间转换库
DayJs 安装 · Day.js (gitee.io)
ms 使用链接:vercel/ms: Tiny millisecond conversion utility (github.com)
其实日常工作中,还是推荐moment库。
五、前端时间日期组件库
组件库大家都很熟悉吧,过年回家,你搞你的组件库并不能给你带来任何实质性作用,朋友们兜里掏出一大把钱吃喝玩乐,你默默的在家里摆弄你的破组件库。亲戚朋友吃饭问你收获了什么,你说我封装了一套高性能的组件库,亲戚们懵逼了,你还在心里默默嘲笑他们,笑他们不懂你的高内聚,不懂你的低耦合,也笑他们连web项目怎么搭建的都不知道。你父母的同事都在说自己的子女一年的收获,儿子买了个房,女儿买了个车,姑娘升职加薪了,你的父母默默无言,说我的儿子封装了个组件库,跑起来电脑咔咔响、家里电表走得越来越快了
1. EXTJS
你说好好的,他就付费了,我本想找个EXTJS的日历组件截个图,但是没找到,给大家看看今天才长出来的香蕉吧
2. easyui
以我们现在看,样式是不是有点单薄,模样是不是差了那么点意思,但曾几何时,这可是陪伴了大家很久很久的一个非常完美的日历组件。
3. elementui
现在很多人已经养成习惯了,凡是用vue开发,我就要上elementUI,不用这个第三方框架我就不开心,哎,好好的团队现在也不是怎么样了,好久不更新了,问题也没人解决了,你们倒是留下一个维护的人啊。
4. 其他
其他的也很重要,还有好多,就不一一列举了,Ant Design,DatePicker,Bootstrap,layui,My97DatePicker等等吧,好乱。
六、做为开发对于时间的思考
有些人死了不是真的死了,一直到这个世上最后一个还记得他的人死了才是真的死了;一个作家死了不是真的死了,他的思想他的作品还一直流传着;而我们一年年辛苦奋斗着,一天天代码敲着,随着岁月的流逝,我们可以留下点什么呢?