golang根據配置的時間和時區計算定時任務是否到了重新整理時間

changjixiong發表於2016-11-04

## 起因   很多時候我們會碰到這樣的需求,每天某個時候需要定時執行某個任務,比如定時發郵件、定時發推送訊息等,而這個定時是針對當地時間的,比如每天中午 12 點發推送訊息給玩家提醒可以上線領金幣啦。   然而,中國的 12 點和越南的 12 點就不是同一個 12 點,所以需要通過時區計算是否到了該執行任務的時候。 ## 思路   先來看一下如何根據時區計算約定的時間。假設現在需要晚上 20 點,執行任務,時區為西 3 時區。首先生成一個格林威治時間的 20 點

utcTime := time.Now().UTC()
targetTime :=time.Date(utcTime.Year(),utcTime.Month(),utcTime.Day(),
20, 0, 0, 0, utcTime.Location())

  由於西 3 時區比格林威治時間慢 3 個小時,等西 3 時區 20 點的時候,格林威治時間就是 20 點再過 3 小時,對應的格林威治時間就是

targetTime.Unix() + 3 * 3600

而如果是東 8 時區到 20 點的時候,格林威治時間還差 8 小時才到 20 點,則對應的時間是

targetTime.Unix() - 8 * 3600

## 細化 先對重新整理時間的配置定義一個結構

type RefreshConfig struct {
    TargetHour      int
    TargetMinute    int
    Targetsecond    int
    Offset          int64
    lastRefreshTime int64
}

定義了定時任務執行的時分秒,offset 表示在格林威治時間對應的時分秒基礎上做多少偏移能得到本地的目標時間。offset 定義如下

var zoneToOffset = map[string]int64{
    "Z0":  0,
    "E1":  -1 * 3600,
    "E2":  -2 * 3600,
    "E3":  -3 * 3600,
    "E4":  -4 * 3600,
    "E5":  -5 * 3600,
    "E6":  -6 * 3600,
    "E7":  -7 * 3600,
    "E8":  -8 * 3600,
    "E9":  -9 * 3600,
    "E10": -10 * 3600,
    "E11": -11 * 3600,
    "E12": 12 * 3600,
    "W1":  1 * 3600,
    "W2":  2 * 3600,
    "W3":  3 * 3600,
    "W4":  4 * 3600,
    "W5":  5 * 3600,
    "W6":  6 * 3600,
    "W7":  7 * 3600,
    "W8":  8 * 3600,
    "W9":  9 * 3600,
    "W10": 10 * 3600,
    "W11": 11 * 3600,
    "W12": 12 * 3600,
}

E8 對應東 8 區,W3 對應西 3 區,參照前文的計算方式。 通過一下程式碼計算是否達到 (或者超過了) 當地的執行時間

func TimeIsUp(refreshConfig *RefreshConfig) bool {

    targetTime := getTargerTime(refreshConfig.TargetHour,
        refreshConfig.TargetMinute,
        refreshConfig.Targetsecond,
        refreshConfig.Offset)

    return refreshConfig.lastRefreshTime < targetTime &&
        time.Now().Unix() >= targetTime
}

定時任務執行以後,需要把 lastRefreshTime 設定為當前時間。 完整內容檢視github 上的程式碼 ## 遺留問題   對於夏令時的計算,暫時沒找到比較好的辦法。

更多原創文章乾貨分享,請關注公眾號
  • golang根據配置的時間和時區計算定時任務是否到了重新整理時間
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章