ZonedDateTime对SQL数据库的持久性



您好,
我创建了将在世界各地使用的web应用程序服务
因此,我需要将日期时间值存储为UTC,并将其表示为墙上的时钟时间给最终用户
在阅读堆栈溢出后,我明白了,我应该:

  1. 使用时间戳作为DB中的列类型(当前为MariaDB 10.1.20)
  2. 在Java中使用ZonedDateTime(我使用java8)

在这些值之间转换时出现问题
当我使用JDBC时,我必须进行以下转换:

java.sql.Timestamp <-> java.time.ZonedDateTime 

我的代码:

// Get current zonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
// Convert zonedDateTime to java.sql.Timestamp before saving to DB
Timestamp = Timestamp.from(zonedDateTime.toInstant());
// Get zonedDateTime from resultSet
Timestamp timestamp = (Timestamp) resultSet.getObject("created");
ZonedDateTime zonedDateTime = 
ZonedDateTime.ofInstant(ts.toInstant(), ZoneOffset.UTC))

当我使用:

zonedDateTimeBeforeSave.isEqual(zonedDateTimeAfterSave);

它返回false(我需要在域模型的重写的equal方法中比较它们)
下面是两者的打印结果:

zonedDateTimeBeforeSave:2017-01-24T20:18:17.720Z
zonedDateTimeAfterSave:2017-01:24T20:17:17Z

问题:

  1. 我的选择对吗。也许,我应该使用另一个列或java类型
  2. 我做转换是对的吗。也许还有更好的方法

谢谢

  1. 编辑:在Matt Johnson的帮助下,我明白问题出在事实上,当我将日期时间保存到DB时,它不会保存分数,尽管它应该保存。仅供参考的列类型为时间戳(6)
  2. 编辑:现在我使用java.time.Instant而不是ZonedDateTime

在阅读了这篇文章和评论后,我终于发现了问题所在:

http://mysqlnoob.blogspot.com/2016/09/replication-from-mysql-56-to-mariadb-10-fails-with-fractional-seconds.html

原因是我的MariaDB JDBC驱动程序
我有一个旧的1.1.7版本,参数"useFractionalSeconds"设置为false
解决方案是将此参数设置为true(例如URL)或更新驱动程序。截至2017年1月25日,当前最新版本为1.5.7

MySQL在5.6.4版本中增加了对小数秒的支持。我的猜测是,你正在运行比这更旧的东西,因此你的毫秒数被截断了。

来自MySQL 5.6文档:

在MySQL 5.6.4之前,实例是有限的,其中允许在时间值中使用小数秒部分。在文本值等上下文中,以及在某些时态函数的参数或返回值中,允许使用尾随小数部分。。。但是,当MySQL将一个值存储到任何时态数据类型的列中时,它会丢弃任何小数部分,并且不存储它

MySQL 5.6.4及以上版本扩展了对TIMEDATETIMETIMESTAMP值的小数秒支持,精度高达微秒(6位数)。。。

如果您愿意,请比较此文档中5.5、5.6和5.7版本的更改。

相关内容

  • 没有找到相关文章

最新更新