秋季時間變化期間的計劃作業
我想知道其他人如何處理這種情況。
如果您有一個計劃在凌晨 1:30 執行的作業怎麼辦。在秋天,當時間改變時,1:00:00 到 1:59:59 的時間會重複,因此該作業會執行兩次。
可以是 Windows 任務計劃程序、SQL 代理或任何其他計劃工具。這些工具中的大多數似乎都基於機器時間,而不是 UTC 時間。如果我告訴它每晚在 UTC 時間執行這項工作,那麼我就不會遇到重複時間問題。
考慮到時區和夏令時,按當地時間正確安排未來任務是一個非常複雜的主題。我以前從這里和這裡的 Stack Overflow 的程式角度寫過它。
我將從非程式的角度來總結一下:
按本地時間而不是 UTC定義您的重複模式。例如,如果您將每日鬧鐘設置為每天早上 8:00 叫醒您,那麼您不希望在夏令時轉換後提前一小時或晚一小時醒來。如果我在美國太平洋時區,我無法安排 UTC 下午 4:00,因為在轉換後它必須切換到下午 3:00 UTC 以保持相同的當地時間上午 8:00。
定義“本地”時間所代表的時區。不要假設伺服器的本地時區與對最終使用者很重要的時區相同。
將本地時間投影到您希望事件觸發的每個事件的 UTC 日期和時間。
- 您幾乎總是在下一次立即發生時執行此操作,這樣您就可以使用 UTC 時鐘來確定執行的真正時刻。
- 在某些情況下,您可能還希望預測接下來的幾個(或許多)實例,例如接下來的 5 次事件,或下一年的所有事件。(這部分與應用程序的要求高度相關。)
制定策略(固定的或可配置的),以應對夏令時轉換時發生的事件:
- 對於“彈簧向前”過渡,當該事件可能不存在時,會缺少本地時間。例如,在美國太平洋時間,計劃在當地時間凌晨 2:00 執行的每日任務在 2014 年 3 月 9 日將不存在。在大多數情況下,您會希望將該時間提前節省量(通常為 1 小時) ),因此當天它將在凌晨 3:00 執行,但在下一個實例中將恢復為凌晨 2:00 執行。(但是,您完全有可能為此需要不同的策略。)
- 對於“回退”過渡,當事件可能存在兩次時,重複的本地時間會重疊。例如,在美國太平洋時間,計劃在凌晨 1:00 執行的每日任務將有兩個可能的時間在 2014 年 11 月 2 日執行。在大多數情況下,您會希望在第一次出現 1時執行:00 AM PDT 並跳過同一日期的 1:00 AM PST 的下一次出現。(但同樣,您可能需要不同的策略,例如在第二次出現時執行,或者同時執行。YMMV)
如果您需要更新時區數據,請準備好重新計算所有出現的 UTC 時間。IANA/Olson TZDB每年都會發布多次更新,因為世界各國政府一直在改變他們對時區偏移和夏令時規則的看法。 您不能假設未來任何特定的時間段內規則都不會改變。
- 請務必訂閱時區數據發佈公告,並製定將其應用到您的系統和/或應用程序的流程。
- 在傳統的公司環境中,這應該是 IT 運營人員的責任。
- 根據您的環境,您可能通過
tzdata
linux 包更新、Java JRE 或 tzupdater或任何數量的其他渠道獲取此數據。有時它是特定於環境的,有時是特定於程式平台的,例如PHP 的 timezonedb PECL 包等等。- 微軟有自己的時區數據。在 Windows 上,如果您使用
TimeZoneInfo
的是 .NET(例如),則您正在使用此數據。更新來自這裡,並且也會通過 Windows 更新自動推出,因此您應該留意這些更新,以便知道何時/是否需要重新計算。了解了所有這些之後,仍有一種情況是您可以僅按 UTC 進行安排,那就是絕對**未來事件。例子:
- 每 X 小時或每 X 分鐘執行一次的作業。
- 日出開始和停止時間,或其他天文現象。
- 時間敏感的安全視窗,例如在預定時間將敏感資訊傳輸給另一方時。
Windows 任務計劃程序
Windows 不一定做正確的事。注意你如何定義觸發器:
當您選中標有“跨時區同步”的框時,該任務僅由 UTC 安排。(所有時間仍顯示為本地時間,但儲存為 UTC。)所以這是我之前所說的“絕對”事件。
當您未選中該框時,它將使用執行程式碼的電腦的本地時區。它沒有為您提供任何指定時區的選項,因此恕我直言,這不是一個很好的實現。
我不確定它的 DST 行為,但我會進行試驗並就此與您聯繫。它可能會做我上面描述的事情,但不一定。
SQL 代理
SQL 代理調度程序更糟糕,因為它只允許您使用本地伺服器時間。同樣,不能指定時區,也不能指定 UTC。
它已被請求,但未被接受。