Java 自Unix纪元以来JDBC MySQL读写时间戳(毫秒)
我通过JDBC访问MySQL表中的TIMESTAMP列。在Java方面,我使用的是JodaTime 我希望将自Unix时代以来的所有实例表示为毫秒。我只想使用一个整数字段,但我想使用只支持TIMESTAMP/DATETIME类型的Java 自Unix纪元以来JDBC MySQL读写时间戳(毫秒),java,mysql,jdbc,timestamp,Java,Mysql,Jdbc,Timestamp,我通过JDBC访问MySQL表中的TIMESTAMP列。在Java方面,我使用的是JodaTime 我希望将自Unix时代以来的所有实例表示为毫秒。我只想使用一个整数字段,但我想使用只支持TIMESTAMP/DATETIME类型的ON UPDATE CURRENT_TIMESTAMP语法 JodaTime允许我轻松地在不同的表示形式和自epoch以来的毫秒之间进行转换,但是 是否有任何方法可以使用JDBC在时间戳列中存储毫秒\u自\u epoch,并将时间戳列检索为毫秒\u自\u epoch,而
ON UPDATE CURRENT_TIMESTAMP
语法
JodaTime允许我轻松地在不同的表示形式和自epoch以来的毫秒之间进行转换,但是
是否有任何方法可以使用JDBC在时间戳列中存储毫秒\u自\u epoch,并将时间戳列检索为毫秒\u自\u epoch,而不必担心由于客户端或服务器更改时区而导致的值更改
我希望不必乱弄mysql服务器设置或jdbc连接设置,但如果这是唯一的方法,我愿意这样做
是否有任何方法可以使用JDBC在时间戳列中存储毫秒\u自\u epoch,并将时间戳列检索为毫秒\u自\u epoch
对于5.6.4之前的MySQL服务器版本:
否。时间戳列将丢弃小数秒(参考:)
如果您真的需要存储毫秒,那么您必须将它们放在单独的数字列中。但是,如果您可以使用整秒的时间分辨率,则时间戳列将在存储值时自动将值转换为UTC(参考:)
对于MySQL服务器5.6.4及更高版本:
对。有关更多信息,请参阅以下MySQL文档主题:
让您的工具担心毫秒数
您正在与SQL、JDBC和Java类型系统作斗争。不要担心毫秒数。您的数据库、驱动程序和Java已经在为您这样做了,但更精细(MySQL中为微秒,Java中为纳秒)
我希望将自Unix时代以来的所有实例表示为毫秒
这正是MySQL在其时间戳
数据类型中为您所做的,只是更精细——自1970年开始以UTC计算以来的微秒数。致:
时间戳的范围为“1970-01-01 00:00:01”UTC到“2038-01-19 03:14:07”UTC
时间戳值可以包括精度高达微秒(6位)的尾随小数秒部分
您对留在UTC的担忧
从\u epoch开始以毫秒\u的形式检索时间戳列,而不必担心由于客户端或服务器更改时区而导致的值更改
…已经解决了。MySQL正在UTC中存储时间戳
,您的JDBC驱动程序应该在UTC中检索值,java.time类Instant
将值存储在UTC中。该类表示时间线上的一个时刻,分辨率为(小数点的九(9)位)因此您始终只有UTC。
尽可能避免麻烦的旧日期时间类。而是使用它们的替代品java.time类。如果更新了for和更高版本,则可以直接使用java.time类型
Instant instant = Instant.now() ; // Current moment in UTC with resolution up to nanoseconds.
myPreparedStatement.setObject( … , instant ) ;
……还有
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Instant instant = myResultSet.getTimestamp( … ).toInstant() ;
如果您的JDBC驱动程序尚不兼容,请简要使用旧的java.sql类型,但立即转换为java.time。不要使用java.sql类型执行业务逻辑
myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;
……还有
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Instant instant = myResultSet.getTimestamp( … ).toInstant() ;
当您想要调整出UTC并进入时区(如向用户演示)时,请应用ZoneId
以获取zoneDateTime
。搜索堆栈溢出以获取更多示例
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
如果您坚持从epoch开始访问毫秒,请询问Instant
对象。但要小心数据丢失,因为MySQL可能会在瞬间丢失微秒数据,而其他数据源可能会在瞬间丢失纳秒数据。要求毫秒意味着截断一秒钟的更精细部分
long millisSinceEpoch = instant.toEpochMilli() ;
往另一个方向走
Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- ,及以后
- 内置的李>
- 标准JavaAPI的一部分,带有捆绑实现
- Java9添加了一些次要功能和修复
- 及
- 大部分java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(你能详细解释一下为什么你不想使用bigint并实际存储毫秒数而不是目标日期/时间转换吗?如果只是时间戳列更新的速度太快,你可以定义一个匹配的触发器。首先你依靠MySQL自动更新列,但是你需要一种方法来设置它…是什么?我是b我开始认为使用bigint+触发器是我最好的选择,但我仍然保留这个问题,以防有更好的方法来解决。如果没有方法通过JDBC设置字段,那可能没问题,因为我不认为我需要为同一列同时设置+自动更新,但如果时间戳字段可以ld有两个用途。你可能还想考虑选择/报告:日期列提供了一些非常好的嵌入式函数,而秒/毫秒在按同一个工作日进行分组方面不是很方便……这是MySQL 5.7的发展:实际上,MySQL 5.6.4增加了支持。5.6.4之前的MySQL不支持它,but 5.6.4或更高版本(包括