java - java.sql.Timestamp 时区是特定的吗?

标签 java oracle date datetime jdbc

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

获取此特定时区中的 Date 对象

        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);
        }

输出

DB (oracle) 存储了相同的 dateTime: "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 那样在本地时区打印吗?不是 UTC?

最佳答案

虽然没有为 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(int parameterIndex, 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(int parameterIndex, 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* 类没有时区,因此不需要应用转换(尽管如果您的代码确实假设了特定时区,这可能会引发一系列新问题)。

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

相关文章:

java - 一段简单代码的时间复杂度

java - 在 Windows 上使用 JPackage 是否可以使 main .exe 不作为控制台运行,但让其他 laucher 作为控制台运行?

java - 启用spring security后静态资源不再可用

sql - Oracle SQL-在 "Distinct"查询中获取 "CASE"值

mysql - 设计具有多种变体产品的数据库的最佳方法是什么?

Java 格式详细的日期差异

java - 自定义 equals() 方法无法正常工作

oracle - Oracle NUMBER的小数位数如何比精度大?

php - 获取特定日期的 SQL 数据

php - 将时间/日期从 XML 文件转换为 MYSQL 格式