gpt4 book ai didi

java - java.sql.Timestamp 时区是否特定?

转载 作者:行者123 更新时间:2023-12-01 16:20:34 27 4
gpt4 key购买 nike

我必须将 UTC 日期时间存储在数据库中。
我已将特定时区中给出的日期时间转换为 UTC。为此,我遵循了以下代码。
我输入的日期时间是“20121225 10:00:00 Z”时区是“亚洲/加尔各答”
我的服务器/数据库(oracle)在同一时区(IST)“亚洲/加尔各答”运行

获取该特定时区的日期对象

        String date = "20121225 10:00:00 Z";
String timeZoneId = "Asia/Calcutta";
TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);

DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss z");
//This date object is given time and given timezone
java.util.Date parsedDate = dateFormatLocal.parse(date + " "
+ timeZone.getDisplayName(false, TimeZone.SHORT));

if (timeZone.inDaylightTime(parsedDate)) {
// We need to re-parse because we don't know if the date
// is DST until it is parsed...
parsedDate = dateFormatLocal.parse(date + " "
+ timeZone.getDisplayName(true, TimeZone.SHORT));
}

//assigning to the java.sql.TimeStamp instace variable
obj.setTsSchedStartTime(new java.sql.Timestamp(parsedDate.getTime()));

存储到数据库

        if (tsSchedStartTime != null) {
stmt.setTimestamp(11, tsSchedStartTime);
} else {
stmt.setNull(11, java.sql.Types.DATE);
}

输出

数据库(oracle)已存储相同的给定日期时间:“20121225 10:00:00,而不是UTC。

我已经从下面的sql中确认了。

     select to_char(sched_start_time, 'yyyy/mm/dd hh24:mi:ss') from myTable

我的数据库服务器也在同一时区“亚洲/加尔各答”上运行

它给了我以下外观

  1. Date.getTime() 不是 UTC
  2. 或者时间戳在存储到数据库时会受到时区影响我在这里做错了什么?

还有一个问题:

timeStamp.toString() 会像 java.util.date 那样以本地时区打印吗?不是世界标准时间?

最佳答案

虽然没有明确指定 setTimestamp(int parameterIndex, Timestamp x) 驱动程序必须遵循 setTimestamp(int parameterIndex, Timestamp x, Calendar cal) javadoc 建立的规则:

Sets the designated parameter to the given java.sql.Timestamp value, using the given Calendar object. The driver uses the Calendar object to construct an SQL TIMESTAMP value, which the driver then sends to the database. With a Calendar object, the driver can calculate the timestamp taking into account a custom time zone. If no Calendar object is specified, the driver uses the default time zone, which is that of the virtual machine running the application.

当您使用 setTimestamp(intparameterIndex, Timestamp x) 调用时,JDBC 驱动程序使用虚拟机的时区来计算该时区中时间戳的日期和时间。该日期和时间是存储在数据库中的内容,如果数据库列不存储时区信息,则有关该区域的任何信息都会丢失(这意味着使用该数据库的应用程序将使用该日期和时间)一致地使用相同的时区,或者提出另一种方案来识别时区(即存储在单独的列中)。

例如:您的本地时区是 GMT+2。您存储“2012-12-25 10:00:00 UTC”。数据库中存储的实际值为“2012-12-25 12:00:00”。您再次检索它:您再次检索它为“2012-12-25 10:00:00 UTC”(但前提是您使用 getTimestamp(..) 检索它),但当另一个应用程序时访问GMT+0时区的数据库,它将检索时间戳为“2012-12-25 12:00:00 UTC”。

如果您想将其存储在不同的时区,则需要将 setTimestamp(intparameterIndex, Timestamp x, Calendar cal) 与所需时区的 Calendar 实例结合使用。只需确保在检索值时也使用具有相同时区的等效 getter(如果您使用数据库中没有时区信息的 TIMESTAMP)。

因此,假设您想存储实际的 GMT 时区,您需要使用:

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
stmt.setTimestamp(11, tsSchedStartTime, cal);

对于 JDBC 4.2,兼容的驱动程序应支持 java.time.LocalDateTime(和 java.time.LocalTime)的 TIMESTAMP(以及 TIME) 通过 get/set/updateObjectjava.time.Local* 类没有时区,因此不需要应用转换(尽管如果您的代码确实假设了特定时区,这可能会带来一系列新问题)。

即:

  • getDate(..) 替换为 getObject(.., LocalDate.class)
  • setDate(.., dateValue) 替换为 setObject(.., localDateValue)
  • getTime(..) 替换为 getObject(.., LocalTime.class)
  • setTime(.., timeValue) 替换为 setObject(.., localTimeValue)
  • getTimestamp(..) 替换为 getObject(.., LocalDateTime.class)
  • setTimestamp(.., timestampValue) 替换为 setObject(.., localDateTimeValue)

关于java - java.sql.Timestamp 时区是否特定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62296586/

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