6

美好的一天,
我创建了将在全球范围内使用的 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);

它返回我错误(我需要在我的域模型的覆盖相等方法中比较它们)
下面是两者的打印:

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

问题:

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

谢谢

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

2 回答 2

2

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

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 的 f.ex)或更新驱动程序。当前最新版本为 1.5.7 至 25.01.2017

于 2017-01-25T07:40:15.690 回答
0

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

来自 MySQL 5.6 文档:

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

TIMEMySQL 5.6.4 及更高版本扩展了对、DATETIME和值的小数秒支持,TIMESTAMP精度高达微秒(6 位)。...

如果您愿意,可以比较本文档中5.55.65.7版本的更改。

于 2017-01-24T21:05:25.227 回答