Java OffsetDateTime<-&燃气轮机;MYSQL时间戳问题

Java OffsetDateTime<-&燃气轮机;MYSQL时间戳问题,java,mysql,jdbc,Java,Mysql,Jdbc,我在处理与MYSQL时间戳之间的OffsetDateTime转换时遇到了一些问题。 我的JVM时区是GMT+1,我的数据库时区是UTC,我可以确认这是因为now()返回过去1小时的时间戳 这是我的密码: 公共类TestDBTime{ 公共静态void main(字符串[]args)引发SQLException、InterruptedException{ testOffsetDateTime(); } 私有静态void testOffsetDateTime()引发SQLException{ Con

我在处理与MYSQL时间戳之间的OffsetDateTime转换时遇到了一些问题。 我的JVM时区是GMT+1,我的数据库时区是UTC,我可以确认这是因为now()返回过去1小时的时间戳

这是我的密码:

公共类TestDBTime{
公共静态void main(字符串[]args)引发SQLException、InterruptedException{
testOffsetDateTime();
}
私有静态void testOffsetDateTime()引发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(“来自即时的默认偏移日期时间:+offsetDateTime.toString());
OffsetDateTime offsetDateTimeUTC=instant.atOffset(ZoneOffset.UTC);
System.out.println(“UTC…从瞬间开始的偏移日期时间:+offsetDateTimeUTC.toString());
String update=“更新计划集时间戳=?其中id=1”;
try(PreparedStatement PreparedStatement=connection.preparest陈述(更新)){
preparedStatement.setObject(1,offsetDateTimeUTC);
preparedStatement.executeUpdate();
}
String query=“从id=1的计划s中选择s.*,现在()作为现在”;
try(PreparedStatement PreparedStatement=connection.prepareStatement(查询)){
ResultSet ResultSet=preparedStatement.executeQuery();
resultSet.next();
OffsetDateTime retrievedDateTime=resultSet.getObject(“时间戳”,OffsetDateTime.class);
System.out.println(“检索到的偏移日期时间:“+retrievedDateTime”);
System.out.println(“检索到的odt等于原始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(“检索到的时间戳瞬间等于原始瞬间:”+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小时,因为db是UTC,所以它应该是1小时,它被检索为+01:00时间戳,而它应该是UTC。
最后,如果我使用java timestamp类(我知道不应该使用它)检索时间戳,则报告的瞬间与我在方法开始时声明的瞬间完全相同


Java版本是8,mysql连接器是8.0.23,mysql版本是5.7。您的比较不正确
2021-03-26T16:05:11.856Z和
2021-03-26T17:05:11.856+01:00表示相同的瞬间。您应该将
即时
s或
OffsetDateTime
s与相同的
即时
进行比较,例如:

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

有关它的更多详细信息,请查看。为了避免获得不同的日期时间,您应该按照中所述设置
serverTimezone=UTC

您的比较不正确
2021-03-26T16:05:11.856Z和
2021-03-26T17:05:11.856+01:00表示相同的瞬间。您应该将
即时
s或
OffsetDateTime
s与相同的
即时
进行比较,例如:

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

有关它的更多详细信息,请查看。为了避免获得不同的日期时间,您应该设置
serverTimezone=UTC
,如中所述。

url字符串是什么样子的?url是“jdbc:mysql://domain.mysql.database.azure.com:3306/schema?useSSL=true&requireSSL=false"尝试添加另一个参数
serverTimezone=UTC
,该参数有助于将UTC odt作为UTC时间戳存储在数据库中,现在()也作为UTC odt进行检索。但我忍不住觉得这是一个创可贴/黑客解决方案。db已经具有UTC时区属性,为什么我还必须在url中明确指定它?您的意思是这是为您的服务器设置的?如果设置了,那么它应该工作,否则它将选择系统时区。url字符串是什么样子的?url是“jdbc:mysql://domain.mysql.database.azure.com:3306/schema?useSSL=true&requireSSL=false"尝试添加另一个参数
serverTimezone=UTC
,该参数有助于将UTC odt作为UTC时间戳存储在数据库中,现在()也作为UTC odt进行检索。但我忍不住觉得这是一个创可贴/黑客解决方案。db已经具有UTC时区属性,为什么我还必须在url中明确指定它?您的意思是这是为您的服务器设置的?如果设置了,那么它应该工作,否则它会选择系统时区。我不想测试它们是否具有相同的基本瞬间,我的观点是显示这两个对象具有不同的时区和时间。因为我的问题是UTC odt在dbI上存储为gmt+1,我没有尝试测试它们是否具有相同的基本瞬间,我的观点是显示这两个对象具有不同的时区和时间。因为我的问题是UTC odt在db上存储为gmt+1