[英]Add 1 day to timezone aware timestamp with regards to daylight savings
我正在嘗試將 1 天添加到時區感知時間戳。 在此示例中,我預計+ interval '1' day
會增加 23 小時,因為 DST 於2021-03-28 02:00:00
在Europe/Berlin
,但它的行為與+ interval '24' hour
:
select timestamp '2021-03-28 00:00:00 Europe/Berlin' as before_dst,
timestamp '2021-03-28 00:00:00 Europe/Berlin' + interval '1' day as plus_1_day,
timestamp '2021-03-28 00:00:00 Europe/Berlin' + interval '24' hour as plus_24_hour
from dual;
BEFORE_DST | PLUS_1_DAY | PLUS_24_HOUR |
---|---|---|
2021-03-28 00:00:00.000000000 +01:00 | 2021-03-29 01 :00:00.000000000 +02:00 | 2021-03-29 01:00:00.000000000 +02:00 |
有沒有辦法在時間戳中添加一天,以便遵守夏令時的開始或結束? 對於上面的示例,這意味着一種讓 oracle 自動識別2021-03-28
天在Europe/Berlin
只有 23 小時的方法。
我試圖通過在添加一天之前at local
將時間戳轉換為本地時間戳來解決這個問題,但這不起作用,因為at local
將時間戳轉換為本地時區,而不是像 java 中的LocalDateTime
類的東西,導致完全相同的結果: + interval '1' day
總是恰好加上 24 小時。
您可以將帶有時區值的時間戳轉換為普通時間戳,從而丟棄時區信息; 然后添加 1 天間隔,並聲明結果在所需的時區:
from_tz(cast(timestamp '2021-03-28 00:00:00 Europe/Berlin' as timestamp) + interval '1' day, 'Europe/Berlin') as plus_1_day
或轉換為日期(可能是隱式的),添加一天,然后轉換:
from_tz(cast(cast(timestamp '2021-03-28 00:00:00 Europe/Berlin' as date) + 1 as timestamp), 'Europe/Berlin')
調整您的示例並顯示中間值:
select timestamp '2021-03-28 00:00:00 Europe/Berlin' as before_dst,
cast(timestamp '2021-03-28 00:00:00 Europe/Berlin' as timestamp) as as_ts,
cast(timestamp '2021-03-28 00:00:00 Europe/Berlin' as timestamp) + 1 as plus_1_day_ts,
from_tz(cast(timestamp '2021-03-28 00:00:00 Europe/Berlin' as timestamp) + interval '1' day, 'Europe/Berlin') as plus_1_day
from dual;
BEFORE_DST | AS_TS | PLUS_1_DAY_TS | PLUS_1_DAY |
---|---|---|---|
2021-03-28 00:00:00 +01:00 | 2021-03-28 00:00:00 | 2021-03-29 00:00:00 | 2021-03-29 00:00:00 +02:00 |
這假設您總是在處理一個固定的已知時區區域; 如果您實際上有一個未知時區的變量或列值,那么您可以從中提取區域並將其用作from_tz()
參數。
您還應該知道,這將在午夜對您的示例起作用,但不會在所有時間都起作用。 例如,如果您的起始值是timestamp '2021-03-27 02:30:00 Europe/Berlin'
那么它將失敗並顯示“ORA-01878:在日期時間或間隔中未找到指定字段”,因為它最終會嘗試宣布2021-03-28 02:30:00
位於歐洲/柏林區域 - 沒有這樣的時間,因為它屬於 02:00-03:00 的“迷失”小時。 只需添加一天的時間間隔就可以解決這個問題 - 但在您的示例中並沒有像您期望的那樣工作......
這是因為文檔中的這一行:
Oracle 以 UTC 時間執行所有時間戳算法。
2021-03-28 00:00:00 歐洲/柏林是 2021-03-27 23:00:00 UTC; 添加一天是 2021-03-28 23:00:00 UTC; 即 2021-03-29 02:00:00 歐洲/柏林
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.