簡體   English   中英

將 1 天添加到有關夏令時的時區感知時間戳

[英]Add 1 day to timezone aware timestamp with regards to daylight savings

我正在嘗試將 1 天添加到時區感知時間戳。 在此示例中,我預計+ interval '1' day會增加 23 小時,因為 DST 於2021-03-28 02:00:00Europe/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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM