2016-12-20 60 views
-1

我需要爲用戶傳遞的數據在數據庫中搜索結果創建一個24小時的窗口。用戶可以在任何TimeZone中,服務器在PST中,數據庫使用mongodb(UTC)。將字符串日期轉換爲帶有客戶端時區的Java對象(不帶語言環境)

尋找的東西一樣,如果用戶發送Wed Dec 21 2016 00:07:11 GMT+0530 (IST)然後服務器創建一個new DateTime()具有相同的日期和時間(不被默認轉換爲JVM的時區)

一個工作,我周圍想到的是創建在用戶的時區一個日期withTimeAtStartOfDay和addDays加1表示窗口。

例如:String date = "Wed Dec 21 2016 00:07:11 GMT+0530 (IST)" convert to "2016-12-21 00:00:00.000Z"注意:服務器在PST中,所以簡單的日期對象將不起作用。

如何使用用戶的時區(例如字符串日期用戶傳遞給BE)在Java中創建Date對象。

+0

可能的複製(http://stackoverflow.com/q/1091372/5221149) – Andreas

+1

你的問題還不清楚。 「Date」對象不帶時區,服務器的時區與手頭的問題無關。您不會說您想要如何獲取用戶的時區,包含時區的字符串是什麼樣子,或者您正在使用哪種應用程序。這聽起來像你可能需要'java.time' API中的'ZonedDateTime',但很難從你提出的問題中說出。 https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html –

+0

@Andreas - Java對於JavaScript來說就像Car是Carpet一樣。 OP沒有詢問JavaScript。 –

回答

1

服務器的JVM當前的默認時區與您的編程無關。始終將可選參數中所需/預期的時區傳遞給各種方法調用。恕我直言,這些時區參數應該是必需的,而不是可選的。

我不知道或使用MongoDB的,但this page說你本機類型的日期時間值是一個64-bit整數,它表示的milliseconds自Unix紀元(1970年1月1日)在UTC號。

只有日期的值是不明確的,沒有時區的上下文沒有真正的意義。對於任何特定的時刻,日期因地區而異。午夜過後的幾分鐘是法國巴黎的新的一天,而在加拿大蒙特利爾仍然是「昨天」。

所以如果需要時區,我們從哪裏得到一個?最終,唯一安全可靠的方法是詢問用戶。以continent/region的格式提示用戶輸入proper time zone name,例如America/Montreal,Africa/CasablancaPacific/Auckland。切勿使用3-4字母縮寫,如ESTIST,因爲它們是而不是真正的時區,不是標準化的,甚至不是唯一的(!)。

在不詢問用戶的情況下,您只能假設或猜測。有許多方法可以通過JavaScript檢測Web應用程序客戶端瀏覽器的當前默認時區。 Stack Overflow已經多次討論過了,所以搜索一下。但是,您不確定瀏覽器區域是否由用戶向您進行查詢。如果您的用戶經過適當的培訓以便以這種方式工作,您可以假設一個時區或採用UTC。

區域設置有什麼都沒有與時區有關,只有在生成字符串表示時才顯示。 Locale確定(a)用於翻譯日期名稱,月份名稱等的人類語言,以及(b)用於確定縮寫,大寫,標點符號等問題的文化準則。您可以通過Locale.CANADA_FRENCH演示文稿獲得Asia/Kolkata時區,或者使用Locale.ITALY演示文稿獲取Pacific/Auckland時區。所以,語言環境與這個問題無關。

使用LocalDate作爲日期部分。

LocalDate ld = LocalDate.of(2016 , Month.MARCH , 23); 

提供時區。

ZoneId z = ZoneId.of("America/Montreal"); 

獲取一天的開始,第一時刻。讓java.time確定這一點,因爲第一時刻是而不是始終是時間00:00:00。夏令時(DST)等異常情況可能會導致不同的開始時間。

ZonedDateTime zdtStart = ld.atStartOfDay(z); 

我們需要搜索查詢的結束時間。通常在日期時間處理中,我們使用半開式方法,其中開始爲,包括,而結束爲,獨佔。所以我們希望一天的查詢運行到之後的第一個時刻,但不包括之後的第一個時刻。

ZonedDateTime zdtStop = ld.plusDays(1).atStartOfDay(z); // Or, zdtStart.plusDays(1) 

顯然,MondoDB需要我們將此轉換爲自UTC時代以來的毫秒數。爲此,請提取Instant

Instant instantStart = zdtStart.toInstant(); 
Instant instantStop = zdtStop.toInstant(); 

從那些中提取出epoch-count。這可能意味着數據丟失! java.time類跟蹤值的分辨率爲nanoseconds。達到毫秒可能意味着截斷一秒的精細部分。 [獲取客戶端的時區在JavaScript]的

long millisStart = instantStart.toEpochMilli(); // WARNING: possible data loss. 
long millisStop = instantStop.toEpochMilli(); // WARNING: possible data loss. 
+0

尋找類似於用戶發送「Wed Dec 21 2016 00:07:11 GMT + 0530(IST)」之類的東西,則服務器將創建一個具有相同日期和時間的新DateTime()(默認JVM時區不會轉換)。 – nishi

+0

@ nishi發佈進一步的信息,如編輯你的問題,而不是評論。 –

相關問題