时间,日期,倒计时,时间戳

场景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.parse('2018-10-31 11:11:11') //1540955471000

Number(new Date('2018-10-31 11:11:11')) //1540955471000

+ new Date('2018-10-31 11:11:11')  //1540955471000

Date.now() //1540880008094 只能是当前时间


上面从输出结果可以看到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()

你可能感兴趣的:(时间,日期,倒计时,时间戳)