为了统一各地服务器时间,我修改了Date函数

366 阅读2分钟

最近做了一个定时打卡的脚本,然后没多想随便找了个服务器运行着了。

setInterval(()=>{
 var t = new Date();
 var htag = t.getHours()==8;
 var mtag = t.getMinutes()==30;
 htag && mtag && 发送打卡请求()
},1000*60)

看着还行对不对

没想到它并没有按我想的八点半打卡,果然哪里有代码,哪里就有bug,对着代码调试楞了大半天。得出结论:服务器的时间比中国北京时间提前五个小时。

在网上搜了解决方案,都是基于getTimezoneOffset()来调整的时区差,我当时就在想那不如直接修改原来的Date以后再new Date()的时候得到的都是东八时区的时间。

// 修改时区为东八
var timeZone = 8

var _Date = Date
Date = function(dateSign) {
  if (dateSign) return new _Date(dateSign)
  // 取本地时间
  var localtime = new _Date();
  var localtimestamp = localtime.getTime();
  // 取本地时区与格林尼治所在时区的偏差毫秒数
  var localOffset = localtime.getTimezoneOffset() * 60000;
  // 反推得到格林尼治时间
  var utc = localOffset + localtimestamp;
  // 得到指定时区时间
  var calctime = utc + (3600000 * timeZone);
  var nd = new _Date(calctime);
  return nd
}

把这段代码放在代码第一行的位置即可

不过有个缺点,不能取到Date的静态成员,比如 Date.now()你要改写成 (new Date()).now()

都多余了,刚刚翻了一下Date的静态成员,也就只有一个Date.now比较常用,直接改掉得了

Date.now = function (){
  // 一样的代码 取偏差
  var localtime = new _Date();
  var localtimestamp = localtime.getTime();
  var localOffset = localtime.getTimezoneOffset() * 60000;
  var utc = localOffset + localtimestamp;
  var calctimestamp = utc + (3600000 * timeZone);
  // 一样的代码 取偏差
  return calctimestamp
}

我觉得这次重写Date还是很有趣的,很有参考价值。其实完全可以用class继承做出来,考虑到低版本的node,为了语法兼容,没敢写ES6代码。