SpringBoot时区问题

文章讲述了在开发项目中遇到的时间差问题,主要涉及服务器时间设置、数据库(如MySQL)时区配置以及SpringBoot应用中的时区处理。建议在SpringBoot中设置全局时区,并推荐使用LocalDateTime避免时区转换问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.后端服务不同的时区

提供各个维度查看或设置时区的方法,详细修改方法不做缀诉
在我们进行一个项目的的时候经常会发现、从前端上传的时间存入数据库时、或者从数据库查询的时间的时候总是会出现时间多了8个小时或者少了8八个小时的问题。要解决这一问题、首先我们要明白一个后端项目究竟有哪些时区:

服务器时间

项目总是会部署在一个服务器上的,例如阿里云、百度云、或者是自购的私有主机、首先我们要设置好服务的时间。可以通过下面命令查询服务器时区
#查询服务器时区

data -r

数据库时间

在此以MySQL为例,当你使用MySQL作为数据持久化工具时,数据库的时区也需要注意:
在连接数据库时注意加上时区:

192.168.*.*:3306/......&serverTimezone=Asia/Shanghai

通过SQL命令可以查看时区

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

SpringBoot时区

整个项目的时区、你可以在启动文件加上

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

可在properties里面加

spring.jackson.time-zone=GMT+8

也可以在你需要转换的时间类类型参数里面加:

@ApiModelProperty(value = "创建时间", hidden = true)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Null(message = "创建时间必须为空", timezone = "GMT+8")
private DateTime createTime;

说到这里:建议使用LocalDate,因为常见的是Date,这里需要转换时区,所以用Date举例。
当你想用Date的时候使用、LocalDate、想用DatetTime的时候用LocalDateTime
这里简要说一下:LocalDateTime是不需要去转换时区的。Date需要转换、原因就是使用的默认Jackson序列化导致的问题、LocalDateTime没有问题。Java8以后建议使用LocalDateTime,具体用法、好处、自己去发现。

//具体就这么多、有什么错误希望大佬能指正、共同进步,感谢!

### 处理Spring Boot Controller中的时区问题 在构建Web应用程序时,正确处理时间与时区非常重要。对于基于Spring Boot的应用程序,在`Controller`层处理时区可以通过多种方式实现。 #### 使用HTTP头设置默认时区 一种简单的方法是在请求到达控制器之前通过过滤器来修改线程上下文的时间区域属性。这通常涉及到读取来自客户端的特定头部信息(比如`TimeZone`),并将其应用于当前线程: ```java import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.util.TimeZone; @Component public class TimeZoneFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String timeZoneId = httpRequest.getHeader("X-Time-Zone"); if (timeZoneId != null && !timeZoneId.isEmpty()) { TimeZone.setDefault(TimeZone.getTimeZone(timeZoneId)); } try { chain.doFilter(request, response); } finally { // Reset the default time zone after processing. TimeZone.setDefault(null); } } } ``` 这种方法允许开发者根据传入请求动态调整服务器端操作所使用的时区[^1]。 #### 利用@DateTimeFormat注解指定日期格式及时区 当接收带有日期字段的对象作为参数时,可以利用`@DateTimeFormat`注解来指定期望输入的数据格式以及对应的时区。这样做的好处是可以让框架自动完成字符串到Java `Date`, `Calendar`, 或者Joda Time类型的转换工作,并考虑到了不同的地区差异: ```java @PostMapping("/post") public ResponseEntity<?> createPost(@ModelAttribute Post post, BindingResult bindingResult) { // Validate and process 'post' entity... } // In your model/entity class definition: private LocalDateTime createdOn; @DateTimeFormat(iso = ISO.DATE_TIME, pattern="yyyy-MM-dd'T'HH:mm:ssZ", isoPattern=true) public void setCreatedOn(LocalDateTime createdOn){ this.createdOn = createdOn.withZoneSameInstant(ZoneId.of("Asia/Shanghai")); } ``` 这里展示了如何结合自定义setter方法与`@DateTimeFormat`一起使用,从而确保接收到的时间戳被正确解释为上海所在的东八区时间[^2]。 #### 返回JSON响应时控制时区 为了使返回给前端用户的JSON数据包含正确的本地化时间表示形式,可以在序列化过程中应用Jackson库提供的特性之一——`ObjectMapper`配置项。具体来说就是注册一个新的模块用于支持JSR-310 API下的类(`LocalDateTime`, etc.),并通过设定`SerializationFeature.WRITE_DATES_AS_TIMESTAMPS`选项关闭以毫秒数输出的方式转而采用ISO8601标准格式加上偏移量的形式展示时间点: ```yaml spring: jackson: serialization.write_dates_as_timestamps: false date-format: yyyy-MM-dd'T'HH:mm:ss.SSSXXX ``` 上述YAML片段应该放置于项目的`application.yml`文件内;如果偏好`.properties`风格,则相应地改为键值对表达即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值