Sql Oracle数据库中DST更改的时间似乎是凌晨1点,而不是凌晨2点
我试图在Oracle中将UTC时间转换为BST时间-但是,Oracle中的数据更改时间似乎是凌晨1点而不是凌晨2点。或者我在这里错过了什么?我使用以下代码来说明和测试该问题:Sql Oracle数据库中DST更改的时间似乎是凌晨1点,而不是凌晨2点,sql,oracle,Sql,Oracle,我试图在Oracle中将UTC时间转换为BST时间-但是,Oracle中的数据更改时间似乎是凌晨1点而不是凌晨2点。或者我在这里错过了什么?我使用以下代码来说明和测试该问题: WITH time1 AS (select cast('2020-03-29 01:00:00 UTC' ASTIMESTAMP WITH TIME ZONE) AS UTC_time FROM dual) SELECT UTC_time, (UTC_time AT TIME ZONE 'Europe/London') A
WITH time1 AS (select cast('2020-03-29 01:00:00 UTC' ASTIMESTAMP WITH TIME ZONE) AS UTC_time FROM dual)
SELECT UTC_time, (UTC_time AT TIME ZONE 'Europe/London') AS bst FROM time1
在协调世界时1:00:00,英国夏令时时间是2:00:00-应该是1:00:00,Oracle是对的,您的期望似乎是错误的。您可以看到欧洲/伦敦DST的变化 在欧洲/伦敦有以下内容:
# See EU for rules starting in 1996.
...
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/London -0:01:15 - LMT 1847 Dec 1 0:00s
0:00 GB-Eire %s 1968 Oct 27
1:00 - BST 1971 Oct 31 2:00u
0:00 GB-Eire %s 1996
0:00 EU GMT/BST
因此,自1996年以来,英国一直遵循欧盟规则,即:
# Europe
# The following rules are for the European Union and for its
# predecessor organization, the European Communities.
# For brevity they are called "EU rules" elsewhere in this file.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
Rule EU 1977 only - Sep lastSun 1:00u 0 -
Rule EU 1978 only - Oct 1 1:00u 0 -
Rule EU 1979 1995 - Sep lastSun 1:00u 0 -
Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
Rule EU 1996 max - Oct lastSun 1:00u 0 -
所以。。。在英国(以及欧盟其他国家),DST从3月的最后一个星期日起在协调世界时01:00应用,明年是2020-03-29协调世界时01:00:00。它将在DST上持续到10月的最后一个星期日协调世界时01:00,即明年的协调世界时2020-10-25 01:00:00
Oracle遵循这些规则:
with time1 (utc_time) as (
select timestamp '2020-03-29 00:00:00.000 UTC' FROM dual
union all select timestamp '2020-03-29 00:59:59.999 UTC' FROM dual
union all select timestamp '2020-03-29 01:00:00.000 UTC' FROM dual
union all select timestamp '2020-03-29 01:59:59.999 UTC' FROM dual
union all select timestamp '2020-03-29 02:00:00.000 UTC' FROM dual
--
union all select timestamp '2020-10-25 00:00:00.000 UTC' FROM dual
union all select timestamp '2020-10-25 00:59:59.999 UTC' FROM dual
union all select timestamp '2020-10-25 01:00:00.000 UTC' FROM dual
union all select timestamp '2020-10-25 01:59:59.999 UTC' FROM dual
union all select timestamp '2020-10-25 02:00:00.000 UTC' FROM dual
)
select utc_time,
utc_time at time zone 'Europe/London' as london_time,
to_char(utc_time at time zone 'Europe/London', 'TZD') as "DST?"
from time1
order by utc_time;
UTC_TIME LONDON_TIME DST?
--------------------------------- ------------------------------------------- ------
2020-03-29 00:00:00.000000000 UTC 2020-03-29 00:00:00.000000000 EUROPE/LONDON GMT
2020-03-29 00:59:59.999000000 UTC 2020-03-29 00:59:59.999000000 EUROPE/LONDON GMT
2020-03-29 01:00:00.000000000 UTC 2020-03-29 02:00:00.000000000 EUROPE/LONDON BST
2020-03-29 01:59:59.999000000 UTC 2020-03-29 02:59:59.999000000 EUROPE/LONDON BST
2020-03-29 02:00:00.000000000 UTC 2020-03-29 03:00:00.000000000 EUROPE/LONDON BST
2020-10-25 00:00:00.000000000 UTC 2020-10-25 01:00:00.000000000 EUROPE/LONDON BST
2020-10-25 00:59:59.999000000 UTC 2020-10-25 01:59:59.999000000 EUROPE/LONDON BST
2020-10-25 01:00:00.000000000 UTC 2020-10-25 01:00:00.000000000 EUROPE/LONDON GMT
2020-10-25 01:59:59.999000000 UTC 2020-10-25 01:59:59.999000000 EUROPE/LONDON GMT
2020-10-25 02:00:00.000000000 UTC 2020-10-25 02:00:00.000000000 EUROPE/LONDON GMT
在中欧,DST适用于同一UTC时间,但当地时间当然不同:
with time1 (utc_time) as (
...
)
select utc_time,
utc_time at time zone 'Europe/Paris' as paris_time,
to_char(utc_time at time zone 'Europe/Paris', 'TZD') as "DST?"
from time1
order by utc_time;
UTC_TIME PARIS_TIME DST?
--------------------------------- ------------------------------------------ ------
2020-03-29 00:00:00.000000000 UTC 2020-03-29 01:00:00.000000000 EUROPE/PARIS CET
2020-03-29 00:59:59.999000000 UTC 2020-03-29 01:59:59.999000000 EUROPE/PARIS CET
2020-03-29 01:00:00.000000000 UTC 2020-03-29 03:00:00.000000000 EUROPE/PARIS CEST
2020-03-29 01:59:59.999000000 UTC 2020-03-29 03:59:59.999000000 EUROPE/PARIS CEST
2020-03-29 02:00:00.000000000 UTC 2020-03-29 04:00:00.000000000 EUROPE/PARIS CEST
2020-10-25 00:00:00.000000000 UTC 2020-10-25 02:00:00.000000000 EUROPE/PARIS CEST
2020-10-25 00:59:59.999000000 UTC 2020-10-25 02:59:59.999000000 EUROPE/PARIS CEST
2020-10-25 01:00:00.000000000 UTC 2020-10-25 02:00:00.000000000 EUROPE/PARIS CET
2020-10-25 01:59:59.999000000 UTC 2020-10-25 02:59:59.999000000 EUROPE/PARIS CET
2020-10-25 02:00:00.000000000 UTC 2020-10-25 03:00:00.000000000 EUROPE/PARIS CET
可能这就是为什么您希望在02:00之前不会看到时间变化,但如果是这样,您会混淆UTC和当地时间,和/或英国和中欧
与您的问题没有直接关系,但在我的CTE中,我已从使用字符串转换为使用timsetamp。除了打字稍微少一点外,格式也很明确。当您强制转换时,您依赖于会话的NLS设置,该设置与您提供的字符串格式相匹配,因此尽管强制转换适用于您,但可能不适用于运行您的代码的其他人。如果您不想(或不能)使用文字,那么使用带有显式格式掩码的
to_timestamp_tz()
更安全。Oracle是正确的,您的期望似乎是错误的。您可以看到欧洲/伦敦DST的变化
在欧洲/伦敦有以下内容:
# See EU for rules starting in 1996.
...
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/London -0:01:15 - LMT 1847 Dec 1 0:00s
0:00 GB-Eire %s 1968 Oct 27
1:00 - BST 1971 Oct 31 2:00u
0:00 GB-Eire %s 1996
0:00 EU GMT/BST
因此,自1996年以来,英国一直遵循欧盟规则,即:
# Europe
# The following rules are for the European Union and for its
# predecessor organization, the European Communities.
# For brevity they are called "EU rules" elsewhere in this file.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
Rule EU 1977 only - Sep lastSun 1:00u 0 -
Rule EU 1978 only - Oct 1 1:00u 0 -
Rule EU 1979 1995 - Sep lastSun 1:00u 0 -
Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
Rule EU 1996 max - Oct lastSun 1:00u 0 -
所以。。。在英国(以及欧盟其他国家),DST从3月的最后一个星期日起在协调世界时01:00应用,明年是2020-03-29协调世界时01:00:00。它将在DST上持续到10月的最后一个星期日协调世界时01:00,即明年的协调世界时2020-10-25 01:00:00
Oracle遵循这些规则:
with time1 (utc_time) as (
select timestamp '2020-03-29 00:00:00.000 UTC' FROM dual
union all select timestamp '2020-03-29 00:59:59.999 UTC' FROM dual
union all select timestamp '2020-03-29 01:00:00.000 UTC' FROM dual
union all select timestamp '2020-03-29 01:59:59.999 UTC' FROM dual
union all select timestamp '2020-03-29 02:00:00.000 UTC' FROM dual
--
union all select timestamp '2020-10-25 00:00:00.000 UTC' FROM dual
union all select timestamp '2020-10-25 00:59:59.999 UTC' FROM dual
union all select timestamp '2020-10-25 01:00:00.000 UTC' FROM dual
union all select timestamp '2020-10-25 01:59:59.999 UTC' FROM dual
union all select timestamp '2020-10-25 02:00:00.000 UTC' FROM dual
)
select utc_time,
utc_time at time zone 'Europe/London' as london_time,
to_char(utc_time at time zone 'Europe/London', 'TZD') as "DST?"
from time1
order by utc_time;
UTC_TIME LONDON_TIME DST?
--------------------------------- ------------------------------------------- ------
2020-03-29 00:00:00.000000000 UTC 2020-03-29 00:00:00.000000000 EUROPE/LONDON GMT
2020-03-29 00:59:59.999000000 UTC 2020-03-29 00:59:59.999000000 EUROPE/LONDON GMT
2020-03-29 01:00:00.000000000 UTC 2020-03-29 02:00:00.000000000 EUROPE/LONDON BST
2020-03-29 01:59:59.999000000 UTC 2020-03-29 02:59:59.999000000 EUROPE/LONDON BST
2020-03-29 02:00:00.000000000 UTC 2020-03-29 03:00:00.000000000 EUROPE/LONDON BST
2020-10-25 00:00:00.000000000 UTC 2020-10-25 01:00:00.000000000 EUROPE/LONDON BST
2020-10-25 00:59:59.999000000 UTC 2020-10-25 01:59:59.999000000 EUROPE/LONDON BST
2020-10-25 01:00:00.000000000 UTC 2020-10-25 01:00:00.000000000 EUROPE/LONDON GMT
2020-10-25 01:59:59.999000000 UTC 2020-10-25 01:59:59.999000000 EUROPE/LONDON GMT
2020-10-25 02:00:00.000000000 UTC 2020-10-25 02:00:00.000000000 EUROPE/LONDON GMT
在中欧,DST适用于同一UTC时间,但当地时间当然不同:
with time1 (utc_time) as (
...
)
select utc_time,
utc_time at time zone 'Europe/Paris' as paris_time,
to_char(utc_time at time zone 'Europe/Paris', 'TZD') as "DST?"
from time1
order by utc_time;
UTC_TIME PARIS_TIME DST?
--------------------------------- ------------------------------------------ ------
2020-03-29 00:00:00.000000000 UTC 2020-03-29 01:00:00.000000000 EUROPE/PARIS CET
2020-03-29 00:59:59.999000000 UTC 2020-03-29 01:59:59.999000000 EUROPE/PARIS CET
2020-03-29 01:00:00.000000000 UTC 2020-03-29 03:00:00.000000000 EUROPE/PARIS CEST
2020-03-29 01:59:59.999000000 UTC 2020-03-29 03:59:59.999000000 EUROPE/PARIS CEST
2020-03-29 02:00:00.000000000 UTC 2020-03-29 04:00:00.000000000 EUROPE/PARIS CEST
2020-10-25 00:00:00.000000000 UTC 2020-10-25 02:00:00.000000000 EUROPE/PARIS CEST
2020-10-25 00:59:59.999000000 UTC 2020-10-25 02:59:59.999000000 EUROPE/PARIS CEST
2020-10-25 01:00:00.000000000 UTC 2020-10-25 02:00:00.000000000 EUROPE/PARIS CET
2020-10-25 01:59:59.999000000 UTC 2020-10-25 02:59:59.999000000 EUROPE/PARIS CET
2020-10-25 02:00:00.000000000 UTC 2020-10-25 03:00:00.000000000 EUROPE/PARIS CET
可能这就是为什么您希望在02:00之前不会看到时间变化,但如果是这样,您会混淆UTC和当地时间,和/或英国和中欧
与您的问题没有直接关系,但在我的CTE中,我已从使用字符串转换为使用timsetamp。除了打字稍微少一点外,格式也很明确。当您强制转换时,您依赖于会话的NLS设置,该设置与您提供的字符串格式相匹配,因此尽管强制转换适用于您,但可能不适用于运行您的代码的其他人。如果您不想(或不能)使用文字,那么使用带有显式格式掩码的
to_timestamp_tz()
更安全。为什么您认为这是错误的。DST时间在凌晨2:00生效,而不是1:00生效。不,不生效。无论如何,格林尼治标准时间/英国夏令时。其他地区有不同的规则和不同的当地时间;GMT/BST的变化与CET/CEST发生在同一UTC时间(我相信是设计上的变化),所以在巴黎说变化发生在CET时间02:00,这仍然是UTC时间01:00。尝试时间戳'2020-03-29 01:00:00 UTC'
而不是演员阵容。你为什么认为这是错误的。DST时间在凌晨2:00生效,而不是1:00生效。不,不生效。无论如何,格林尼治标准时间/英国夏令时。其他地区有不同的规则和不同的当地时间;GMT/BST的变化与CET/CEST发生在同一UTC时间(我相信是故意的),所以在巴黎说变化发生在CET时间02:00,现在仍然是UTC时间01:00。尝试时间戳“2020-03-29 01:00:00 UTC”
而不是演员阵容。感谢你的全面回答:)我确实错了Tanks的全面回答:)我确实错了