MongoDB ISODate()给出的结果与Date()不同?

时间:2016-11-17 22:43:11

标签: javascript mongodb date datetime mongodb-query

从阅读docs开始,我的印象是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)

2 个答案:

答案 0 :(得分:1)

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

  

在内部,Date对象存储为64位整数表示   自Unix纪元(1970年1月1日)以来的毫秒数   导致可表示的日期范围约为2.9亿年   过去和未来。

让我们分解你拥有的东西。我将在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日期函数中的正则表达式(只是期望正常日期)运行。

  

/(\ 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。

答案 1 :(得分:0)

使用MongoDB Shell(嵌入在meteor中)

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 Constructor?你想创造什么日期?

  

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.

我建议将负值传递给构造函数不在规范中,如果你这样做,你可能会得到意想不到的结果。