当前位置: 首页 > 知识库问答 >
问题:

java.sql.timestamp是特定于时区的吗?

闻人嘉悦
2023-03-14

我必须在数据库中存储UTC日期时间。
我已经将特定时区中给出的日期时间转换为UTC。为此,我遵循了下面的代码。
我的输入日期时间是“20121225 10:00:00 Z”时区是“亚洲/加尔各答”
我的服务器/DB(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()));

存入DB

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

输出

DB(oracle)存储了相同的给定datetime:“20121225 10:00:00不是UTC格式。

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

timestamp.tostring()会像java.util.date一样在本地时区打印吗?不是UTC?

共有1个答案

宦炜
2023-03-14

虽然没有为settimestamp(int parameterIndex,Timestamp x)显式指定驱动程序必须遵循settimestamp(int parameterIndex,Timestamp x,Calendar cal)Javadoc建立的规则:

使用给定的Calendar对象将指定参数设置为给定的java.sql.timestamp值。驱动程序使用Calendarhtml" target="_blank">对象构造SQLTimestamp值,然后将该值发送到数据库。使用Calendar对象,驱动程序可以在考虑自定义时区的情况下计算时间戳。如果没有指定Calendar对象,则驱动程序使用默认时区,即运行应用程序的虚拟机的时区。

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

例如:您的本地时区是GMT+2。您存储“世界协调时2012-12-25 10:00:00”。数据库中存储的实际值为“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)与所需时区中的日历实例一起使用。只需确保在检索值时也使用具有相同时区的等效getter(如果在数据库中使用时间戳而没有时区信息)。

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

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

对于JDBC4.2,兼容的驱动程序应该通过get/set/updateobject支持java.time.localdateTime(和java.time.localTime)对timestamp(和time)的支持。java.time.local*类没有时区,因此不需要应用任何转换(尽管如果您的代码假设了特定的时区,这可能会带来一系列新的问题)。

 类似资料:
  • 问题内容: 我必须将UTC dateTime存储在DB中。 我已将特定时区中给定的dateTime转换为UTC。为此,我遵循以下代码。 我输入的日期时间为“ 20121225 10:00:00 Z”,时区为“ Asia / Calcutta”。 我的服务器/数据库(oracle)在同一时区(IST)“ Asia / Calcutta”中运行 获取此特定时区中的Date对象 存入数据库 输出值 DB

  • 问题内容: 如何获取我的python脚本,以检查是否现在使用DST将特定时区存储在变量中?我的服务器设置为UTC。所以我说例如 我想运行有关现在是否正在使用DST的查询,并让返回的结果为true或false。 问题答案: 替代方法是使用: 可以具有以下三个值之一:没有DST,没有DST和未设置时区。

  • 问题内容: 我正在使用JavaScript类,并尝试使用方法获取当前日期。但显然是加载系统日期和时间。我正在从印度运行代码,但我想使用相同的方法来获取英国的日期和时间。我怎样才能做到这一点? 问题答案: 如果您知道UTC偏移量,则可以使用以下函数传递它并获取时间:

  • 我有一个日期。它是如何存储在数据库中的。我正在使用并调用此函数。 在这里,我知道我的

  • 问题内容: 我一直在做一个Android教程,遇到了一个包含以下内容的类: 是一种按类型继承的形式吗?还是我应该了解的其他Java语法? 该类是: 问题答案: 这称为 泛型 。内的类和是一个 类型参数 。 用一个例子最容易解释: 一个可以存储项目。如果您这样指定类型参数:那么此数组列表将仅存储类型的项(换句话说,将仅存储s)! 同样,也通过类型“参数化”。将可能包含一个值,该值将与指定类型的和,而

  • 问题内容: java.sql.Timestamp构造函数如下所示: 它基本上以毫秒为单位接受时间,然后提取最后3位数字并将其设置为毫微秒。因此对于1304135631 421 的毫秒值,我得到的Timestamp.getnanos()为 421000000 。这是简单的计算(最后添加6个零)…似乎不是最佳方法。 更好的方法是Timestamp构造函数,它接受以纳秒为单位的时间,然后从中计算出纳秒值

  • 问题内容: 我正在使用Moment.js解析和格式化Web应用程序中的日期。作为JSON对象的一部分,我的后端服务器以UTC纪元(Unix偏移)为单位发送日期(以毫秒为单位)。 在特定时区中 解析日期很容易-只需在解析前将RFC 822时区标识符附加到字符串的末尾即可: 但是,如何格式化 特定时区中 的日期? 无论浏览器的当前时间如何,我都希望获得一致的结果,但是我不想以UTC显示日期。 问题答案

  • 我只使用javascript(不允许使用任何第三方js),并且我想检索UTC+7格式的当前日期时间,格式如下例如: