我知道這對圖像很冒昧,在數千個開發人員每天使用的庫中發現了一個錯誤。所以我認爲我的標題問題的答案是「NO !!!」,但是...這是jackson-datatype-jsr310解串器中的錯誤嗎?
我有一個對象,包含從我的前端(JS)收到的日期,並將其存儲到MongoDB中數據庫。我使用Spring來獲取此對象(使用REST控制器),並使用Spring來執行持久性(使用MongoDBRepository)。我的電腦配置了CEST時鐘,所以GMT + 2(UTC +0200)。
我POJO中的日期存儲在LocalDateTime中。
這是我的目標:
class Test{
LocalDateTime when;
String data;
// getter setters...
}
下面的單元測試表明,春季(其中使用傑克遜 - jsr310)填補我的LocalDateTime與UTC日期時間。
mockMvc.perform(post("/test")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content("{\"when\":\"2017-03-31T14:20:28.000Z\",\"data\":\"toto\"}")).andExpect(status().isOk());
List<com.robopec.models.Test> tests = testRepository.findAll();
Assert.assertEquals(14, tests.get(0).getWhen().getHour());
我們可以在傑克遜源代碼LocalDateTimeDeserializer.java 74行看到:
return LocalDateTime.ofInstant(Instant.parse(string), ZoneOffset.UTC);
但是當我保存在我的數據庫,彈簧使用彈簧數據公地到存儲在我的LocalDateTime轉換爲日期數據庫中的日期。 我們可以在這個spring-data-commons/../Jsr310Converters.java閱讀:
public static enum LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
INSTANCE;
@Override
public Date convert(LocalDateTime source) {
return source == null ? null : Date.from(source.atZone(systemDefault()).toInstant());
}
}
所以,彈簧數據JSR310轉換器解釋一個localdatetime作爲默認的系統區域瞬間。
問題是,當我的前端發送「2017-04-03T20:00:00Z」時,REST控制器將其存儲在LocalDateTime中,時間爲:20:00:00。當mongo數據轉換器將其轉換爲日期時,結果時間爲20:00:00 + 0200(因爲我的電腦處於CEST時區)。
我的結論是我不應該將我的日期存儲在LocalDateTime中,而是存儲在Date(java.util)或Instant中。
但是,是否有一個轉換器中的錯誤?
您是否使用POJO樣本建議的LocalDateTime或LocalDate?你使用的是哪個數據庫? Spring Data的哪個版本? –
你說得對,我正在使用LocalDateTime(我將編輯我的文章)。數據庫是一個MongoDB數據庫。我使用spring-boot-starter-data-mongodb版本1.5.1和jackson-datatype-jsr310:2.8.6 –