在Java中处理MySQL日期时间和时间戳

在Java中处理MySQL日期时间和时间戳,java,mysql,date,jdbc,timestamp,Java,Mysql,Date,Jdbc,Timestamp,在java应用程序中,在使用混合使用日期时间和时间戳的MySQL数据库提取和输入日期信息方面,有什么好的折衷办法 MySQL有关于将MySQL类型映射到Java类型的信息。一般来说,对于MySQL的datetime和Timestamp,应该使用java.sql.Timestamp。一些资源包括: 编辑: 正如其他人所指出的,使用字符串的建议可能会导致问题。在Java方面,日期通常由表示(设计不好,但除此之外)。它基本上是由长的样式支持的,也称为时间戳。它包含有关日期和时间部分的信息。在J

在java应用程序中,在使用混合使用日期时间和时间戳的MySQL数据库提取和输入日期信息方面,有什么好的折衷办法

MySQL有关于将MySQL类型映射到Java类型的信息。一般来说,对于MySQL的datetime和Timestamp,应该使用
java.sql.Timestamp
。一些资源包括:

编辑:


正如其他人所指出的,使用字符串的建议可能会导致问题。

在Java方面,日期通常由表示(设计不好,但除此之外)。它基本上是由
长的
样式支持的,也称为时间戳。它包含有关日期和时间部分的信息。在Java中,精度以毫秒为单位

在SQL端,有几种标准的日期和时间类型,
date
time
TIMESTAMP
(在一些数据库中也称为
DATETIME
),它们在JDBC中表示为和,
java.util.date
的所有子类。精度取决于数据库,通常以毫秒为单位,如Java,但也可以以秒为单位

java.util.Date
相反,
java.sql.Date
只包含关于日期部分(年、月、日)的信息。
时间
仅包含有关时间部分(小时、分钟、秒)的信息,
时间戳
包含有关这两部分的信息,就像
java.util.Date
一样

在数据库中存储时间戳的正常做法(因此,在java端为
java.util.Date
,在JDBC端为
java.sql.timestamp
)是使用

从数据库获取时间戳的通常做法是使用


BalusC对这个问题给出了很好的描述,但是它缺少一个好的端到端代码,用户可以自己选择并测试它

最佳实践是始终将日期时间存储在UTC时区的DB中。 Sql时间戳类型没有时区信息

将日期时间值写入sql db时

    //Convert the time into UTC and build Timestamp object.
    Timestamp ts = Timestamp.valueOf(LocalDateTime.now(ZoneId.of("UTC")));
    //use setTimestamp on preparedstatement
    preparedStatement.setTimestamp(1, ts);
将值从DB读回java时

  • 按java.sql.Timestamp类型的原样阅读
  • 使用atZone将DateTime值修饰为UTC时区中的时间 LocalDateTime类中的方法
  • 然后,将其更改为所需的时区。我把它改成 多伦多时区

    ResultSet resultSet = preparedStatement.executeQuery();
    resultSet.next();
    Timestamp timestamp = resultSet.getTimestamp(1);
    ZonedDateTime timeInUTC = timestamp.toLocalDateTime().atZone(ZoneId.of("UTC"));
    LocalDateTime timeInToronto = LocalDateTime.ofInstant(timeInUTC.toInstant(), ZoneId.of("America/Toronto"));
    

  • 为什么把日期转换成字符串会更好呢?不要像字符串一样来回按摩。这是造成可移植性和可维护性问题的秘诀。我相应地修改了我的答案。你认为在模型(java层)中使用java.sql.Timestamp不好吗?@cherouvim:是的。模型不应该知道任何JDBC细节。仅用于设置时间戳<代码>preparedStatement.setTimestamp(新的时间戳(date.getTime())。获取它很容易,因为它已经是
    java.util.Date
    的一个子类。如果您的所有机器和用户都在同一时区中,这将很好地工作。否则,请注意MySQL JDBC驱动程序对时区转换的处理是极其复杂和有缺陷的。例如,请参见BalusC,在您看来,DB中的列应该使用什么类型(日期/时间戳?)。按照你的例子,我从DB读到2017-01-24 19:17:11.0,但在2017年1月24日星期二19:17:11之前。此外,当我使用compareTo进行比较时,我得到:before>after。另外,我用的是时间戳DB@Sabine:您有带时区的时间戳。并非所有DBs都支持这一点。例如,PostgreSQL和Oracle有,但MySQL没有。您需要先转换为固定时区,然后才能保存到DB中。通常使用UTC。
        //Convert the time into UTC and build Timestamp object.
        Timestamp ts = Timestamp.valueOf(LocalDateTime.now(ZoneId.of("UTC")));
        //use setTimestamp on preparedstatement
        preparedStatement.setTimestamp(1, ts);
    
    ResultSet resultSet = preparedStatement.executeQuery();
    resultSet.next();
    Timestamp timestamp = resultSet.getTimestamp(1);
    ZonedDateTime timeInUTC = timestamp.toLocalDateTime().atZone(ZoneId.of("UTC"));
    LocalDateTime timeInToronto = LocalDateTime.ofInstant(timeInUTC.toInstant(), ZoneId.of("America/Toronto"));