数据库datetime类型的数据查询出来相差8小时
背景说明
一个JAVA项目,从MYSQL数据库中查询数据时,发现数据库表中显示的Date类型字段的数据,与查询出来的数据相差8小时
排查过程
- 查看执行的SQL日志:SQL日志中显示,查询出来的数据与数据库一致
- 查看接口返回的数据:发现返回的数据与数据库中相差8小时
修复过程
- 【无效】给数据库连接添加了:serverTimezone=Asia/Shanghai
- 【无效】在项目的启动类main方法,添加如下的代码:TimeZone.setDefault(TimeZone.getTimeZone(“GMT+8”));
- 【无效】将Date类型的引入的包从:import java.util.Date; 改成 import java.sql.Date;
- 【有效】在对应实体类的Date类型的字段添加注解:@JsonFormat(pattern = “yyyy-MM-dd HH:mm:ss”, timezone = “GMT+8”)
- 【有效】使用全局配置:
1
2spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8 - 【有效】配置全局的Jackson ObjectMapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class JacksonConfig {
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
// 设置日期格式_
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 设置时区_
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
// 注册JavaTimeModule以支持Java 8日期和时间API_
objectMapper.registerModule(new JavaTimeModule());
// 禁用时间戳_
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return objectMapper;
}
}
分析原因
java默认使用UTC时间,而大多数数据库(如MySQL)在中国地区通常设置为东八区(GMT+8)。因此,当Java从数据库中读取时间时,如果没有正确设置时区,就会出现时间差异。
因此在spring项目中,Jackson在处理日期和时间时,需要指定对应的时区
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 牛蛙JUN!