2017-10-18 69 views
0

我正在使用終端在不同時區可訪問的Web門戶的時鐘輸入/輸出功能。Spring JDBC Persist ZonedDateTime

我正在使用ZonedDateTime來處理計算什麼日期時間應該是給定的衝入/出記錄。

// Get store timezone 
ZoneId storeTimeZone = this.storeService.getStoreZoneId(storeNum); 

// Get current store time to use for punch in/out timestamp 
ZonedDateTime currentStoreTime = ZonedDateTime.ofInstant(Instant.now(), storeTimeZone); 

當我將數據保存到Oracle 11g時,我無法保存ZonedDateTime對象。可能不受JDBC驅動程序支持。它的企業環境使數據庫和驅動程序不會改變。

當我構建MapSqlParamSource傳入NamedParameterJdbcTemplate時,我不得不將它轉換爲java.sql.Timestamp,但後來我失去了區域數據並存儲了服務器所在時區的時間戳,需求指示它必須在存儲時間內存儲在數據庫中,這只是一個Oracle TIMESTAMP列。

params.addValue("clockInTimestamp", Timestamp.from(prevRecord.getTimeEntryTimestamp().toInstant()), Types.TIMESTAMP); 

有沒有辦法來完成這種持續的ZonedDateTime?

+0

遺忘Spring,JDBC等的細節 - 聽起來像你試圖將「即時+時區」存儲在只能存儲瞬間的字段中......所以這不會比「I想要在4字節字段中存儲32個字節的數據「會。我建議你計算出你想存儲什麼信息,以什麼方式*然後*計算出如何實現它。 –

回答

1

Sprint Boot項目會自動加載jsr310jpaconverters,但這隻會處理LocalDateTime類型的轉換,而不是ZonedDateTime。如果你不使用Spring Boot,你可以自己加載這些額外的轉換器。

您可能希望調整您的應用程序,以便在數據庫交互級別使用這些應用程序,並將您保存的所有內容都強制置於一個標準時區,因此如果需要用戶顯示,您可以輕鬆轉換爲ZonedDateTime

0

我能夠通過將ZonedDateTime轉換爲Instant,然後使用時區偏移手動計算時間戳來解決此問題。

實施例以下代碼:

ZonedDateTime timeEntry = ZonedDateTime.now(); 

ZoneOffset storeOffset = timeEntry.getOffset(); 
ZoneOffset serverOffset = ZonedDateTime.now().getOffset(); 

int secondsOffset = storeOffset.getTotalSeconds() - serverOffset.getTotalSeconds(); 

Instant entryTimestamp = timeEntry.toInstant().plusSeconds(secondsOffset); 

Timestamp ts = Timestamp.from(entryTimestamp); 

然後我存留的java.sql.Timestamp到數據庫。

不是我確定的最乾淨或最好的解決方案,但是由於無法更改數據庫,驅動程序或其他方式工作的限制,它似乎表現良好。