菜单

今非昔比Node版本导致的Date构造函数问题和解决办法

2018年11月16日 - JavaScript

不等Node版本导致的Date构造函数问题与解决措施

2018/07/06 · JavaScript
· Date

原文出处:
康建云   

近年于卷入时间选择组件的单元测试时,为了组织出Date对象,直接利用了默认Date构造函数。自己本地开发,测试均无问题,push远程后,某个小伙伴在地方跑测试用例时,却无力回天透过,具体报错如下:

图片 1

通过截图信息,可以初步判断由于Date构造函数返回了不同日期导致,抱在奇异的态势查阅个各种材料后,竟然发现一个不大的日子构造函数里面不乏,平时祥和写起来还是浅尝辄止,没有深入了解了。下面将详细介绍是破案过程,以免各位看客后续再。

图片 2

题材排查

随定点做法,出问题后先自己本地跑了一样不好测试用例,没有任何问题,初步就足以固定是付出条件问题。于是乎就看了产小伙伴nodejs版本号,版本号为6.10.0,而团结本地node版本号为10.3.0,于是当不同nodejs命令行下直接执行如下测试用例。

JavaScript

const defaultDate = new Date(‘1995-12-17T03:24:00’);
console.log(defaultDate.toString());

1
2
3
const defaultDate = new Date(‘1995-12-17T03:24:00’);
 
console.log(defaultDate.toString());

推行结果,

Node 6.10.0:

JavaScript

> const defaultDate = new Date(‘1995-12-17T03:24:00’) >
console.log(defaultDate.toString()) Sun Dec 17 1995 11:24:00 GMT
+0800(中国标准日)

1
2
3
4
> const defaultDate = new Date(‘1995-12-17T03:24:00’)
> console.log(defaultDate.toString())
 
Sun Dec 17 1995 11:24:00 GMT +0800(中国标准时间)

Node 10.3.0:

JavaScript

const defaultDate = new Date(‘1995-12-17T03:24:00’) undefined
console.log(defaultDatae.toString()) Sun Dec 17 1995 03:24:00 GMT+0800
(中国标准时)

1
2
3
4
const defaultDate = new Date(‘1995-12-17T03:24:00’)
undefined
console.log(defaultDatae.toString())
Sun Dec 17 1995 03:24:00 GMT+0800 (中国标准时间)

暨之基本确认了该问题是出于Nodejs环境导致的问题。但是为什么会生出这般的题目呢,跟着我连续深入探秘下Date构造函数。

图片 3

深切剖析

结缘问题,提炼出以下小示例,以供深入解析Date构造函数:

JavaScript

var d1 = new Date(“1995/12/17 00:00:00”); var d2 = new
Date(“1995-12-17T00:00:00”); var d3 = new Date(“1995-12-17T00:00:00Z”);
console.log(d1.toString()); console.log(d2.toString());
console.log(d3.toString());

1
2
3
4
5
6
var d1 = new Date("1995/12/17 00:00:00");  
var d2 = new Date("1995-12-17T00:00:00");
var d3 = new Date("1995-12-17T00:00:00Z");
console.log(d1.toString());
console.log(d2.toString());
console.log(d3.toString());

nodejs 10.3.0实行结果:

JavaScript

> console.log(d1.toString()); Sun Dec 17 1995 00:00:00 GMT+0800
(中国标准时) > console.log(d2.toString()); Sun Dec 17 1995 00:00:00
GMT+0800 (中国标准时间) > console.log(d3.toString()); Sun Dec 17 1995
08:00:00 GMT+0800 (中国标准时)

1
2
3
4
5
6
> console.log(d1.toString());
Sun Dec 17 1995 00:00:00 GMT+0800 (中国标准时间)
> console.log(d2.toString());
Sun Dec 17 1995 00:00:00 GMT+0800 (中国标准时间)
> console.log(d3.toString());
Sun Dec 17 1995 08:00:00 GMT+0800 (中国标准时间)

nodejs 6.10.0行结果:

JavaScript

> console.log(d1.toString()); Sun Dec 17 1995 00:00:00 GMT+0800
(中国标准时) > console.log(d2.toString()); Sun Dec 17 1995 08:00:00
GMT+0800 (中国标准日) > console.log(d3.toString()); Sun Dec 17 1995
08:00:00 GMT+0800 (中国标准时)

1
2
3
4
5
6
> console.log(d1.toString());
Sun Dec 17 1995 00:00:00 GMT+0800 (中国标准时间)
> console.log(d2.toString());
Sun Dec 17 1995 08:00:00 GMT+0800 (中国标准时间)
> console.log(d3.toString());
Sun Dec 17 1995 08:00:00 GMT+0800 (中国标准时间)

