菜单

不等Node版本导致的Date构造函数问题和解决智

2018年11月15日 - 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地图