有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从Oracle获取时区ID而不是时区偏移量

有没有办法从oracle获取时区id而不是时区偏移量? 当我执行SELECT SYSTIMESTAMP AS TIMEZONE FROM DUAL;时,返回的结果是13-JAN-21 10.19.52.936031000 AM +05:30

当我使用rs.getObject( "TIMEZONE ", ZonedDateTime.class )从Java检索这个时,ZonedDateTime对象将offsetzoneID设置为+05:30

但是我希望看到的是,SELECT SYSTIMESTAMP AS TIMEZONE FROM DUAL;应该返回04-JAN-21 02.40.50.000000000 PM ASIA/COLOMBO,查询的Java ZonedDateTime应该将offset设置为+05:30,将zoneID设置为Asia/Colombo

有没有一种方法可以在DB级或Java级进行设置?当前DBTIMEZONE设置为+05:30


共 (6) 个答案

  1. # 1 楼答案

    如果数据已经在Oracle SQL表中,并且必须转换为带时区的时间戳(例如,在同一表中创建的新列中),则不需要显式转到操作系统,也不需要使用Java或Oracle数据库本身以外的任何其他东西

    您的问题不清楚您是否必须假定“日期”在服务器时区(您提到的“数据库”通常指服务器)或客户端时区(您提到的“会话”指客户端)。无论哪种方式:

    update <your_table>
    set <timestamp_with_time_zone_col> = 
                from_tz(cast<date_col> as timestamp, dbtimezone)
    ;
    

    或者使用sessiontimezone作为第二个参数,如果您需要的话

    这假设数据库(和/或会话)时区分别在数据库和客户机中正确设置。如果不是/他们不是,那需要先解决。如果参数一开始设置正确,Oracle完全能够处理白天节省的时间。(如果不是这样,我们也不清楚为什么要尝试让自己的操作比数据库一开始支持的操作“更正确”)

    示例:在下面的WITH子句中,我模拟了一个数据类型为date的表,其中有一列dt。然后我将其转换为一个带有时区的时间戳,在会话的(客户端)时区中

    with
      my_table ( dt ) as ( 
        select to_date('2018-06-20 14:30:00', 'yyyy-mm-dd hh24:mi:ss') from dual 
      )
    select dt,
           from_tz(cast(dt as timestamp), sessiontimezone) as ts_with_tz
    from   my_table
    ;
    
    DT                  TS_WITH_TZ                                       
    ------------------- -------------------------------------------------
    2018-06-20 14:30:00 2018-06-20 14:30:00.000000000 AMERICA/LOS_ANGELES
    

    为了便于参考,您可以查看此链接 StackOverflow Ref. Link

  2. # 2 楼答案

    SYSTIMESTAMP在数据库操作系统的时区中返回-因此无法在数据库中更改它

    不要将数据库操作系统的时区与DBTIMEZONE混用,它们是不同的

    还要注意,时区Asia/Colombo与时区+05:30不同,尽管它们(当前)具有相同的UTC偏移量

    时区Asia/Colombo考虑了夏令时的适用情况,它还包括changes。例如Asia/Colombo在2006年从UTC+06:00更改为UTC+05:30。例如,因此TZ_OFFSET(TIMESTAMP '2020-01-01 12:00:00 Asia/Colombo')返回的偏移量与TZ_OFFSET(TIMESTAMP '2000-01-01 12:00:00 Asia/Colombo')不同

    时区+05:30总是UTC前5:30

    你的问题不是很清楚,你想得到什么

  3. # 3 楼答案

    Oracle TZ_OFFSET()函数返回有效时区名称或SESSIONTIMEZONE或DBTIMEZONE函数名称相对于UTC的时区偏移量

    TZ_OFFSET(value)
    

    TZ_OFFSET()函数接受一个参数,该参数可以是有效的时区名称,例如“Europe/London”、SESSIONTIMEZONE或DBTIMEZONE的函数名,或者UTC的时区偏移量(它只返回自身)

    SELECT
      TZ_OFFSET( 'Europe/London' )
    FROM
      DUAL;
    

    结果将是+01:00

  4. # 4 楼答案

    这就是你如何获得时区的方法

    SELECT systimestamp AS DBTime,
           systimestamp at time zone 'Europe/London',
           systimestamp at time zone 'America/Sao_Paulo'from dual;
    

    SELECT
      TZ_OFFSET( DBTIMEZONE )
    FROM
      DUAL;
    
  5. # 5 楼答案

    从某种意义上说,你运气不好SYSTIMESTAMP只返回操作系统报告的内容。时区是承载数据库的计算机系统的时区。它不是数据库时区(可能与数据库实际驻留的位置完全无关)或会话时区或诸如此类的东西。如果可以,您需要在db主机操作系统本身中进行更改

    如果您确信托管您的数据库的系统位于斯里兰卡,那么您可以通过以下方式间接获得您想要的:

    select systimestamp AT TIME ZONE 'ASIA/COLOMBO' from dual;
    
  6. # 6 楼答案

    您可以使用ALTER database命令在数据库级别设置时区,如下所示:

    alter database set time_zone = '+05:30';
    

    请注意,这将在重新启动数据库后生效

    shutdown immediate
    startup