干什么当不同条件下Nodejs的剖析行为不一样啊?这就使取下JS中干到时刻的系专业了。

同一、 构造函数是干吗的

系标准

ISO8601标准[参考5]

该专业指定了而为指定偏移时间就默认为眼前日。

图片 4

[ES5 规范][参考6]

指出了一旦没有点名偏移量,默认偏移量为Z。

图片 5

[ES6 规范][参考7]

以与ISO8601标准一样,又针对该专业做了变动,如果时区偏移量不存,日期时以给诠释吗地面时间。

图片 6

classCounter

源码分析

为了确认该问题是出于不同标准导致的,我们就待看下V8源码里面的贯彻了。
获取不同node版本对应之v8版本号,如下图所示:

JavaScript

//node 10.3.0 > process.versions.v8 ‘6.6.346.32-node.9’ //node 6.10.0
> process.versions.v8 ‘5.1.281.93’

1
2
3
4
5
6
7
//node 10.3.0
> process.versions.v8
‘6.6.346.32-node.9’
 
//node 6.10.0
> process.versions.v8
‘5.1.281.93’

查看 v8
的两样版本下git提交记录但观望于6.6版本上已经增加了对ES6规范的支持
,实现了而时区偏移量不存,日期时拿给说也地面时间之功力。

图片 7

{

问题总结

回头看文章开始的之所以底日子构造函数导致的bug,就可讲”1995-12-17T00:00:00″
在没有版本下输出1995-12-17T08:00:00,而高版本下输出1995-12-17T00:00:00之题目了。

经过上述标准以及源码,低版本由于会加默认偏移量Z,默认就解析成0时区之工夫,而我们当东八区,所以最后我们地方的光阴是1995-12-17T08:00:00,高版本下由于没有Z,默认会解析成本地时间,输出结果最后便是1995-12-17T00:00:00。

题目迎刃而解方案就是是单独待添加岁月偏移量即可,如下new
Date(‘1995-12-17T03:24:00+08:00’)。

public:

经验教训

是因为浏览器的异样与未雷同,强烈建议不设
使用Date构造函数解析日期字符串(并且Date.parse它们是当价格的)。

尽可能采取“YYYY / MM /
DD”作为日期字符串,或者采用时隔三差五转的构造函数来布局Date对象,他们获取大规模地支撑。有矣这种格式,所有的年月还是地面的。

惟有你了解好于召开什么,否则要避免以带有连字符号的日期(”YYYY-MM-DD”),只有较新的浏览器支持她。

// 类Counter的构造函数

参考

[1]https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global\_Objects/Date/parse

[2]https://codereview.chromium.org/1229903004

[3]https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results/20463521\#20463521

[4]https://stackoverflow.com/questions/19278797/inconsistant-date-parsing-with-missing-timezone/19279013\#19279013

[5]https://en.wikipedia.org/wiki/ISO\_8601

[6]http://www.ecma-international.org/ecma-262/5.1/\#sec-15.9.1.15

[7]http://www.ecma-international.org/ecma-262/6.0/\#sec-date-time-string-format

1 赞 1 收藏
评论

图片 8

// 特点:以类名作为函数称作,无返回路

Counter()

{

m_value = 0;

}

private:

// 数据成员

intm_value;

}

此类对象吃创造时,编译系统对象分配内存空间,并活动调用该构造函数->由构造函数完成成员的初始化工作

eg:    Counter c1;

编译系统为对象c1底每个数据成员(m_value)分配内存空间,并调用构造函数Counter(
)自动地初始化对象c1底m_value值设置为0

故:

构造函数的意:初始化对象的多少成员。

仲、 构造函数的型

classComplex

{private:

doublem_real;

doublem_imag;

public:

//    无参数构造函数

//
如果创建一个近乎你没写任何构造函数,则网会自动生成默认的无参构造函数,函数为空,什么还不做

//
只要你勾勒了一个底的之一同种植构造函数,系统就是不见面更自动生成这么一个默认的构造函数,如果指望生一个如此的无参构造函数,则用自己展示地勾画出来

Complex(void)

{

m_real = 0.0;

m_imag = 0.0;

}

//    一般构造函数(也如重载构造函数)

//
一般构造函数可以发各种参数形式,一个近似可以产生差不多只一般构造函数,前提是参数的个数或者项目不同(基于c++的重载函数原理)

// 例如:你还得写一个 Complex( int num)的构造函数出来

// 创建对象时根据传入的参数不同调用不同的构造函数

Complex(doublereal,doubleimag)

{ m_real = real;           m_imag = imag;

}

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图