夏令时 moment isDST

何谓夏令时
  • 夏令时,表示为了节约能源,人为规定时间的意思。也叫夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。全世界有近110个国家每年要实行夏令时。
  • 我国夏令时是从1986年4月开始,具体作法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时,即将表针由2时拨至3时,夏令时开始;到九月中旬第一个星期日的凌晨2时整,再将时钟拨回一小时,即将表针由2时拨至1时,夏令时结束。
  • 从1986年到1991年的六个年度,除1986年因是实行夏时制的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。在夏令时开始和结束前几天,新闻媒体均刊登有关部门的通告。1992年起,夏令时暂停实行。
日期解析格式
  • 目前碰到的日期解析格式有两种, 一个是标准格式, 一个是夏令时格式
    贴图为证
    夏令时格式.jpg

    标准格式.jpg
解决思路

1: 因为时区问题, 客户进行时间搜索时, 可能把本地的时间戳拿到, 这个时候, 就会出现问题,
(因为我们的数据以及页面都是基于北京+8时间来进行的, 客户传给我们的时间戳,
如果不加+8判断的话, 可能搜的就是北京时间以外的数据,我们要让他遵循北京时间来进行功能操作)
解决方法:
拿到时间戳后转为+8地区,再转成时间戳发送, 这样就可以拿到正确的数据了。
2: 拿到时间戳后要将他渲染成北京+8的时间,并且转换成夏令时格式
解决方法:
拿到时间戳后,可以使用moment插件, 使用对应的方法,(并且要兼容夏令时) 实现这个功能

题1:如何解决在不同的系统时区中拿到 东八的时间戳

  let startTime = new Date().FormatTime();
  let endTime = new Date(new Date().FormatTime().getTime() + 24 * 60 * 60 * 1000 - 1);
  // 拿到对应的日期时间
  Date.prototype.FormatTime = function() {
    let str = this.getBJDate();
    let start = new Date(str).toLocaleDateString();
    let nowDate = new Date(start);
    return nowDate;
  };

  //  拿到对应的北京时间戳 
  Date.prototype.getBJDate = function() {
    //获得当前运行环境时间
    var d = new Date(),
    currentDate = new Date(),
    tmpHours = currentDate.getHours();
    //算得时区
    var time_zone = -d.getTimezoneOffset() / 60;
    //少于0的是西区 西区应该用时区绝对值加京八区 重新设置时间(西区时间比东区时间早 所以加时区间    隔)
    if (time_zone < 0) {
      time_zone = Math.abs(time_zone) + 8;
      currentDate.setHours(tmpHours + time_zone);
    } else {
      //大于0的是东区  东区时间直接跟京八区相减
      time_zone -= 8;
      currentDate.setHours(tmpHours - time_zone);
    }
    return currentDate;
  };
题2:如何解决夏令时在页面中的显示问题
  • 事情的起因是这样的, 在日常项目开发中, 突然发现页面展示的日期同从页面下载的pdf、excel 里面的日期有出入,并且展示效果会随着本地系统时区进行改变。
  • 解决方法:使用moment插件
    注意 isDST()在1.2.0+版本上才可以使用
    下方例子适用于电脑设置为东八区能解析夏令时格式的机器
  let filter = {};
  import moment from "moment";
  filter.formatDate = (value, format = "YYYY-MM-DD") => {
    let weekList = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
    if (format) {
      if (format === "e") {
        var weekIndex = moment(value).days();
        return weekList[weekIndex];
      }
    } else {
      format = "YYYY-MM-DD";
    }
    // value 是时间戳
    if (isNaN(value)) return value;
    if (value) {
      value = Number(value);
      format = "YYYY-MM-DD HH:mm:ss";
      if (moment(value).isDST()) {
        return moment(value).utcOffset(9).format(fmt);
      }
      return moment(value).utcOffset(8).format(format);
    } else {
      return "";
    }
  }

  filter.install = function(Vue) {
    for (var filterName in filter) {
      if (filter.hasOwnProperty(filterName) && filterName !== "install") {
        Vue.filter(filterName, filter[filterName]);
      }
    }
  };
  export default filter;

别走, 下面还有

扩展:其实到这一步,基本的功能都已经完善了。但是, 夏令时怎么可能让你那么轻松。
  • 当我们把项目部署好以后, 由于不同时区的影响,我们的显示效果又发生了变化, 查询原因, 原来是因为上面使用的isDST的问题 ,接着我们捋一捋原因
    何谓isDST? 来看下官网解释:
       moment().isDST(); // 检查当前时刻是否为夏令时
       moment([2011, 2, 12]).isDST(); // false, 2011年3月12日不是 DST。
       moment([2011, 2, 14]).isDST(); // true, 2011年3月14日是 DST。
       // 此示例适用于 "en" 语言环境:https://www.timeanddate.com/time/dst/2011.html
    
    看了一篇文章, 以下是我的见解:
    "在实际操作中, 它运行时考虑了电脑本机得时区, 也就是说会根据你本地电脑得时区解析夏令时规 则,所以会造成在不同电脑得时区上显示不一样得时间."
    目前暂时还未发现能解决问题得方法, 建议由后端转换完后以后在接口返回前端显示, 这样避免了时区错误问题,
    贴上借鉴得文章: 里面有一个moment-timezone的方法, 可以试下能不能解决这个问题,
    momentjs
    momentjs-timezone
    https://www.it1352.com/1633225.html
结尾:

又到了对一个知识点得回顾与总结的时候,温故而知新, 希望小伙伴们看完可以有一点收获,
觉得不错的可爱们请点赞哦

你可能感兴趣的:(夏令时 moment isDST)