Oracle中是否有一种平滑的方法来获取当前时刻(执行调用时)SESSIONTIMEZONE和DBTIMEZONE之间的数值差异?

例如:

SELECT SESSIONTIMEZONE, DBTIMEZONE FROM DUAL;

返回值:
+04:00  +07:00

因此,我需要某种函数,通过使用给定参数调用该函数,可以得到这两个值之间的差异。

对于上述实例:
SELECT get_numeric_offset(SESSIONTIMEZONE, DBTIMEZONE) FROM DUAL;

将返回-3(该符号至关重要)。

当然,我可以自己编写该函数,方法是使用字符串并对其进行解析,然后进行一些算术运算或执行类似的操作(我仍然认为这不是一个非常平滑的解决方案:
SELECT (
        CAST(SYSTIMESTAMP AT TIME ZONE SESSIONTIMEZONE AS DATE) -
        CAST(SYSTIMESTAMP AT TIME ZONE DBTIMEZONE AS DATE)
       )*24
 FROM DUAL;

也许我错过了一些东西,而Oracle实际上提供了一种方法来计算两个给定时区之间的差异?

最佳答案

有关使用SESSIONTIMEZONE的一些警告

您的第一个示例不是防弹的,因为可以将 session 时区设置为以下任意一个:

  • 操作系统本地时区('OS_TZ')
  • 数据库时区('DB_TZ')
  • 与UTC的绝对偏移量(例如'-05:00')
  • 时区区域名称(例如'Europe/London')

  • 看看这里发生了什么:
    SELECT SESSIONTIMEZONE, DBTIMEZONE FROM DUAL;
    
    SESSIONTIMEZONE  |  DBTIMEZONE
             +04:00  |      +07:00
    
    ALTER SESSION SET TIME_ZONE='Europe/Paris';
    
    SELECT SESSIONTIMEZONE, DBTIMEZONE FROM DUAL;
    
    SESSIONTIMEZONE  |  DBTIMEZONE
       Europe/Paris  |      +07:00
    

    在您的函数中解析“Europe/Paris”字符串将变得更加困难...您应该使用TZ_OFFSET函数,以确保始终获得相同的±HH:MM格式。
    ALTER SESSION SET TIME_ZONE='Europe/Paris';
    
    SELECT DBTIMEZONE, SESSIONTIMEZONE, TZ_OFFSET(SESSIONTIMEZONE) FROM DUAL;
    
     DBTIMEZONE | SESSIONTIMEZONE | TZ_OFFSET(SESSIONTIMEZONE)
         +07:00 |    Europe/Paris |                     +02:00
    

    关于第二个解决方案

    我想我更喜欢您的第二个解决方案。您可以通过使用CURRENT_DATE而不是CAST(SYSTIMESTAMP AT TIME ZONE SESSIONTIMEZONE AS DATE)来缩短它,它们是等效的:
    SELECT (
            CURRENT_DATE -
            CAST(SYSTIMESTAMP AT TIME ZONE DBTIMEZONE AS DATE)
           )*24
     FROM DUAL;
    

    从技术上讲,您甚至可以这样做!
    SELECT (CURRENT_DATE - SYSDATE) * 24
     FROM DUAL;
    

    但实际上不能保证SYSDATEDBTIMEZONE处于同一时区。 SYSDATE始终绑定(bind)到底层操作系统的时区,而一旦服务器启动,就可以更改DBTIMEZONE

    而且,当我在割头发时,我还应该提醒您,某些国家/地区使用的偏移量不是整数,例如,伊朗标准时间是UTC+03:30,缅甸时间是UTC+06:30……我不知道您是否会曾经在您的生产环境中遇到过这种情况,但我希望您可以接受查询返回1.5之类的信息的可能性。

    关于oracle - 如何获得DBTIMEZONE和SESSIONTIMEZONE之间的数值差异?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18072549/

    10-10 11:43