Spring @JsonFormat序列化日期时少一天问题求助
Hey there, let's dig into why your date is showing up one day earlier in the API response than what's stored in the database. The issue almost always boils down to timezone mismatches between how JPA reads the date and how Jackson serializes it. Here's what's happening and how to fix it:
What's Causing the Shift?
Your entity uses Date (a timezone-aware type) with @Temporal(TemporalType.DATE) and Jackson's @JsonFormat set to Brazil/East. Here's the core problem:
- When JPA reads the
DATEvalue from the database (which stores just a date, no time), it converts it into aDateobject using your application server's default timezone—not necessarilyBrazil/East. - If the server timezone is UTC, for example, the database's
11-06-2018becomes2018-06-11T00:00:00Z(UTC midnight). When Jackson formats this withBrazil/East(UTC-3), it translates to2018-06-10T21:00:00-03:00—so the date part ends up as10-06-2018.
Fixes to Try
1. Switch to LocalDate (Recommended)
The Date class is outdated and prone to timezone bugs. Java 8+ introduced LocalDate, which is designed specifically for dates without time or timezones—perfect for matching your database's DATE type.
Update your entity field like this:
@Column(name = "date") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy", locale = "pt-BR") private LocalDate date;
No need for @Temporal or timezone in @JsonFormat here, since LocalDate doesn't care about timezones. This eliminates any conversion-related shifts entirely.
2. Align JPA and Jackson Timezones
If you need to stick with Date, make sure JPA uses the same timezone as Jackson when reading the date from the database.
For Spring Boot + Hibernate, add this to your application.properties:
spring.jpa.properties.hibernate.jdbc.time_zone=Brazil/East
This tells Hibernate to parse the database's DATE value using Brazil/East timezone, so the Date object Jackson receives will already be aligned with your desired output.
3. Verify Database Timezone
Double-check your database's timezone configuration. If the database is using a different timezone than your application, it could introduce subtle shifts. Ensure the database's timezone matches either Brazil/East or the timezone you've configured for JPA/Jackson.
Final Notes
Using LocalDate is the cleanest solution because it removes timezone ambiguity entirely. The old Date class was never meant to represent just a date—it's a timestamp under the hood, which is why these timezone issues pop up.
内容的提问来源于stack exchange,提问作者faserx

