英文:
Spring Boot Wrong date returned
问题
我有一个实体类Person
```java
@Entity
@Data
public class Person {
@Temporal(TemporalType.DATE)
private Calendar dob;
}
还有一些DAO类
@Data
public class PersonResponse {
@JsonFormat(pattern = "yyyy-MM-dd")
private Calendar dob;
}
@Data
public class PersonRequest {
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Calendar dob;
}
在存储数值时,它可以完美工作。例如,如果我发送"2000-01-01",它会按原样存储在数据库中,即"2000-01-01"。但是当我尝试返回它时,我得到的是"1999-12-31"。
现在很明显这是一个时区问题,但我不知道该如何修复它。
我对原因的解释
用户的时区是GMT+1,所以它以某种方式被检索为"2000-01-01T00:00:00.000 +01:00",然后被解析为UTC"1999-12-31T23:00:00.000 +00:00",最后返回为"1999-12-31"。
但是为什么?我该如何防止这种情况发生,考虑到用户的时区可能会更改(因此手动添加1小时的时间偏移量不起作用)。
我还尝试将类型从Calendar更改为java.util.Date和java.sql.Date...但没有结果。
类似的问题以前也被提出过,比如这个问题,但我仍然无法理解如何解决它。
<details>
<summary>英文:</summary>
I have an entity Person
@Entity
@Data
public class Person {
@Temporal(TemporalType.DATE)
private Calendar dob;
}
And some dao classes
@Data
public class PersonResponse {
@JsonFormat(pattern = "yyyy-MM-dd")
private Calendar dob;
}
@Data
public class PersonRequest{
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Calendar dob;
}
When storing values it works perfectly. Example if I send "2000-01-01" it's stored as is in the database "2000-01-01". But When I try to return it I get "1999-12-31".
Now it's clear that is a ***Timezone Problem*** but I don't know how to fix it.
##### My explanation for the cause
The user timezone is GMT+1 so it is some how retrieved as "2000-01-01T00:00:00.000 +01:00", then parsed to UTC "1999-12-31T23:00:00.000 +00:00" to finally be returned as "1999-12-31".
But why? And how can I prevent this knowing that users timezones can change (so adding the time offset manually of 1 hour won't work).
I tried also changing type from Calendar to java.util.Date and java.sql.Date... but no result.
Similar questions where asked before like [this one](https://stackoverflow.com/questions/50829014/spring-bootreturn-wrong-value-date-in-json-response) but I still couldn't understand how to fix it
</details>
# 答案1
**得分**: 2
如果适用的话,尝试从类 `Calendar` 切换到 `LocalDate`。`LocalDate` 不考虑时区。这应该解决您的问题(并简化您的代码)。此外,要将 `LocalDate` 格式化为 Json,请参考此问题的答案:[Spring Data JPA - ZonedDateTime format for json serialization][1]。
<details>
<summary>英文:</summary>
If Applicable try to switch from class `Calendar` to `LocalDate`. `LocalDate` does not take time zone into consideration. This should resolve your issue (and simplify your code). Also, for formatting the `LocalDate` with Json see the answer to this question: [Spring Data JPA - ZonedDateTime format for json serialization][1]
[1]: https://stackoverflow.com/questions/31627992/spring-data-jpa-zoneddatetime-format-for-json-serialization
</details>
# 答案2
**得分**: 1
问题您面临的确与时区有关。将dob值存储在数据库中时,它以提供的确切日期和时间存储。但是,当您检索它时,会进行时区转换,导致日期看起来不同。
尝试使用 `TimeZone.setDefault(TimeZone.getTimeZone("UTC"));`
并设置 spring.datasource.url 为:jdbc:mysql://127.0.0.1:3306/database?serverTimezone=UTC
<details>
<summary>英文:</summary>
The issue you're facing is indeed related to time zones. When you store the dob value in the database, it's stored as the exact date and time provided. However, when you retrieve it, the time zone conversion takes place, causing the date to appear different.
Try use `TimeZone.setDefault(TimeZone.getTimeZone("UTC"));`
and set spring.datasource.url: jdbc:mysql://127.0.0.1:3306/database?**serverTimezone=UTC**
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论