我在处理OffsetDateTime与MYSQL时间戳之间的转换时遇到了一些麻烦。我的JVM时区是GMT+1,我的数据库时区是UTC,我可以确认是因为now()返回一个小时前的时间戳。
下面是我的代码:
public class TestDBTime {
public static void main(String[] args) throws SQLException, InterruptedException{
testOffsetDateTime();
}
private static void testOffsetDateTime() throws SQLException {
Connection connection = DriverManager.getConnection(DB_Connection.url, DB_Connection.user, DB_Connection.password);
Instant instant = Instant.now();
OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(instant, ZoneId.systemDefault());
System.out.println("Default offset date time from instant: " +offsetDateTime.toString());
OffsetDateTime offsetDateTimeUTC = instant.atOffset(ZoneOffset.UTC);
System.out.println("UTC.... offset date time from instant: " +offsetDateTimeUTC.toString());
String update = "update schedule set timestamp = ? where id = 1";
try (PreparedStatement preparedStatement = connection.prepareStatement(update)){
preparedStatement.setObject(1, offsetDateTimeUTC);
preparedStatement.executeUpdate();
}
String query = "SELECT s.*, now() as now from schedule s where id = 1";
try (PreparedStatement preparedStatement = connection.prepareStatement(query)){
ResultSet resultSet = preparedStatement.executeQuery();
resultSet.next();
OffsetDateTime retrievedDateTime = resultSet.getObject("timestamp", OffsetDateTime.class);
System.out.println("Offset date time retrieved: " +retrievedDateTime);
System.out.println("Retrieved odt is equal to original UTC odt: " +retrievedDateTime.equals(offsetDateTimeUTC));
OffsetDateTime retrievedNow = resultSet.getObject("now", OffsetDateTime.class);
System.out.println("Now: " +retrievedNow);
Timestamp timestamp = resultSet.getTimestamp("timestamp");
System.out.println("Retrieved timestamp instant is equal to original instant: " +timestamp.toInstant().equals(instant));
}
}
}我执行代码,我的控制台输出是:
Default offset date time from instant: 2021-03-26T17:05:11.856+01:00
UTC.... offset date time from instant: 2021-03-26T16:05:11.856Z
Offset date time retrieved: 2021-03-26T17:05:11.856+01:00
Retrieved odt is equal to original UTC odt: false
Now: 2021-03-26T16:05:12+01:00
Retrieved timestamp instant is equal to original instant: true问题是,数据库中的时间戳保存在我的本地时间,而不是UTC,因为我可以在MYSQL工作台中使用查询进行测试。
另一个奇怪的问题是now()值,你可以看到它应该是过去的1小时,因为数据库是UTC,它被检索为+01:00时间戳,而它应该是UTC。
最后,如果我使用java timestamp类检索时间戳(我知道不应该使用这个类),它会报告与我在方法开始时声明的时刻完全相同的时刻。
Java版本为8,mysql连接器为8.0.23,mysql版本为5.7
发布于 2021-03-27 00:31:58
你的比较是不正确的。2021-03-26T16:05:11.856Z和2021-03-26T17:05:11.856+01:00代表同一时刻。您应该将Instant或OffsetDateTime与相同的Instant进行比较。
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
OffsetDateTime offsetDateTimeUTC = OffsetDateTime.parse("2021-03-26T16:05:11.856Z");
OffsetDateTime retrievedDateTime = OffsetDateTime.parse("2021-03-26T17:05:11.856+01:00");
System.out.println(retrievedDateTime.withOffsetSameInstant(ZoneOffset.UTC).equals(offsetDateTimeUTC));
}
}输出:
true有关更多详细信息,请查看documentation。为了避免获取不同的日期-时间,您应该按照this answer中的说明设置serverTimezone=UTC。
https://stackoverflow.com/questions/66820574
复制相似问题