场景:前端传来String格式的日期数据data,后端用实体类User接收(其中User实体类有一个时间格式参数Data data)
此时我们要解决各个阶段的格式转换配置:
1、前端到后端:String data ——转换为—— Data data
2、后端到数据库:
3、后端到前端:Data data ——转换为—— String Data
注意:如果不设置的话默认的时间是世界标准世界(0区),而我们中国地区是东8区,相差8个小时。
一、使用@DateTimeFormat+@JsonFormat
1、当使用@DateTimeFormat时
User类:(注意Data要导util包的,别导错包了)
@Data
public class User {
private int id;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
//@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
private Date data;
}
Controller
@RestController
public class BeanController {
@PostMapping("data")
public Map data(@RequestBody User user){
//1、 查看前端到后端处理了格式没有
System.out.println(user);
//2、查看后端到前端处理了格式没有
HashMap hashMap = new HashMap();
hashMap.put("id",user.getId());
hashMap.put("data",user.getData());
return hashMap;
}
}
启动类
@SpringBootApplication
public class DemoApp {
public static void main(String[] args) {
SpringApplication.run(DemoApp.class,args);
}
}
发送请求:
结果:
这是因为@DateTimeFormat只能处理后端到前端阶段(出参),而我们前端到后端的阶段并没有进行处理。所以我们需要加上入参(前端到后端的处理过程)
当然,如果你只需要前端到后端的部分则可以只用@JsonFormat这个注解即可
2、加上@JsonFormat注解
将User实体类改为:
@Data
public class User {
private int id;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
private Date data;
}
此时重新访问,此时返回处理过的String类型的日期
注意:2020-01-01T03:11:11.000+0000 :以+0000结尾,此时需要加上8个小时(中国时区(东8区)和标准世界时间(0区)的相差8小时)
如果是2020-01-01T03:11:11.000+0800:以+0800结尾,此时表示已经是中国时区(东8区了),则不用再做换算。
此时后端控制台,打印了前端的String转化为Data后的日期值
shuo
此时前后端的日期格式则都设置完成了
这里网上的人可以直接得到一个这样格式的值
,而我自己做出来的确是
。说实在的不知道是网上的人抄来抄去,还是我自己写错了。这个等我之后再验证
2、使用配置文件进行配置(全局配置)
此时不用@DateTimeFormat+@JsonFormat注解,直接在yml中加上下面配置:
#时间戳统一转换
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
结果:
此时前端传来的和后端传到前端的都是处理好的了,连前端的+8小时的都不用处理了。
3、自定义格式转换器
自定义全局日期转换器可以参考
4、当加入数据库这个环节
4.1、概述
为什么要加入数据库这个环节?
因为数据库的data类型数据也会存在时区的问题。
例如:
jdbc:mysql://localhost:3306/food?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai(东8区,中国的时区)
和
jdbc:mysql://localhost:3306/food?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC (0区,世界标准时区)
由于时区问题,查出来的数据是相差8个小时的。后者在数据库拿到数据后会在小时上+8个小时。对于UTC、CST、GTM的概念可以网上百度。
而如果我们设置为Asia/Shanghai中国时区,则插入数据库时不会减掉8个小时,从数据库拿时不会加上8小时。
因为UTC是世界标准时间,而中国时区和标准时间相差8小时,所以这里设置数据库时区在插入查询时会根据不同的时区进行加减8小时(数据库是UTC,而我们项目设置了是GTM+8即中国时区设置为东八区)
所以在和数据库进行日期交互的时候要注意时区问题。
而对于数据库的日期类型:
Mysql中经常用来存储日期的数据类型有三种:Date、Datetime、Timestamp。
【1】Date数据类型:用来存储没有时间的日期。Mysql获取和显示这个类型的格式为“YYYY-MM-DD”。支持的时间范围为“1000-00-00”到“9999-12-31”。
【2】Datetime类型:存储既有日期又有时间的数据。存储和显示的格式为 “YYYY-MM-DD HH:MM:SS”。支持的时间范围是“1000-00-00 00:00:00”到“9999-12-31 23:59:59”。
【3】Timestamp类型:也是存储既有日期又有时间的数据。存储和显示的格式跟Datetime一样。支持的时间范围是“1970-01-01 00:00:01”到“2038-01-19 03:14:07”。1、数据库中,如果使用datatime类型的日期,这是这个日期是不存储时区信息的,如果需要可以加上时区的字段。
2、data则精度只到年月日没有时分秒
3、Timestamp:和datatime类似,就是范围不同。
4.2、加入数据库后(这里使用配置文件进行配置时间类型的转换)
数据库,建立一个user数据库,字段为id——int ;data——datatime
yml
server:
port: 10083
#时间戳统一转换
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8 #设置为东八区
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
password: 123456
url: jdbc:mysql://localhost:3306/food?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
username: root
mybatis:
mapper-locations: classpath:mappers/*.xml
pojo:
@Data
public class User {
private int id;
private Date data;
}
dao:
@Mapper
public interface UserMapper {
User Sel(int id);
int ins(User user);
}
xml:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spring.dao.UserMapper">
<select id="Sel" resultType="com.spring.pojo.User">
select * from user where id = #{id}
</select>
<insert id="ins" parameterType="com.spring.pojo.User">
INSERT INTO user (id,data) VALUES (#{id},#{data})
</insert>
</mapper>
controller:这里就不写service层了
@RestController
public class BeanController {
@Autowired
UserMapper userMapper;
@GetMapping("abc")
public User usersel(){
User sel = userMapper.Sel(1);
return sel;
}
@PostMapping("data")
public Map data(@RequestBody User user){
userMapper.ins(user);
System.out.println(user);
HashMap hashMap = new HashMap<String,Object>();
hashMap.put("id",user.getId());
hashMap.put("data",user.getData());
return hashMap;
}
}
启动类:
@MapperScan("com.spring.dao") //扫描的mapper
@SpringBootApplication
public class DemoApp {
public static void main(String[] args) {
SpringApplication.run(DemoApp.class,args);
}
}
启动调用
此时插入正常。
此时查询也正常
该案例需要注意的是数据库时区的选择。