在我的一個Web應用程序中,我必須安排一個事件。 我的服務器,客戶端和數據庫位於不同的時區。 客戶端將安排一個事件,服務器必須執行該事件。保存和檢索從客戶端到數據庫的時間
我該怎麼做?
從客戶目前,我發送事件的時間以毫秒爲單位自紀元:(帶的getTime()在javascript日期的方法)
在服務器我將其轉換爲使用Java日期對象,並存儲這作爲數據庫中的日期類型值。
在數據庫中,存儲的值比我給客戶端的日期晚了一天。 這是爲什麼?我如何將它存儲在服務器時間?
在我的一個Web應用程序中,我必須安排一個事件。 我的服務器,客戶端和數據庫位於不同的時區。 客戶端將安排一個事件,服務器必須執行該事件。保存和檢索從客戶端到數據庫的時間
我該怎麼做?
從客戶目前,我發送事件的時間以毫秒爲單位自紀元:(帶的getTime()在javascript日期的方法)
在服務器我將其轉換爲使用Java日期對象,並存儲這作爲數據庫中的日期類型值。
在數據庫中,存儲的值比我給客戶端的日期晚了一天。 這是爲什麼?我如何將它存儲在服務器時間?
您的問題與其他許多問題相同。所以我會簡短。
有兩種方法來代表三個品種的現代化棗,時間值:
Instant
類。在SQL中使用TIMESTAMP WITH TIME ZONE
。LocalDateTime
類。在SQL中,使用TIMESTAMP WITHOUT TIME ZONE
。爲了提供時間表,使用ZonedDateTime
類,通過Instant::atZone
方法,使用Java生成瞬態數據。LocalDateTime
類。在SQL中,使用TIMESTAMP WITHOUT TIME ZONE
。作爲一個程序員和系統管理員,學會思考在UTC和24小時的時間。在工作中忘記你自己的教區時區。在辦公室保持第二個時鐘設置爲UTC。
您如何知道用戶的預期/所需時區?最終唯一確定的方法是問她/他。
當序列化爲文本時,請使用標準ISO 8601格式。
避免可怕的舊日期時間類,如java.util.Date
和java.sql.Date
等,這些現在已經成爲傳統,被業界領先的優秀java.time類所取代。
Instant instant = Instant.ofEpochMilli(millis) ;
,以呈現給用戶,調整UTC到他們期望/希望的時區。想象一下,就像internationalization一樣,在那裏存儲對某個鍵的引用,然後爲了演示,使用檢索到的鍵來查找本地化的文本值。
切勿使用3-4個字符的僞時區。 True time zones有一個continent/region
名稱,如Asia/Kolkata
和Pacific/Auckland
。
ZoneId z = ZoneId.of("America/Montreal") ;
ZonedDateTime zdt = instant.atZone(z) ;
注意,數據庫在他們處理的日期,時間變化廣泛。 SQL標準幾乎沒有涉及到這個問題。研究文檔並進行實驗以確保您瞭解其行爲。同上您的JDBC驅動程序。提示:對date-time types和functions有一些最好的支持。
隨着JDBC 4.2和後,用經由java.time對象數據庫交換數據,通過調用:
PreparedStatement::setObject
ResultSet::getObject
實施例代碼
myPStmt.setObject.(… , myInstant) ;
...和...
Instant instant = myResultSet.getObject(… , Instant.class) ;
對不起,但沒有。 *調度*,UTC不一定是最好的方法。從那裏查看最佳做法和相關答案。 –
@MattJohnson真的。我修改了我的答案,增加了一對子彈來處理每個案例。 –
更好。謝謝! :)另請參閱:https://twitter.com/mj1856/status/903682303833944064 –
當你存儲時間時,你最好的選擇是將它存儲到任何時間的任何地方(或者如果你喜歡unix時間的話),然後在前端反序列化它。這意味着你可以放心,你堅持了正確的時間,然後你可以在前端進行轉換。在不知道具體情況的情況下,我懷疑你在Java中創建的日期對象是導致分流,然後將錯誤的日期值存儲在數據庫中。
對不起,但沒有。對於調度*,unix時間不一定是最好的方法。從那裏查看最佳做法和相關答案。 –
由於您的問題是關於調度*,請參閱鏈接的最佳做法中的第6項。 (UTC不一定是調度的最佳方法) –