解决LocalDateTime 时间格式中间带’T’返回的问题(小心踩坑) 您所在的位置:网站首页 mysql获取昨天的日期转换为特定格式 解决LocalDateTime 时间格式中间带’T’返回的问题(小心踩坑)

解决LocalDateTime 时间格式中间带’T’返回的问题(小心踩坑)

2024-07-09 02:24| 来源: 网络整理| 查看: 265

解决LocalDateTime 时间格式中间带’T’返回的问题

前言:在一次工作开发过程中,LocalDateTime 类型的字段返回给前端带着T,然后被测试无情的提了一个bug,然后只能使用百度大法了,结果发现网上全是一堆相同的答案,且是无效无用的,只能自己实践整理一版有效的使用出来。

PS:要看自己的项目是数据序列化是不是用fastJson序列化(很重要,因为这个导致很多正常有效的都变无效了,我就是踩这个坑)

首先我们先了解Date和LocalDateTime 的源码返回格式

下面是Date的toString方法的源码,里面返回的字符格式就是日常使用的

public String toString() { // "EEE MMM dd HH:mm:ss zzz yyyy"; BaseCalendar.Date date = normalize(); StringBuilder sb = new StringBuilder(28); int index = date.getDayOfWeek(); if (index == BaseCalendar.SUNDAY) { index = 8; } convertToAbbr(sb, wtb[index]).append(' '); // EEE convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss TimeZone zi = date.getZone(); if (zi != null) { sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz } else { sb.append("GMT"); } sb.append(' ').append(date.getYear()); // yyyy return sb.toString(); }

LocalDateTime的toString方法的源码,会把T放在年月日和时分秒的中间,所以会出现带’T’的字符串

@Override public String toString() { return date.toString() + 'T' + time.toString(); }

所以如果,后端想返回给前端不带’T’的时间格式,想省事就直接把LocalDateTime类型改为Date类型,然后在字段上加上注解即可

@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”,timezone=“GMT+8”)

但是,这不是我们想要的,如果我们就是想用LocalDateTime类型字段返回给前端,那应该怎么办呢。

一、使用字符串替(不推荐,很low)

前面我们可以知道,LocalDateTime源码是会自动把T加上去的,所以我们要做的比较简单,就是把T替换成空格即可

二、使用注解(处理局部实体对象返回) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8") 三、使用全局配置统一处理(对日期数据序列化和反序列化处理) 方式一: import cn.hutool.core.date.DatePattern; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; @Configuration public class LocalDateTimeConfig { @Bean @Primary public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){ //日期转字符串 return builder -> builder.serializerByType(LocalDate.class,new LocalDateTimeSerializer(DatePattern.NORM_DATE_FORMATTER)) .serializerByType(LocalDateTime.class,new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMATTER)) .serializerByType(LocalTime.class,new LocalDateTimeSerializer(DatePattern.NORM_TIME_FORMATTER)) //字符串转日期 .deserializerByType(LocalDateTime.class,new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMATTER)) .deserializerByType(LocalDate.class,new LocalDateDeserializer(DatePattern.NORM_DATE_FORMATTER)) .deserializerByType(LocalTime.class,new LocalTimeDeserializer(DatePattern.NORM_TIME_FORMATTER)); } }

方式二:

import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @Configuration public class LocalDateTimeConfig { @Bean public LocalDateTimeSerializer localDateTimeSerializer(){ return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){ return e -> e.serializerByType(LocalDateTime.class,localDateTimeSerializer()); } } 四、总结(很重要,踩坑)

在我们实际生产项目中,后端返回给前端的数据都是做统一的格式化处理,例如用到fastjson进行格式化,此时有可能会导致上面的一些方式失效,例如下面就是用JSON.toJSONString将localDateTime日期转换,

public static String toString(Object data) { return JSON.toJSONString(data, features); } /** * 可以看到fastJson.toJSONString的序列化LocalDateTime的格式是带T的 */ public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { ... if (fieldType == LocalDateTime.class) { int mask = SerializerFeature.UseISO8601DateFormat.getMask(); LocalDateTime dateTime = (LocalDateTime)object; String format = serializer.getDateFormatPattern(); if (format == null) { if ((features & mask) == 0 && !serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) { int nano = dateTime.getNano(); if (nano == 0) { format = "yyyy-MM-dd'T'HH:mm:ss"; } else if (nano % 1000000 == 0) { format = "yyyy-MM-dd'T'HH:mm:ss.SSS"; } else { format = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS"; } } else { format = "yyyy-MM-dd'T'HH:mm:ss"; } } .... } }

如果如果上面的方法不生效的话,可以用下面的方法尝试下

使用@JSONField代替@JsonFormat

@JSONField(format = "yyyy-MM-dd HH:mm:ss")


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有