在Java中处理MySQL日期时间和时间戳
在java应用程序中,在使用混合使用日期时间和时间戳的MySQL数据库提取和输入日期信息方面,有什么好的折衷办法 MySQL有关于将MySQL类型映射到Java类型的信息。一般来说,对于MySQL的datetime和Timestamp,应该使用在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.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"));