Java EE JSONB序列化Date对象时日期自动减一天问题求助
解决JSONB序列化Date时日期偏移一天的问题
这个问题的核心根源是时区不匹配:Date本质是UTC时间戳,你用SimpleDateFormat解析日期时默认使用了本地时区,而JSONB序列化时又默认转换为UTC时区,一进一出的时区差就导致了日期显示偏移一天。
问题拆解
当你执行new SimpleDateFormat("yyyy-MM-dd").parse("2021-03-19")时,它会把字符串解析成你本地时区的2021-03-19 00:00:00。比如你在东八区(UTC+8),这个时间对应的UTC时间是2021-03-18 16:00:00。JSONB序列化Date时默认用UTC时区格式化,最终就输出了2021-03-18。
另外你后来添加时间的代码出现2020-12-19的错误,是因为格式字符串写错了:HH:MM:SS里的MM代表月份,不是分钟,SS是毫秒,不是秒,正确格式应该是yyyy-MM-dd HH:mm:ss。
解决方案
方案1:统一解析与序列化的时区
给SimpleDateFormat和JSONB都指定同一个时区(比如UTC,或者业务需要的特定时区),消除时区转换带来的偏移。
修改后代码:
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.TimeZone; import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; import javax.json.bind.JsonbConfig; import javax.json.bind.annotation.JsonbDateFormat; public class MyDate { @JsonbDateFormat(value = "yyyy-MM-dd", locale = "en_US") private Date myDate; // Getter & Setter public Date getMyDate() { return myDate; } public void setMyDate(Date myDate) { this.myDate = myDate; } public static void main(String[] args) throws ParseException { // 解析时指定UTC时区 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US); sdf.setTimeZone(TimeZone.getTimeZone("UTC")); Date parsedDate = sdf.parse("2021-03-19"); MyDate myDateObj = new MyDate(); myDateObj.setMyDate(parsedDate); // JSONB序列化时也指定UTC时区 JsonbConfig config = new JsonbConfig() .setProperty("jsonb.timezone", "UTC"); Jsonb jsonb = JsonbBuilder.create(config); System.out.println(jsonb.toJson(myDateObj)); } }
运行结果:{"myDate":"2021-03-19"}
方案2:使用Java 8+的LocalDate(推荐)
如果你只需要存储日期(不需要时间和时区信息),Java 8引入的java.time.LocalDate是更合适的选择——它是无时区的纯日期类型,从根源上避免了时区转换问题,也更符合你想要的"强类型"需求。
修改后代码:
import java.time.LocalDate; import javax.json.bind.JsonbBuilder; import javax.json.bind.annotation.JsonbDateFormat; public class MyDate { @JsonbDateFormat("yyyy-MM-dd") private LocalDate myDate; // Getter & Setter public LocalDate getMyDate() { return myDate; } public void setMyDate(LocalDate myDate) { this.myDate = myDate; } public static void main(String[] args) { MyDate myDateObj = new MyDate(); myDateObj.setMyDate(LocalDate.parse("2021-03-19")); System.out.println(JsonbBuilder.create().toJson(myDateObj)); } }
运行结果直接是:{"myDate":"2021-03-19"}
内容的提问来源于stack exchange,提问作者Nicolas Baumann
相关产品推荐
相关产品推荐

