2014-10-22 27 views
2

我遇到了正確使用UTC日期的問題,並想知道是否有處理此問題的常見方法。在Javascript和MongoDB中使用UTC日期

基本上我有一個javascript datepicker,我可以選擇一個日期。例如:

2014-10-15 

當這個被轉換爲字符串JSON.stringify()我結束了:

2014-10-14T22:00:00+0200 

我假設這是正確的,因爲日期被轉換爲UTC日期。

當日期,然後到達我的Java(新澤西州)REST接口,它看起來像下面這樣:

2014-10-14T22:00:00.000Z 

的日期似乎是相同的,但+0200就不再出現了。可能導致問題。

下一個步驟是將日期保存到我的蒙戈的數據庫,然後存儲這樣的日期:

2014-10-14 20:00:00.000Z 

還有兩小時已取消,我假設這是因爲日期被再次轉換爲UTC「。

我現在的問題是,如果我重新加載頁面,我的輸入字段現在說:

2014-10-14 

,而不是二○一四年十月一十五日。

如果我手動更改數據庫中的日期並再次添加2小時以結束「2014-10-14T22:00:00.000Z」,則日期將再次正確顯示在前端中 - 日期現在正確地表示爲當地時間,因爲2014-10-14T22:00:00.000Z之後的2小時再次成爲2014-10-15。

我的問題是:

在哪裏,我需要讓我的變化,以防止這種情況發生?

a)我只在前端使用本地時間,這樣mongodb纔會轉換爲UTC。這對我來說聽起來並不安全,因爲我確信當客戶端從不同的時區被呼叫時,這會造成問題。

b)我只使用UTC日期,但是我需要以某種方式告訴mongodb日期已經是UTC,因此不需要再次轉換它。

任何幫助將不勝感激。

感謝, 邁克爾

編輯

我想我可能是更進了一步了。我可以告訴json解串器什麼日期格式可以預期。我已經配置這對:

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ") 

如果我手動測試日期格式我最終

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); 
System.out.println(sdf.parse("2014-10-14T22:00:00+0200")); 

產生

Tue Oct 14 22:00:00 CEST 2014 

所以難怪mongodb的(或mongo- bson-driver)將日期再次轉換爲UTC。

如果我這樣做不過:

Wed Oct 15 00:00:00 CEST 2014 

當轉換從MongoDB的驅動程序完成的,它可能把它變成「2014-10:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); // Removed the "Z" 
sdf.setTimeZone(TimeZone.getTimeZone("UTC")); 
System.out.println(sdf.parse("2014-10-14T22:00:00+0200")); 

它正確地來了-14T22:00:00 + 0200「,這是正確的。

不知道這是最好的辦法,但...我會遇到的問題,如果客戶端的日期是在另一個時區?我想不是因爲如果它是「2014-10-15T06:00:00-0600」,例如,它可能會把它變成正確的日期......

任何人都可以確認這是要走的路?

謝謝!

+0

UTC日期是一個痛苦。一種選擇是將日期傳遞並存儲爲'2014-10-14'字符串,但除此之外,您必須非常小心,以便日期在每一步都表示該日期的UTC午夜。 – JohnnyHK 2014-10-22 13:22:12

+0

是的,我也考慮過這個問題,但是我擔心如果我現在不解決這個問題,它會在以後的另一個場景中困擾我。我認爲我發佈的編輯(出於某種原因,我註銷了,因此stackoverflow認爲社區進行了編輯)可能是解決轉換問題的解決方案......但不是100%確定。 – michaeldd 2014-10-22 13:45:05

回答

1

希望此信息可能會提供幫助。

MongoDB數據庫不進行轉換。它只是假定收到的日期是UTC時間。它是從日期對象獲取UTC時間(以毫秒爲單位)的java驅動程序。從蒙戈-java的駕駛員2.12.3.jar的BasicBSONEncoder.java以下代碼。

protected void putDate(String name , Date d){ 
    _put(DATE , name); 
    _buf.writeLong(d.getTime()); // d.getTime() Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT 
} 

如果您仍有疑問的,你可以在新的直接java代碼Date對象並將其保存到數據庫中,以檢查是否有進一步的轉換。 (比較時,請注意您的Java應用程序的時區)


現在,問題是:如果你得到2014-10-14T22:00:00 + 0200,則源應該是2014-10-15T00:00:00 + 0400,或2014-10-15T02:00:00 + 0600等這意味着不同的時區已經被調用之間的JavaScript日期選擇和JSON.stringify()使用。

當您向java應用程序發送字符串「2014-10-14T22:00:00 + 0200」並由SimpleDateFormat解析時,請確保該模式與數據一致(使用新的SimpleDateFormat(「yyyy-MM-dd 「T'HH:MM:SS ž「)不要忘記最後一個字符ž,否則+0200將被丟棄和字符串的其餘部分將被解析基於Java應用程序的時區的時區)

當您使用SimpleDateFormat來仔細檢查輸出時,最好創建另一個新的SimpleDateFormat(「yyyy-MM-dd'T'HH:mm:ssz」)來格式化日期對象,然後將其傳遞給System.out.print(),因爲它是ea sier按時區進行比較。

如果可能的話,我建議你發送UTC毫秒給java應用程序,因爲它很容易獲得並避免各種轉換格式問題。