Java 17+Jackson中SimpleDateFormat日期格式不符的解决咨询
问题分析与解决方案
问题根源
你代码里的两个关键错误导致日期格式不符合预期:
- ObjectMapper的DateFormat设置完全没生效:你是手动调用
sdf.format()把日期转成字符串后再赋值给timeStamp字段,ObjectMapper序列化String类型字段时不会再做任何日期格式化处理,所以你给ObjectMapper设置的规则等于白写。 - 你使用的
sdf实例格式错误:出现Oct月份缩写,说明这个sdf用的是包含MMM(月份缩写)的格式串,而非你需要的MM(两位数字月份)。
解决方案
根据ErrorMessage的timeStamp字段类型,分两种处理方式:
方式一:timeStamp字段为Date/Instant类型(推荐)
不要手动格式化日期,直接将日期对象传给字段,让ObjectMapper按你配置的规则完成序列化:
ObjectMapper objectMapper = new ObjectMapper(); // 配置你需要的目标格式 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", new Locale("en", "NZ"))); String jsonMessage = objectMapper.writeValueAsString( ErrorMessage.builder() .message(mostSpecificCauseMessage) .timeStamp(new Date(System.currentTimeMillis())) // 直接传递Date对象 .build() );
方式二:timeStamp字段必须为String类型
直接使用正确格式的SimpleDateFormat实例来格式化日期,无需依赖ObjectMapper的日期配置:
// 创建格式正确的SimpleDateFormat实例 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", new Locale("en", "NZ")); String jsonMessage = objectMapper.writeValueAsString( ErrorMessage.builder() .message(mostSpecificCauseMessage) .timeStamp(sdf.format(System.currentTimeMillis())) .build() );
额外推荐:Java 17 更优的日期处理方案
SimpleDateFormat存在线程不安全问题,Java 17推荐使用java.time包下的新日期API,搭配Jackson的jackson-datatype-jsr310模块处理序列化,示例如下:
// 先确保引入jackson-datatype-jsr310依赖 ObjectMapper objectMapper = new ObjectMapper(); JavaTimeModule timeModule = new JavaTimeModule(); // 配置自定义日期格式 timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); objectMapper.registerModule(timeModule); String jsonMessage = objectMapper.writeValueAsString( ErrorMessage.builder() .message(mostSpecificCauseMessage) .timeStamp(LocalDateTime.now(ZoneId.of("Pacific/Auckland"))) // 指定新西兰时区 .build() );
内容的提问来源于stack exchange,提问作者Ray Bond
相关产品推荐
相关产品推荐

