有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JDBC MySQL从Unix时代开始以毫秒为单位读取和写入时间戳

我通过JDBC访问MySQL表中的TIMESTAMP列。在Java方面,我使用的是JodaTime

我希望将自Unix时代以来的所有实例表示为毫秒。我只想使用一个整数字段,但我想使用ON UPDATE CURRENT_TIMESTAMP语法,它只支持TIMESTAMP/DATETIME类型

JodaTime允许我轻松地在不同的表示和自epoch以来的毫秒之间进行转换,但是it's not so simple to use milliseconds since epoch with JDBC/MYSQL

我是否可以使用JDBC在时间戳列中存储毫秒\u自\u epoch,并将时间戳列检索为毫秒\u自\u epoch,而不必担心由于客户端或服务器更改时区而导致的值更改

我希望不必乱弄mysql服务器设置或jdbc连接设置,但如果这是唯一的方法,我愿意这样做


共 (2) 个答案

  1. # 1 楼答案

    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

    对于5.6.4之前的MySQL服务器版本:

    否。时间戳列将丢弃小数秒(参考:here

    如果你真的需要存储毫秒,那么你必须把它们放在一个单独的数字列中。但是,如果您可以使用整秒的时间分辨率,则时间戳列将在存储值时自动将其转换为UTC(参考:here

    对于MySQL服务器5.6.4及更高版本:

    对。有关更多信息,请参阅以下MySQL文档主题:

    Fractional Seconds in Time Values

  2. # 2 楼答案

    让你的工具担心毫秒

    您正在对抗SQL、JDBC和Java的类型系统。不要担心毫秒。你的数据库、驱动程序和Java已经在为你做这些了,但是更精细(MySQL是微秒,Java是纳秒)

    I would like to represent all my instants as milliseconds since the Unix epoch.

    这正是MySQL在其TIMESTAMP数据类型中为您所做的事情,只是更精细——自1970年UTC开始以来的微秒计数。致quote the doc

    TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

    TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision

    你对留在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

    …已经解决了。MySQL正在UTC中存储一个TIMESTAMP,您的JDBC驱动程序应该在UTC中检索值,而java。时间类Instant以UTC为单位存储值。^{}类表示UTC中时间轴上的一个时刻,分辨率为nanoseconds(最多九(9)位小数)所以你一直只有UTC

    尽可能避免麻烦的旧日期时间类。取而代之的是java。时间课。如果JDBC driver更新为JDBC 4.2或更高版本,则可以直接使用java。时间类型

    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或从java转换。时间不要用java执行业务逻辑。sql类型

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

    …还有

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

    当您希望调整出UTC并进入时区(例如向用户演示)时,请应用ZoneId以获得ZonedDateTime。搜索堆栈溢出以获取更多示例

    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。时间

    java.time框架内置于Java8及更高版本中。这些类取代了legacy日期时间类,比如^{}^{}、&^{}

    现在位于maintenance modeJoda-Time项目建议迁移到java.time

    要了解更多信息,请参阅Oracle Tutorial。并在Stack Overflow中搜索许多示例和解释。规格是JSR 310

    你可以交换java。时间对象直接与数据库连接。使用符合JDBC 4.2或更高版本的JDBC driver。不需要字符串,也不需要java.sql.*

    在哪里可以获得java。时间课

    ThreeTen-Extra项目扩展了java。有额外课程的时间。这个项目是java未来可能增加的一个试验场。时间你可以在这里找到一些有用的类,比如^{}^{}^{}more