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