【发布时间】:2020-03-05 10:06:00
【问题描述】:
我正在开发一个使用 MySQL 数据库的 Spring Boot REST API。我正在尝试“按原样”保存从客户端应用程序接收到的日期(带时间),该日期是 UTC 时间。基本上,已经同意日期将在 UTC 中来回发送,并且将在客户端上完成到适当时区的转换,所以我已经有 JSON 中的 UTC 时间,我正在尝试将其保存到 DATETIME 列在 MySQL 中。
我选择 DATETIME 是因为 MySQL reference 中说 TIMESTAMP 转换值,而 DATETIME 没有,这正是我所需要的。
我已经创建了映射表所需的所有实体,from reference,我已经看到 DATETIME 映射到 java.sql.Timestamp,所以这就是我用作类型的内容。
我正在使用 JpaRepository 并调用它的 save 方法来保存我的实体。 发生的情况是:当我将日期保存到 MySQL 时,它们会转换为 UTC(我假设,因为我在 UTC+1 并且日期比我插入的时间早一小时)。
我已经阅读了几个关于 SO 的答案,并尝试在我的 jdbc 连接字符串中使用以下属性(如建议的here):noDatetimeStringSync=true、useLegacyDatetimeCode=false、sessionVariables=time_zone='-00:00' 但它们都不起作用。
我不知道是不是 spring 会搞砸这个?
这是我在请求中收到的 JSON 的一部分:
{
"dateFrom": "2019-12-01 16:00:00",
"dateTo": "2019-12-01 16:30:00"
}
我的实体具有以下属性:
import java.sql.Timestamp;
...
private Timestamp dateFrom;
private Timestamp dateTo;
db 中的表列:
date_from datetime
date_to datetime
当我将 String 转换为 Timestamp 并调用 save() 方法时,实体内部具有正确的值。所以 JpaRepository 和数据库本身之间的某些东西会与日期混淆。
更新: Timestamp 实际上不是正确的值,它在从 String 转换时添加了 ZoneInfo with ID="Europe/Prague" 和 zoneOffset=3600000。
我最终得到的是 db 中的 2019-12-01 15:00:00 和 2019-12-01 15:30:00。
我希望按照我收到它们的方式存储这些日期。我什至考虑过切换到 VARCHAR,因为我很沮丧,但我不想这样做,因为我需要根据日期等执行查询。
有什么方法可以实现我想要的吗?起初它看起来很简单,但现在它真的让我发疯了。
[如果需要,请提供其他信息] 我正在使用:
- MySQL 5.7.27
- Spring Boot (starter-parent) 2.2.0.RELEASE
- mysql-connector-java
编辑:
我可能会以错误的方式处理这个问题,所以如果你能建议我如何以不同的方式做到这一点,那就太棒了。 重点是:我的应用需要为不同时区的用户工作,并且他们需要通过日期相互交流。因此,如果欧洲/布拉格时区的一个用户对美国/芝加哥的另一个用户说“让我们明天下午 5 点谈谈”,我需要以一种可以在当地时间为美国用户翻译的方式存储此信息(但也为任何其他时区的任何其他用户)。这就是为什么我选择在 UTC 中存储日期,然后在客户端将它们转换为用户的本地时间。但显然我误解了这一切是如何运作的。
【问题讨论】:
-
日期时间
Strings 不包含任何有关时区或偏移的信息,将通过系统区域设置或数据库的默认区域设置进行解释。检查配置。 -
添加时区信息可以消除歧义。
-
Timestamp变量中存储了什么?在哪个时区? -
@deHaar 哦,好吧,这是有道理的,我认为它会“按原样”存储它而不包括任何时区。我可以以某种方式将其“强制”到 UTC 吗?我刚刚尝试将列类型更改为 TIMESTAMP,同样的事情发生了。
-
@OleV.V. JDBC 没有定义对
Instant的支持,这些是一些驱动程序的非标准扩展。
标签: java mysql spring-boot datetime jdbc