我尝试添加时区的支持到网络应用程序。用户的时区将用于显示时间和计算。
我检查了很多博客和StackOverflow上关于Hibernate的帖子,Sping Boot 与时区有关,但我没有找到解决方案。一些帖子描述了使用时区只显示日期/时间给用户,但这是不够的。我需要从数据库加载的日期时间与用户时区在服务器上进行计算。
我用休眠拦截器做了一些实验(Hibernate用户指南-事件)。Hibernate提供了用onLoad
方法实现拦截器的能力,该方法允许在加载后修改实体。在这种情况下,拦截器应该根据从一些全局服务获得的用户时区修改日期/时间字段。它看起来像是我需要的东西,但我没有任何生产经验,也没有“I don’我不知道这是解决问题的好办法。
要求
每个用户都应该能够设置自己的时区。
时区不仅用于时间显示,也用于计算。应用程序包括一个预订模块,其中准确的时间是重要的。它不能是我们允许某人预订约会,例如,在10:00,因为它只是8:30在服务器上,因为它可能已经是1:00 p.m.,即3小时后的约会时间在用户的时区。
问题
我想根据当前用户设置更改Hibernate对每个HTTP请求使用的时区。如何设置Hibernate在给定请求期间使用的时区?
技术堆栈
在我使用Hibernate的应用程序中,时间总是以UTC格式保存在数据库中,在应用程序端,时间被转换为config中设置的时区(每个用户都使用相同的时区)。
我在应用程序中使用Quarkus,但Sping Boot 的解决方案也令我满意。将Spring Boot或其他Java EE框架的解决方案重写到Quarkus对我来说不成问题。
1条答案
按热度按时间mrfwxfqh1#
我认为这很简单,但由于某些原因,你的情况过于复杂。
如果这是一个
spring-mvc
应用程序,我会理解UI后端与某种时区通信的需要。但您可能有一个rest后端应用程序,因为您提到了quarkus
/spring-boot
。Rest应用程序通常是无状态的。我认为这个article来自非常有名的**@vlad-mihalcea**,它也验证了什么是最佳实践,它的结论我也100%同意。
处理时区时,最好尽可能使用UTC,并且在呈现UI时只将时间戳转换为当前用户时区。
所以我认为如果你使用UTC作为数据库,UTC作为后端服务器,你只需要在UI中使用时区,让用户读取它,只需要将UTC转换为用户的时区,你的问题就会简化很多。如果你有一个普通的无状态rest应用程序,那么后端对用户时区是完全不可知的。用户生活在浏览器窗口中,所以只有前端知道用户时区。
即使我们假设您需要记住用户的时区,您也可以将用户的特定时区存储在数据库中(用户A的时区为GMT+2),然后UI可以轮询它一次,然后将从后端接收的所有数据转换为该特定用户的时区。
因此,如果您在后端进行与用户
timezone
相关的计算,并且您还在数据库中持久化时区,我会将此视为可能的体系结构缺陷,即使您设法暂时解决了问题,将来也可能会使情况过于复杂。