【发布时间】:2018-02-11 22:10:42
【问题描述】:
回答:这个问题以不同的形式遍布 styackoverflow,我已经能够很好地利用一些答案。但在这一点上,即使以前回答过的问题似乎也没有任何效果。这个问题好像应该够简单了,我这里真的是一头雾水。
我有一个项目(约会日历),其中需要将日期时间存储在 MySQL 中,然后以正确的时间显示在本地计算机上的时区,无论从何处查看它。要做到这一点,我觉得最简单的方法是将时间存储在 UTC 中。因此,无论何时创建约会,开始和结束时间都会在客户端转换为 UTC,然后存储在数据库中。到目前为止,一切都很好。我能够用这段代码完成这个。 DateTimePermissive 特定于我正在使用的选择器
LocalDateTime st = start.getDateTimePermissive();
ZonedDateTime stz = st.atZone(ZoneId.systemDefault());
ZonedDateTime stzUTC = stz.withZoneSameInstant(ZoneId.of("UTC"));
java.sql.Timestamp startTime = Timestamp.valueOf(stzUTC.toLocalDateTime());
LocalDateTime et = end.getDateTimePermissive();
ZonedDateTime etz = st.atZone(ZoneId.systemDefault());
ZonedDateTime etzUTC = etz.withZoneSameInstant(ZoneId.of("UTC"));
java.sql.Timestamp endTime = Timestamp.valueOf(etzUTC.toLocalDateTime());
我遇到麻烦的地方是从另一个方向回来。我已经尝试了各种其他方法来做到这一点,即使我觉得我的代码是正确的,似乎也无法让它工作。这就是我现在正在尝试的方法。
java.sql.Timestamp st = apptRecords.getTimestamp("start");
LocalDateTime stld = st.toLocalDateTime();
ZonedDateTime startTime = stld.atZone(ZoneId.systemDefault());
//String startTimeConverted = startTime.toString();
java.sql.Timestamp et = apptRecords.getTimestamp("end");
LocalDateTime etld = et.toLocalDateTime();
ZonedDateTime endTime = etld.atZone(ZoneId.systemDefault());
//String endTimeConverted = endTime.toString();
这似乎应该工作。我还尝试创建一个 ZonedDateTime 设置为 UTC,然后将其设置为本地时间,我认为这可能是因为 java.sql.timestamp 不包含可能需要的时区。那也没用。
此时,我非常乐意将时区偏移量作为 int 值存储在某个静态变量中,然后执行 ZonedDateTime.minus(ZoneOffsetNumber, minutes) 或类似的操作以获得正确的本地时间,但是我不知道如何找到并将其存储为 int 值。
它只是一直在 UTC 时间返回。它显示正确的时区名称,如美国/东部,但仍以 UTC 显示时间。
我应该使用 atInstant 吗?我也无法让它工作。
这是一个学校项目,我不能更改 MySQL 中的任何变量类型。这些特定的是日期时间。
有人有这方面的经验吗?对于这样的事情,似乎以 UTC 存储在服务器上是最佳实践。我不知道为什么回到原来的时区如此困难。
编辑:我在这里找到了 Abdelhafid 的答案:Is java.sql.Timestamp timezone specific?
通过将他提到的连接属性添加到连接属性中
useTimezone=true
useLegacyDatetimeCode=false
serverTimezone=UTC
无论我从哪个时区登录,时间都会转换为正确的时间。
因此,如果其他人对此有疑问,这就是您的答案。像这样设置你的连接器
Properties props = new Properties();
props.setProperty("user", "root");
props.setProperty("password", "");
props.setProperty("useTimezone", "true");
props.setProperty("useLegacyDatetimeCode", "false");
props.setProperty("serverTimezone", "UTC");
Connection con = DriverManager.getConnection(conString, props);
【问题讨论】:
-
你不能用
LocalDateTime stld = apptRecords.getObject("start", LocalDateTime.class);吗?并跳过旧的Timestamp课程。无论如何,下一步将是ZonedDateTime startTime = stld.atZone(ZoneOffset.UTC).withZoneSameInstant(ZoneId.systemDefault());。我敢肯定,您一直在寻找的一些答案会说类似的话。 -
如果您认为您的问题已得到解答,我们非常欢迎您在下方发布您的答案,并接受它(一段时间后)。然后其他人就会清楚,有一个答案,答案是什么。这肯定会有所帮助。
-
哦,对不起。我能够回答这个问题。请参阅编辑:原始帖子中的文本。我没有足够高的评分来回答它我不认为
-
Ole V.V.我也尝试过 withZoneSameInstant 方法。除了如上所示更改连接器属性外,没有任何效果。
标签: java mysql timestamp utc timezone-offset