代码之家  ›  专栏  ›  技术社区  ›  Tristan

更改DST规则后,从UTC日期时间检索历史本地日期时间

  •  1
  • Tristan  · 技术社区  · 6 年前

    假设我使用的是oraclesgbd(RDBMS)和java8。

    我的历史日期时间存储在UTC时区,但我的应用程序只显示本地日期时间,我的统计计算也只适用于本地日期时间。

    as is planned .

    到目前为止,我读到的是两者都有与DST规则相关的时区 Oracle Java ,但它们不会自动更新。此外,我想做的是保留更改前后的规则,而不仅仅是更新规则,因为我需要历史数据,所以我需要“更改前的欧洲/巴黎”时区和“更改后的欧洲/巴黎”时区,或者更好的是与规则历史相关联的时区,根据需要应用它们自己。

    而且,即使在Java中有一些方便的方法可以做到这一点,它也应该在Oracle中修复,以涵盖所有用例。

    DST开始(向前时钟)—>DST结束(时钟向后)
    1953年迪曼奇26艾薇儿,02 h 00->迪曼奇27 septembre,02小时00分

    1955迪曼奇24艾薇儿,02 h 00->迪曼奇10月30日,02时00分
    1956迪曼奇29艾薇儿,02 h 00->迪曼奇10月28日,02时00分

    IANA historical timezone database ,但如果您已经这样做了,请说明如何在oraclesgbd和Java中实际使用它。

    附言:我们也欢迎您在未来的数据库中提供任何关于如何比“UTC”更好地处理这个问题的建议。

    2 回复  |  直到 6 年前
        1
  •  4
  •   Alex Poole    6 年前

    Java或Oracle将自动为任何UTC日期应用正确的规则—当然,只要您拥有最新的时区数据文件。

    既然您询问了Oracle(SGBD/RDBMS)方法并提到了Chicago,那么生成时钟在不同规则下更改的示例日期就相当简单了,并且可以看到更改应用于正确的日期(与添加到问题中的示例规则更改相比较,以及 https://www.timeanddate.com/time/zone/usa/chicago ).

    alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZH:TZM';
    
    with t (utc) as (
                select timestamp '1954-04-25 07:59:59 UTC' from dual
      union all select timestamp '1954-04-25 08:00:00 UTC' from dual
      union all select timestamp '1954-09-26 06:59:59 UTC' from dual
      union all select timestamp '1954-09-27 07:00:00 UTC' from dual
      --
      union all select timestamp '1955-04-24 07:59:59 UTC' from dual
      union all select timestamp '1955-04-24 08:00:00 UTC' from dual
      union all select timestamp '1955-10-30 06:59:59 UTC' from dual
      union all select timestamp '1955-10-30 07:00:00 UTC' from dual
      --
      union all select timestamp '1974-01-06 07:59:59 UTC' from dual
      union all select timestamp '1974-01-06 08:00:00 UTC' from dual
      union all select timestamp '1974-10-27 06:59:59 UTC' from dual
      union all select timestamp '1974-10-27 07:00:00 UTC' from dual
      --
      union all select timestamp '1975-02-23 07:59:59 UTC' from dual
      union all select timestamp '1975-02-23 08:00:00 UTC' from dual
      union all select timestamp '1975-10-26 06:59:59 UTC' from dual
      union all select timestamp '1975-10-26 07:00:00 UTC' from dual
      --
      union all select timestamp '1987-04-05 07:59:59 UTC' from dual
      union all select timestamp '1987-04-05 08:00:00 UTC' from dual
      union all select timestamp '1987-10-25 06:59:59 UTC' from dual
      union all select timestamp '1987-10-25 07:00:00 UTC' from dual
      --
      union all select timestamp '2007-03-11 07:59:59 UTC' from dual
      union all select timestamp '2007-03-11 08:00:00 UTC' from dual
      union all select timestamp '2007-11-04 06:59:59 UTC' from dual
      union all select timestamp '2007-11-04 07:00:00 UTC' from dual
    )
    select utc,
      utc at time zone 'America/Chicago' as chicago
    from t;
    

    这给了你:

    UTC                        CHICAGO                   
    -------------------------- --------------------------
    1954-04-25 07:59:59 +00:00 1954-04-25 01:59:59 -06:00
    1954-04-25 08:00:00 +00:00 1954-04-25 03:00:00 -05:00
    1954-09-26 06:59:59 +00:00 1954-09-26 01:59:59 -05:00
    1954-09-27 07:00:00 +00:00 1954-09-27 01:00:00 -06:00
    1955-04-24 07:59:59 +00:00 1955-04-24 01:59:59 -06:00
    1955-04-24 08:00:00 +00:00 1955-04-24 03:00:00 -05:00
    1955-10-30 06:59:59 +00:00 1955-10-30 01:59:59 -05:00
    1955-10-30 07:00:00 +00:00 1955-10-30 01:00:00 -06:00
    1974-01-06 07:59:59 +00:00 1974-01-06 01:59:59 -06:00
    1974-01-06 08:00:00 +00:00 1974-01-06 03:00:00 -05:00
    1974-10-27 06:59:59 +00:00 1974-10-27 01:59:59 -05:00
    1974-10-27 07:00:00 +00:00 1974-10-27 01:00:00 -06:00
    1975-02-23 07:59:59 +00:00 1975-02-23 01:59:59 -06:00
    1975-02-23 08:00:00 +00:00 1975-02-23 03:00:00 -05:00
    1975-10-26 06:59:59 +00:00 1975-10-26 01:59:59 -05:00
    1975-10-26 07:00:00 +00:00 1975-10-26 01:00:00 -06:00
    1987-04-05 07:59:59 +00:00 1987-04-05 01:59:59 -06:00
    1987-04-05 08:00:00 +00:00 1987-04-05 03:00:00 -05:00
    1987-10-25 06:59:59 +00:00 1987-10-25 01:59:59 -05:00
    1987-10-25 07:00:00 +00:00 1987-10-25 01:00:00 -06:00
    2007-03-11 07:59:59 +00:00 2007-03-11 01:59:59 -06:00
    2007-03-11 08:00:00 +00:00 2007-03-11 03:00:00 -05:00
    2007-11-04 06:59:59 +00:00 2007-11-04 01:59:59 -05:00
    2007-11-04 07:00:00 +00:00 2007-11-04 01:00:00 -06:00
    

    v$timezone_file 查看,或在最新版本中 database_properties

    您可以在中阅读有关Oracle时区文件版本和修补程序的更多信息 Oracle Support Document 412160.1 (Updated DST Transitions and New Time Zones in Oracle RDBMS and OJVM Time Zone File Patches) .

    特别是,请参阅第J节“RDBMS DST更新中更新时区的列表”,其中指出:

    所有时区文件更新都是累积的,这意味着较新的RDBMS DST修补程序具有以前更新的所有更改。
    ...
    在下面的列表中,列出了在时区文件版本中更新的时区。还列出了该时区的时区规则更改的第一年和最后一年(如果适用)。

    所以它显示历史日期也包括在内。

        2
  •  2
  •   Tristan    6 年前

    https://www.oracle.com/technetwork/java/javase/tzdata-versions-138805.html :

    Java开发工具包(JDK)软件和 TZUpdater工具。有关时区内容的详细信息 数据发布包含在相关的增强请求中 (RFE)发布。发生重大时区变化的地方 列。

    IANA TZdata page .

    如果您想在javase中获得时区数据更新的信息

    因此,基本上如果您一直需要最新的时区数据,可以使用 TZUpdater tool

    Oracle/Java将应用UTC日期生效的适当规则 你正试图转换到一个特定的时区。你不需要这么做 显式地做任何事情-您只需要最新版本的