2016-11-17 64 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

這是行得通的,是的。但是我從那以後改變了我的方法。這個問題更多的是出於對這種差異的好奇心,而不是試圖解決我的問題。 –

相關問題