简体   繁体   English

JDBC MySQL读取和写入TIMESTAMP的时间,以毫秒为单位,距离Unix Epoch

[英]JDBC MySQL reading and writing TIMESTAMP as milliseconds since Unix Epoch

I have a TIMESTAMP column in a MySQL table which I am accessing through JDBC. 我在通过JDBC访问的MySQL表中有一个TIMESTAMP列。 On the Java side, I am using JodaTime. 在Java方面,我正在使用JodaTime。

I would like to represent all my instants as milliseconds since the Unix epoch. 我想将我的所有瞬间表示为自Unix时代以来的毫秒数。 I would just use an integer field, but I want to use the ON UPDATE CURRENT_TIMESTAMP syntax which is only supported for TIMESTAMP/DATETIME types. 我只使用整数字段,但是我想使用仅TIMESTAMP / DATETIME类型支持的ON UPDATE CURRENT_TIMESTAMP语法。

JodaTime allow me to easily convert between the different representations and milliseconds since epoch, but it's not so simple to use milliseconds since epoch with JDBC/MYSQL . JodaTime让我可以轻松地从epoch到毫秒之间转换不同的表示形式,但是使用JDBC / MYSQL从epoch到毫秒之间并不是那么简单

Is there any way I can us JDBC to store milliseconds_since_epoch in a TIMESTAMP column, and retrieve TIMESTAMP columns as milliseconds_since_epoch without having to worry about the values changing due to the client or the server changing timezones. 我有什么办法可以使我们的JDBC将milliseconds_since_epoch存储在T​​IMESTAMP列中,并将TIMESTAMP列检索为milliseconds_since_epoch,而不必担心由于客户端或服务器更改时区而导致的值更改。

I would prefer to not have to mess with mysql server settings or jdbc connection settings, but I would be willing to if it's the only way. 我希望不必弄乱mysql服务器设置或jdbc连接设置,但是如果这是唯一的方法,我将愿意。

Is there any way I can us JDBC to store milliseconds_since_epoch in a TIMESTAMP column, and retrieve TIMESTAMP columns as milliseconds_since_epoch 有什么办法可以使我们的JDBC在TIMESTAMP列中存储milliseconds_since_epoch,并将TIMESTAMP列检索为milliseconds_since_epoch

For MySQL Server versions prior to 5.6.4: 对于5.6.4之前的MySQL服务器版本:

No. A TIMESTAMP column will discard fractional seconds (ref: here ). 不会。TIMESTAMP列将舍弃小数秒(参考: 此处 )。

If you really need to store milliseconds then you'll have to put them in a separate numeric column. 如果您确实需要存储毫秒,则必须将它们放在单独的数字列中。 However, if you can make do with time resolution of whole seconds then a TIMESTAMP column will automatically convert values to UTC when they are stored (ref: here ). 但是,如果可以使用整秒的时间分辨率,则TIMESTAMP列将在存储值时自动将其转换为UTC(请参阅: 此处 )。

For MySQL Server versions 5.6.4 and later: 对于MySQL Server 5.6.4及更高版本:

Yes. 是。 See the following MySQL documentation topic for more information: 有关更多信息,请参见以下MySQL文档主题:

Fractional Seconds in Time Values 时间值的分数秒

Let your tools worry about the milliseconds 让您的工具担心毫秒

You are fighting against the type system of SQL, JDBC, and Java. 您正在与SQL,JDBC和Java的类型系统作斗争。 Do not worry about the milliseconds. 不用担心毫秒。 Your database, driver, and Java are already doing that for you, but finer (microseconds in MySQL, nanoseconds in Java). 您的数据库,驱动程序和Java已经为您做到了,但是更好(MySQL中为微秒,Java中为纳秒)。

I would like to represent all my instants as milliseconds since the Unix epoch. 我想将我的所有瞬间表示为自Unix时代以来的毫秒数。

