从阅读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)
答案 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.
我建议将负值传递给构造函数不在规范中,如果你这样做,你可能会得到意想不到的结果。