gpt4 book ai didi

Java MySQL Timestamp时区问题

转载 作者:可可西里 更新时间:2023-11-01 06:35:50 25 4
gpt4 key购买 nike

我有一个 java.util.Date 对象,我需要将它以 UTC 格式插入到 MySQL 的日期时间字段中。

java.util.Date date = myDateFromSomewhereElse;
PreparedStatement prep = con.prepareStatement(
"INSERT INTO table (t1, t2) VALUES (?,?)");

java.sql.Timestamp t = new Timestamp(date.getTime());
prep.setTimestamp(1, t, Calendar.getInstance(TimeZone.getTimeZone("PST"));
prep.setTimestamp(2, t, Calendar.getInstance(TimeZone.getTimeZone("UTC"));
System.out.println(prep.toString());

这给了我准备好的 SQL 语句字符串:

INSERT INTO table (t1, t2) VALUES ('2012-05-09 11:37:08','2012-05-09 11:37:08');

无论我指定的时区如何,返回的时间戳都是相同的时间戳。它忽略了我指定的具有时区的日历对象。这是怎么回事,我做错了什么?

最佳答案

Jordan,实际上你的想法是对的。问题是 MySQL JDBC 驱动程序中存在错误,默认情况下完全忽略日历参数。查看 PreparedStatement 的源代码,真正了解发生了什么。

注意它使用 JVM 的时区来格式化时间戳。这仅在您的 JVM 使用 UTC 时区时有效。 Calendar 对象被完全忽略。

this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''", Locale.US);
timestampString = this.tsdf.format(x);

为了让 MySQL 使用 Calendar 参数,您必须使用以下连接选项禁用旧的日期/时间代码:

useLegacyDatetimeCode=false

所以你可能会像这样连接到数据库时使用它:

String url = "jdbc:mysql://localhost/tz?useLegacyDatetimeCode=false"

如果您使用上面的行禁用旧的日期时间代码,那么它将在目标日历的时区中呈现您的时间戳:

if (targetCalendar != null) {
targetCalendar.setTime(x);
this.tsdf.setTimeZone(targetCalendar.getTimeZone());

timestampString = this.tsdf.format(x);
} else {
this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
timestampString = this.tsdf.format(x);
}

很容易看出这里发生了什么。如果您传入一个 Calendar 对象,它将在格式化数据时使用它。否则,它将使用数据库的时区来格式化数据。奇怪的是,如果你传入一个 Calendar,它还会将时间设置为给定的 Timestamp 值(这似乎毫无意义)。

关于Java MySQL Timestamp时区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10522267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com