This is exactly what MySQL is doing for you in its TIMESTAMP data type, only finer - A count of microseconds since start of 1970 in UTC. 这正是MySQL在其TIMESTAMP数据类型中为您所做的,只是更好-自1970年以来,在UTC中以毫秒为单位。 To quote the doc : 引用文档

TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC. TIMESTAMP的UTC范围为'1970-01-01 00:00:01'至UTC'2038-01-19 03:14:07'。

...

TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision TIMESTAMP值可以包含尾随的小数秒部分,精度最高为微秒(6位数)

Your concern about staying in UTC… 您对留在UTC的担忧...

retrieve TIMESTAMP columns as milliseconds_since_epoch without having to worry about the values changing due to the client or the server changing timezones 检索TIMESTAMP列为milliseconds_since_epoch,而不必担心由于客户端或服务器更改时区而导致值更改

…is already addressed. …已经解决。 MySQL is storing a TIMESTAMP in UTC, your JDBC driver should be retrieving the value in UTC, and the java.time class Instant stores the value in UTC. MySQL在UTC中存储TIMESTAMP ,您的JDBC驱动程序应在UTC中检索值,而java.time类Instant将值存储在UTC中。 The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). Instant类以UTC表示时间轴上的时刻,分辨率为纳秒 (最多十进制的九(9)位数字)。 So you have UTC only, all the way through. 因此,您始终只有UTC。

Avoid the troublesome old date-time classes whenever possible. 尽可能避免使用麻烦的旧日期时间类。 Instead use their replacement, the java.time classes. 而是使用它们的替换java.time类。 If your JDBC driver is updated for JDBC 4.2 and later you can work directly with java.time types. 如果您的JDBC驱动程序针对JDBC 4.2和更高版本进行了更新,则可以直接使用java.time类型。

Instant instant = Instant.now() ;  // Current moment in UTC with resolution up to nanoseconds.
myPreparedStatement.setObject( … , instant ) ;

…and… …和…

Instant instant = myResultSet.getObject( … , Instant.class ) ;

If your JDBC driver is not yet compliant, briefly use the old java.sql types but convert immediately to/from java.time. 如果您的JDBC驱动程序还不兼容,请简要使用旧的java.sql类型,但立即将其转换为java.time。 Do not perform business logic with the java.sql types. 不要使用java.sql类型执行业务逻辑。

myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;

…and… …和…

Instant instant = myResultSet.getTimestamp( … ).toInstant() ;

When you want to adjust out of UTC and into a time zone such as for presentation to a user, apply a ZoneId to get a ZonedDateTime . 当您在UTC之外进行调整并进入某个时区(例如向用户演示)时,请应用ZoneId以获得ZonedDateTime Search Stack Overflow for many more examples. 搜索堆栈溢出以获取更多示例。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, different wall-clock time.

If you insist on accessing milliseconds-since-epoch, interrogate the Instant object. 如果您坚持要访问毫秒级以来的时间,请询问Instant对象。 But beware of data-loss, as that instant may hold microseconds from MySQL or nanoseconds from other sources. 但是要提防数据丢失,因为该瞬间可能会发生MySQL发出的微秒或其他来源发出的纳秒的情况。 Asking for milliseconds means truncating the finer fraction of a second. 要求毫秒表示将秒数缩短一秒。

long millisSinceEpoch = instant.toEpochMilli() ;

Going the other direction. 走另一个方向。

Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;

About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧的旧式日期时间类,例如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参见Oracle教程 And search Stack Overflow for many examples and explanations. 并在Stack Overflow中搜索许多示例和说明。 Specification is JSR 310 . 规格为JSR 310

You may exchange java.time objects directly with your database. 您可以直接与数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later. 使用与JDBC 4.2或更高版本兼容的JDBC驱动程序 No need for strings, no need for java.sql.* classes. 不需要字符串,不需要java.sql.*类。

Where to obtain the java.time classes? 在哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目为将来可能在java.time中添加内容提供了一个试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM