我在MySQL表中有一个TIMESTAMP列,我通过JDBC访问它。在Java方面,我使用的是JodaTime。
我想用自己的时代以毫秒为单位表示我的所有瞬间。我只想使用整数字段,但我想使用ON UPDATE CURRENT_TIMESTAMP
语法,该语法仅支持TIMESTAMP / DATETIME类型。
JodaTime允许我在epoch之后轻松转换不同的表示和毫秒,但是it's not so simple to use milliseconds since epoch with JDBC/MYSQL。
我有没有办法让JDBC在TIMESTAMP列中存储milliseconds_since_epoch,并将millESTAMP列检索为milliseconds_since_epoch,而不必担心由于客户端或服务器更改时区而导致的值更改。
我宁愿不必搞乱mysql服务器设置或jdbc连接设置,但我愿意,如果这是唯一的方法。
答案 0 :(得分:0)
我有没有办法让JDBC在TIMESTAMP列中存储milliseconds_since_epoch,并检索TIMESTAMP列为milliseconds_since_epoch
对于5.6.4之前的MySQL Server版本:
没有。 TIMESTAMP列将丢弃小数秒(参考:here)。
如果你真的需要存储毫秒,那么你必须将它们放在一个单独的数字列中。但是,如果您可以使用整秒的时间分辨率,那么TIMESTAMP列将在存储时自动将值转换为UTC(参考:here)。
对于MySQL Server 5.6.4及更高版本:
是。有关更多信息,请参阅以下MySQL文档主题:
答案 1 :(得分:0)
您正在与SQL,JDBC和Java的类型系统作斗争。不要担心毫秒。你的数据库,驱动程序和Java已经为你做了,但更精细(MySQL中的微秒,Java中的纳秒)。
我希望将所有时刻表示为自Unix时代以来的毫秒数。
这正是MySQL在TIMESTAMP
数据类型中为您所做的事情,只是更精细 - 自UTC 1970年以来的微秒数。致quote the doc:
TIMESTAMP的范围为'1970-01-01 00:00:01'UTC至'2038-01-19 03:14:07'UTC。
...
TIMESTAMP值可以包括一个高达微秒(6位)精度的尾随小数秒部分
您对留在UTC的担忧...
将millESTAMP列检索为milliseconds_since_epoch,而不必担心由于客户端或服务器更改时区而导致的值更改
......已经解决了。 MySQL以UTC格式存储TIMESTAMP
,您的JDBC驱动程序应该以UTC格式检索值,而java.time类Instant
以UTC格式存储该值。 Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。 所以你只有UTC,一直到。
尽可能避免使用麻烦的旧日期时间类。而是使用他们的替换,java.time类。如果JDBC driver更新为JDBC 4.2,稍后您可以直接使用java.time类型。
Instant instant = Instant.now() ; // Current moment in UTC with resolution up to nanoseconds.
myPreparedStatement.setObject( … , instant ) ;
...和...
Instant instant = myResultSet.getObject( … , Instant.class ) ;
如果您的JDBC驱动程序尚未兼容,请简单使用旧的java.sql类型,但立即转换为/从java.time转换。不要使用java.sql类型执行业务逻辑。
myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;
...和...
Instant instant = myResultSet.getTimestamp( … ).toInstant() ;
如果希望调整UTC以及时区(例如向用户演示),请应用ZoneId
获取ZonedDateTime
。搜索Stack Overflow以获取更多示例。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
如果您坚持访问milliseconds-since-epoch,请询问Instant
对象。但请注意数据丢失,因为该瞬间可能会持续MySQL的微秒或其他来源的纳秒。要求毫秒意味着截断一秒的更精细部分。
long millisSinceEpoch = instant.toEpochMilli() ;
走向另一个方向。
Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。