在 Oracle 数据库中调用 AT TIME ZONE 函数时时区区域无效
Invalid time zone region while calling AT TIME ZONE function in Oracle database
只是一个关于 Oracle 中的 "AT TIME ZONE" 函数的简单问题。似乎名为 CEST 的时区不是此函数的有效参数,尽管它列在视图 V$TIMEZONE_NAMES
中
select * from V$TIMEZONE_NAMES where tzname like '%Rome%';
TZNAME TZABBREV CON_ID
----------- -------- ------
Europe/Rome LMT 0
Europe/Rome RMT 0
Europe/Rome CET 0
Europe/Rome CEST 0
SQL>
当我尝试将时间戳转换为时区名称 CET 时,一切正常
SELECT TO_TIMESTAMP('2012-MAG-24 02:00:00','RRRR-MON-DD HH24:MI:SS')
AT TIME ZONE 'CET' "CET"
FROM DUAL;
CET
--------------------------------
24-MAG-12 02:00:00,000000000 CET
SQL>
当我将时区更改为 CEST 时,出现此错误:
SELECT TO_TIMESTAMP('2012-MAG-24 02:00:00','RRRR-MON-DD HH24:MI:SS')
AT TIME ZONE 'CEST' "CEST"
FROM DUAL;
ORA-01882: timezone region not found
SQL>
我的问题是:为什么 CEST 时区对此转换无效?
为了清楚起见,我 运行 一个 Oracle 12c 实例
AT TIME ZONE
采用时区 name - 您正在传递时区 abbreviation。这些名称位于您向我们展示的结果的 TZNAME
列中,但您使用的是 TZABBREV
中的值。缩写是个坏主意,因为:
- 它们不是唯一的,因此不能充当标识符。
- 他们只申请了 part 的时间...所以在现代,Europe/Rome 在 CET 和 CEST 之间有所不同,从 table。如果您必须弄清楚哪个缩写在特定时间实际有效,您不妨指定偏移量...
基本上,答案是使用 'Europe/Rome'
而不是 'CET'
。
正如 Jon 所说,您必须使用完整的时区名称而不是缩写,但是,也有一些例外情况,您也可以使用时区缩写,这就是 CET
起作用的原因。
SELECT tzabbrev, tzname, TZ_OFFSET(tzname)
FROM V$TIMEZONE_NAMES tz
WHERE tzabbrev = tzname;
TZABBREV TZNAME TZ_OFFSET(TZNAME)
CET CET +01:00
CST CST -06:00
EET EET +02:00
EST EST -05:00
GMT GMT +00:00
HST HST -10:00
MET MET +01:00
MST MST -07:00
PST PST -08:00
WET WET +00:00
注意。 'Europe/Rome'
与 'CET'
不同。
'Europe/Rome'
自动考虑夏令时,'CET'
不考虑。
只是一个关于 Oracle 中的 "AT TIME ZONE" 函数的简单问题。似乎名为 CEST 的时区不是此函数的有效参数,尽管它列在视图 V$TIMEZONE_NAMES
中select * from V$TIMEZONE_NAMES where tzname like '%Rome%';
TZNAME TZABBREV CON_ID
----------- -------- ------
Europe/Rome LMT 0
Europe/Rome RMT 0
Europe/Rome CET 0
Europe/Rome CEST 0
SQL>
当我尝试将时间戳转换为时区名称 CET 时,一切正常
SELECT TO_TIMESTAMP('2012-MAG-24 02:00:00','RRRR-MON-DD HH24:MI:SS')
AT TIME ZONE 'CET' "CET"
FROM DUAL;
CET
--------------------------------
24-MAG-12 02:00:00,000000000 CET
SQL>
当我将时区更改为 CEST 时,出现此错误:
SELECT TO_TIMESTAMP('2012-MAG-24 02:00:00','RRRR-MON-DD HH24:MI:SS')
AT TIME ZONE 'CEST' "CEST"
FROM DUAL;
ORA-01882: timezone region not found
SQL>
我的问题是:为什么 CEST 时区对此转换无效?
为了清楚起见,我 运行 一个 Oracle 12c 实例
AT TIME ZONE
采用时区 name - 您正在传递时区 abbreviation。这些名称位于您向我们展示的结果的 TZNAME
列中,但您使用的是 TZABBREV
中的值。缩写是个坏主意,因为:
- 它们不是唯一的,因此不能充当标识符。
- 他们只申请了 part 的时间...所以在现代,Europe/Rome 在 CET 和 CEST 之间有所不同,从 table。如果您必须弄清楚哪个缩写在特定时间实际有效,您不妨指定偏移量...
基本上,答案是使用 'Europe/Rome'
而不是 'CET'
。
正如 Jon 所说,您必须使用完整的时区名称而不是缩写,但是,也有一些例外情况,您也可以使用时区缩写,这就是 CET
起作用的原因。
SELECT tzabbrev, tzname, TZ_OFFSET(tzname)
FROM V$TIMEZONE_NAMES tz
WHERE tzabbrev = tzname;
TZABBREV TZNAME TZ_OFFSET(TZNAME)
CET CET +01:00
CST CST -06:00
EET EET +02:00
EST EST -05:00
GMT GMT +00:00
HST HST -10:00
MET MET +01:00
MST MST -07:00
PST PST -08:00
WET WET +00:00
注意。 'Europe/Rome'
与 'CET'
不同。
'Europe/Rome'
自动考虑夏令时,'CET'
不考虑。