假设我有一个以日期格式存储数据的数据库列。当前存储在此表中的所有记录都是时间设置为 00:00 AM 的日期。
美洲/圣保罗地区最终进入夏令时。发生这种情况时,时钟会调快一小时。夏令时开始当天的第一个有效小时是凌晨 1:00(即没有凌晨 0:00)。例如,由于当年实行夏令时,日期
10/15/2017 0:00 AM
被视为无效(第一个有效时间为10/15/2017 1:00 AM
)。
如何实现 SELECT...WHERE 查询来识别因美洲/圣保罗地区夏令时开始而被视为无效的日期?
你可以查一下https://www.timeanddate.com/time/change/brazil/sao-paulo?year=2018
年份 | 夏令时结束(时钟向后) | 夏令时开始(时钟向前) |
---|---|---|
2010 | 2 月 21 日星期日 00:00 | 10 月 17 日星期日 00:00 |
2011 | 2 月 20 日星期日 00:00 | 10 月 16 日星期日 00:00 |
2012 | 2 月 26 日星期日 00:00 | 10 月 21 日星期日 00:00 |
2013 | 2 月 17 日星期日 00:00 | 10 月 20 日星期日 00:00 |
2014 | 2 月 16 日星期日 00:00 | 10 月 19 日星期日 00:00 |
2015 | 2 月 22 日星期日 00:00 | 10 月 18 日星期日 00:00 |
2016 | 2 月 21 日星期日 00:00 | 10 月 16 日星期日 00:00 |
2017 | 2 月 19 日星期日 00:00 | 10 月 15 日,星期日,00:00 |
2018 | 2 月 18 日,星期日,00:00 | 11 月 4 日星期日 00:00 |
2019 | 2 月 17 日星期日 00:00 | 没有夏令时开始 |
如果您想要查询,那么您可以生成一个日期列表,并找到当天与第二天之间的时间差超过 24 小时的日期:
WITH bounds (start_dt, end_dt) AS (
SELECT DATE '2010-01-01',
TRUNC(SYSDATE)
FROM DUAL
),
days (dt, ts) AS (
SELECT start_dt + (LEVEL - 1),
FROM_TZ(CAST(start_dt AS TIMESTAMP), 'America/Sao_Paulo')
+ INTERVAL '1' DAY * (LEVEL - 1)
FROM bounds
CONNECT BY
start_dt + (LEVEL - 1) <= end_dt
),
diff (dt, ts, diff) AS (
SELECT dt,
ts,
LEAD(CAST(ts AS DATE)) OVER (ORDER BY ts) - CAST(ts AS DATE)
FROM days
)
SELECT dt
FROM diff
WHERE diff > 1
哪个输出:
DT |
---|
2010-10-17 00:00:00 |
2011-10-16 00:00:00 |
2012-10-21 00:00:00 |
2013-10-20 00:00:00 |
2014-10-19 00:00:00 |
2015-10-18 00:00:00 |
2016-10-16 00:00:00 |
2017-10-15 00:00:00 |
2018-11-04 00:00:00 |