Spring MVC - 将用户时区的日期转换为 UTC

Posted

技术标签:

【中文标题】Spring MVC - 将用户时区的日期转换为 UTC【英文标题】:Spring MVC - convert dates from user's timezone into UTC 【发布时间】:2016-02-17 13:46:09 【问题描述】:

often recommended 将日期时间以 UTC 格式存储在数据库中,并以当地时区向用户显示/接收。

我正在尝试在 Spring MVC / Spring Boot 应用程序中实现此模式,但无法找到文档或示例。我在 @ModelAttribute 表单对象的 java.util.Date 属性上使用 @DateTimeFormat 注释来使 Spring 解析/格式化日期。

Spring 是否内置了对这种模式的支持?类似于Django's timezone-aware datetimes 的东西会很好。如果没有,是否有一种不太麻烦的实现方式?或者有没有更好的方法在 Spring MVC 应用程序中处理/存储日期时间?

目前该应用程序仅适用于英国,因此目前我只需要支持 BST(夏令时),而不需要针对不同用户的不同时区。然而,支持不同时区的用户是未来的潜在需求。

【问题讨论】:

您是否将日期存储在 Date o Calendar 对象中? 你有没有想过这个问题?我对此也很感兴趣。 @reos,我们现在将其存储为 java.util.Date @Andy 不是。我发现在这种环境中,日期和时间被解释为在服务器 JVM 的时区中,所以我们暂时将服务器的时区设置为我们用户所在的时区(欧洲/伦敦)并且我们正在使用我们的 PostgreSQL 数据库中日期字段的“带时区的时间戳”数据类型,以便跨越夏令时更改的日期计算工作。如果应用需要支持其他时区的用户,我们将不得不重新审视我们的工作方式。 好的,感谢您的反馈! 【参考方案1】:

希望这会对您有所帮助,或者至少是您可以开始的起点。

看起来最好的方法是使用 OffsetDateTime 类型来存储日期。将来自用户的 dateTime 值转换为 UTC 很容易:

OffsetDateTime createdOn = requestDto.getCreatedOn();
OffsetDateTime utc = createdOn.atZoneSameInstant(ZoneId.of("UTC"));

然后再返回(当然您也需要存储用户时区):

OffestDateTime eventDate = modelObject.getEventDate();
OffsetDateTime userTime = eventDate.atZoneSameInstant(ZoneId.of(userTimeZone));

要在 UTC 中实例化新的日期对象,您可以使用 clock-object:

OffestDateTime now = OffestDateTime.now(Clock.systemUTC());
ModelObject dto = new ModelObject();
dto.setEventDate(now);

最后如果你不需要显示偏移量,你可以使用 LocalDateTime 类型:

OffestDateTime eventDate = databaseModelObject.getEventDate();
LocalDateTime userTime = eventDate.atZoneSameInstant(ZoneId.of(userTimeZone)).toLocalDateTime());
ResponseDto response = new ResponseDto();
response.setEventDate(userTime);

【讨论】:

以上是关于Spring MVC - 将用户时区的日期转换为 UTC的主要内容,如果未能解决你的问题,请参考以下文章

检索日期并根据用户时区将其转换为特定时区

如何将 Moment.js 日期转换为用户本地时区?

使用 joda time 将一个时区转换为另一个时区

如何将 UTC 日期时间字符串转换为用户的当前时区?

JavaScript:将 UTC 日期时间转换为传递时区的日期时间

如何在javascript中将日期时间从用户时区转换为EST [重复]