在 sqlplus 与 sql developer 中运行时,Oracle 时区偏移量不同

这是一个谜题。取以下查询并在oracle sqldeveloper中执行:

select to_char(CAST (sysdate AS  TIMESTAMP WITH TIME ZONE),'TZH:TZM') dst,to_char(CAST (sysdate-160 AS  TIMESTAMP WITH TIME ZONE),'TZH:TZM') nodst    
 from dual;

你会得到“-04:00”、“-05:00”的结果。这给出了正确的 dst 调整时区偏移量(东部),一个日期在 dst 中,另一个没有。从 sqlplus 运行相同的查询将两个值都设为“-4:00”。这会导致从 sqlplus 调用时也显示错误值的包出现问题。

iCMS 回答:在 sqlplus 与 sql developer 中运行时,Oracle 时区偏移量不同

当您转换为带时区的时间戳时,Oracle 必须选择使用哪个时区;它使用当前会话时区。相当于做:

select to_char(FROM_TZ(CAST (sysdate AS  TIMESTAMP),SESSIONTIMEZONE),'TZH:TZM') dst,to_char(FROM_TZ(CAST(sysdate-160 AS  TIMESTAMP),'TZH:TZM') nodst    
 from dual;

当您在 SQL Developer 和 SQL*Plus 中得到不同的结果时,您在这两个客户端中的会话时区似乎不同。您可以通过在每个中查询 sessiontimezone 来检查。 SQL Developer 根据 Java 时区设置会话时区(默认情况下从操作系统获取;您可以通过 passing a user.timezone value at start-up 覆盖它)。 SQL*Plus uses the ORA_SDTZ environment variable,因此如果您不想使用 alter session(手动或通过 login.sql)从数据库中设置它,您可以将其设置为与您的语言环境相匹配;如果未设置,则默认为“OS_TZ”:

ORA_SDTZ 变量的默认值为 'OS_TZ',当变量未设置或设置为无效值时使用。

... 并将其作为偏移量 (-04:00) 而不是一个区域。

如果无论任何用户的会话设置如何,您始终希望结果位于特定时区,那么您可以说明要使用哪个时区,例如:

select to_char(FROM_TZ(CAST (sysdate AS  TIMESTAMP),'America/New_York'),'TZH:TZM') nodst    
 from dual;

db<>fiddle 带有几个会话设置来演示。

大概您的真实查询是从可变日期值开始工作的,而不是 sysdate;否则,您可以改用 systimestamp,必要时使用 at time zone 调整到不同的区域。

,

这给出了正确的 dst 调整时区偏移量(东部),一个日期在 dst 中,另一个没有。

不,它会为您提供一个看似正确的手动调整值;但是,当 DST 结束时,您的查询将不正确,需要调整……然后明年春天需要再次调整……明年秋天。

如果您想要正确的值,那么让 Oracle 调整时区(并且您不需要将 SYSDATE 强制转换为 TIMESTAMP WITH TIME ZONE,您可以只使用 SYSTIMESTAMP 或 {{ 1}}):

CURRENT_TIMESTAMP
本文链接:https://www.f2er.com/101237.html

大家都在问