2016-11-17 78 views
1

从阅读docs,我的印象是ISODate只是包装了Date构造函数。然而,我似乎无法让它们在过去很远很远的日期正常工作。例如:MongoDB ISODate()给出了不同于Date()的结果?

new Date(-8640000000000000);       // Mon Apr 19 -271821 18:00:00 GMT-0600 (Mountain Daylight Time) 
new Date(-8640000000000000).toISOString();   // -271821-04-20T00:00:00.000Z 
ISODate(new Date(-8640000000000000).toISOString()); // Wed Sep 03 2719 18:00:00 GMT-0600 (Mountain Daylight Time) 

为什么第一个日期和最后一个日期有所不同?我可以看到,我清楚地东西,某处。另外,Mongo支持的最小和最大日期是多少?

编辑:有趣的是,这个工程按预期:

new Date(new Date(-8640000000000000).toISOString()); // Mon Apr 19 -271821 18:00:00 GMT-0600 (Mountain Daylight Time) 

回答

1

对于范围部分,其在docs中提到。

在内部,日期对象被存储作为表示 自Unix纪元毫秒(1970年1月1日),的数量的64位整数,其 结果在约290百万年可表示的时间范围为 的过去和未来。

让我们来分解一下你有什么。我会在mongo shell上运行所有的东西。

new Date(-8640000000000000); //ISODate("-271821-04-20T00:00:00Z") 

new Date(-8640000000000000).toISOString(); // -271821-04-20T00:00:00.000Z 

ISODate(new Date(-8640000000000000).toISOString()); //ISODate("2719-09-04T00:00:00Z") 

让我们分析上一次日期的输出。解析新日期(-8640000000000000).toISOString()后,输出-271821-04-20T00:00:00.000Z通过ISODate函数传递。

以前获得的结果是通过ISO Date函数中的正则表达式(它只是期待正常日期)运行。

/(\ d {4}) - (\ d {2}) - (\ d {2})(T (:????(\ d {2})(:(\ ({\ d {2}(。\ d +)?))?)?(Z |([+ - ])(\ d {2}):?(\ d {2})?)?)?/

当正则表达式针对日期执行时,会产生三组。

Full match 0-9 `271821-04` 

Group 1. 0-4 `2718` 
Group 2. 4-6 `21` 
Group 3. 7-9 `04` 

所以ISODate通过这些输入的JavaScript Date.UTC构造,这将有一年2718,每月21月的一天为4 JavaScript方法处理本月21日至1年9个月,所以它将偏移1添加到2718,将年份更改为2719,将月份更改为9,日期为4.

最终输出日期为2719-09-04。

0

使用MongoDB的壳牌(嵌入在流星)

meteor:PRIMARY> new Date(1479424285700) 
ISODate("2016-11-17T23:11:25.700Z") 
meteor:PRIMARY> ISODate(new Date(1479424285700).toISOString()); 
ISODate("2016-11-17T23:11:25.700Z") 

可正常工作,都返回相同的日期。

为什么你将-8640000000000000传递给Date构造函数?你想创建什么日期?

JavaScript Date instance that represents a single moment in time. Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC.

我建议传递负值构造方法中没有包括在说明,如果你这样做,你可能会得到意想不到的效果。

+0

这只是一个创建某种最低日期的数字(具体来说,是4月19日,-271821日期)。自那以后,我一直在努力,但很好奇为什么会发生这种行为。 –

+0

你需要1970年之前的日期,毫秒精度?我建议使用'新日期(0)',即'ISODate(“1970-01-01T00:00:00Z”)' – JeremyK

+0

这是行得通的,是的。但是我从那以后改变了我的方法。这个问题更多的是出于对这种差异的好奇心,而不是试图解决我的问题。 –

相关问题