时间,日期,倒计时,时间戳
场景1:获取当前日期
很多时候我们会展示当前日期时间,那么常用的东西,我们该如何优雅的实现呢?
const formatTime = (time, format1, format2) => {
let date = time ? new Date(time) : new Date();
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join(format1 || '-') + ' ' + [hour, minute, second].map(formatNumber).join(format2 || ':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
// 调用:
formatTime() //2018-10-30 11:21:25
formatTime('', '/', ','); //2018/10/30 11,23,02
formatTime('Tue Oct 30 2018 11:44:57 GMT+0800', '/', ','); //2018/10/30 11,44,57
formatTime('2018-10-31'); //2018-10-31 08:00:00
formatTime(1540828800000); //2018-10-31 08:00:00 //这里的时间戳为number类型而不是字符串
场景2:倒计时
很多场景都会用到倒计时,那么倒计时是如何实现的呢?这里来说说倒计时实现的两种方法:
*方法一:用两个时间值间的时间戳,再计算出时分秒,如下
function countDown(endtime) {
let cd = {};
let stamp = new Date(endtime.replace(/-/g, '/')).getTime() - new Date().getTime();
if (stamp >= 0) {
cd.d = Math.floor(stamp / (24 * 3600 * 1000));
cd.h = formatNumber(parseInt((stamp / 1000 / 3600) % 24));
cd.m = formatNumber(parseInt((stamp / 1000 / 60) % 60));
cd.s = formatNumber(parseInt(stamp / 1000 % 60));
}
return cd;
}
*方法二:用两个时间值间的时间戳,再用Date现有的方法得出时分秒,如下:
function countDown(endtime) {
let cd = {};
let stamp = new Date(endtime.replace(/-/g, '/')).getTime() - new Date().getTime();
if (stamp >= 0) {
cd.d = Math.floor(stamp / (24 * 3600 * 1000));
cd.h = formatNumber(new Date(stamp).getHours());
cd.m = formatNumber(new Date(stamp).getMinutes());
cd.s = formatNumber(new Date(stamp).getSeconds());
}
return cd;
}
- 调用:
let time;
setInterval(() => {
time = countDown('2018-11-11 11:11:11'); //{d: 12, h: "01", m: "04", s: "17"}
}, 1000)
- 上面两种方法中的结束时间都用正则替检测,如果有"-"符号则替换成“/”,因为在移动端中ios系统不识别 '2018-11-11' 这样的格式,所以替换成 '2018/11/11' 格式。
- 从场景1,场景2的方法2 中可以得出,不管我们拿到的是什么格式的时间,都可以用new Date()转为标准格式后再去处理。
场景3:时间 -》 时间戳
时间转时间戳:javascript获得时间戳的方法有五种,都是通过实例化时间对象 new Date() 来进一步获取当前的时间戳
new Date('2018-10-31 11:11:11').getTime(); //1540955471000
new Date('2018-10-31 11:11:11').valueOf() //1540955471000
Date.parse(new Date('2018-10-31 11:11:11')) //1540955471000
Date.now('2018-10-31 11:11:11') //1540880008094
Number(new Date('2018-10-31 11:11:11')) //1540955471000
上面从输出结果可以看到Date.now方法并不能识别传进去的日期,他返回的是当前时间的时间戳。
场景4:时间戳 -》 时间
new Date(1540955471000).toLocaleDateString() // 2018/10/31
new Date(1540955471000).toLocaleDateString().replace(/\//g, "-") //2018-10-31
new Date(1540955471000).toTimeString() //11:11:11 GMT+0800 (中国标准时间)
new Date(1540955471000).toTimeString().substr(0, 8) // 11:11:11
可以直接用时间戳格式转化获得当前时间,不过这样转换在某些浏览器上会出现不理想的效果,因为toLocaleDateString()方法是因浏览器而异的,比如
IE为: 2016年8月24日 22:26:19 格式
搜狗为: Wednesday, August 24, 2016 22:39:42
所以为了格式统一,一般用场景1的方法处理。
场景4:UTC,CMT,GST 分别代表什么时间
- UTC(世界标准时间):
协调世界时(英:Coordinated Universal Time ,法:Temps Universel Coordonné),又称为世界统一时间,世界标准时间,国际协调时间。英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。 - GMT(格林尼治时间)
格林威治平时(Greenwish Mean Time ),这是UTC的民间名称(GMT=UTC)。是指伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线(子午线即经线,本初子午线即 0 度经线)被定义通过那个的经线。 - GST (北京时间)
通常我们在数据库中存放,或者给用户看的时间都是GST时间。
北京时间=UTC+8=GMT+8。
场景5:比较两个时间大小
对比时间的大小,我们可以通过转换成时间戳后来比较,例如:
new Date('2018-10-11'.replace(/-/g, "/")).getTime() > new Date('2018-10-1-11').getTime() ? 0 : 1;
//1
再来看看下面方法
new Date('2018-10-11'.replace(/-/g, "/")) > new Date('2018-10-1-11') ? 0 : 1;
// 1
原来对比时间的大小可以直接new Date实例化后就笔记,不用多转一部啦。
场景5:展示 今天,昨天,近7天 ,近30天 的数据
做数据统计可视化时,通常会统计出今天,昨天,近7天等一定时间段的数据。
如果说今天是2018-10-10号,要统计出今天的数据,就是值从2018-10-10 00:00:00 到 2018-10-11 00:00:00 这个时间段的数据。
这个获得这个时间段呢?
方法1:
用到场景1的获取当前时间的方法,然后解决前面的日期再拼接个零点的字符串,例如
let start = formatTime(new Date()).split(" ")[0] + " 00:00:00" //输入当前时间
let start = formatTime((new Date().getTime) + 1*24*3600*1000).split(" ")[0] + " 00:00:00" //输入当前时间 + 一天时间 的时间戳
这个方法当然可以,那有没有比较优雅的方法呢?
Date 实例有个setDate
的方法,字面意思,就是设置日期,返回值为时间戳。
用法简单new Date().setDate(t.getDate() - 7)
则返回当前时间减去7天的时间的时间戳。
不防来写个获得这些时间期间的通用方法:
var formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
var timeInterval = function (day = 0) { //没有参数时默认为今天
var t = new Date();
t.setDate(t.getDate() + day);
var y = t.getFullYear();
var m = t.getMonth() + 1;
var d = t.getDate();
return [y, m, d].map(formatNumber).join('-') + ' 00:00:00'
};
调用:
//今天
let s1 = timeInterval();
let end1 = timeInterval(1)
//昨天
let s2 = timeInterval(-1);
let end1 = timeInterval()
//近7天
let s2 = timeInterval(-7);
let end1 = timeInterval()