jasonlvhit / gocron

A Golang Job Scheduling Package.
BSD 2-Clause "Simplified" License
3.45k stars 346 forks source link

Could not run job at specific time when daylight saving time switches #39

Open reorx opened 7 years ago

reorx commented 7 years ago

Code:

gocron_test.go

package main

import (
    "time"
    "fmt"
    "github.com/jasonlvhit/gocron"
)

func main() {
    fmt.Println("start main")
    go func() {
        for {
            time.Sleep(time.Duration(3*time.Second))
            now := time.Now()
            fmt.Println("   (now", now, time.Local, ")")
        }
    }()
    gocron.Every(1).Day().At("01:59").Do(pri1)
    gocron.Every(1).Day().At("03:01").Do(pri2)
    <- gocron.Start()
}

func pri1() {
    now := time.Now()
    fmt.Println("do 1 !!!", now)
}

func pri2() {
    now := time.Now()
    fmt.Println("do 2 !!!", now)
}

The time zone is set to America/New_York, and the date time is set to 2017-03-12 01:58:50 by sudo timedatectl set-time "2017-03-12 01:58:50" && sudo hwclock -w

Output:

[vagrant@localhost ~]$ ./settime.sh && go run ./test_gocron.go
Sun Mar 12 01:58:51 EST 2017
start main
    (now 2017-03-12 01:58:54.789104654 -0500 EST Local )
    (now 2017-03-12 01:58:57.78959527 -0500 EST Local )
    (now 2017-03-12 01:59:00.793605829 -0500 EST Local )
do 1 !!! 2017-03-12 01:59:00.793731129 -0500 EST
    (now 2017-03-12 01:59:03.797613207 -0500 EST Local )
    (now 2017-03-12 01:59:06.798436061 -0500 EST Local )
    ...
    (now 2017-03-12 03:00:51.833313996 -0400 EDT Local )
    (now 2017-03-12 03:00:54.83476427 -0400 EDT Local )
    (now 2017-03-12 03:00:57.836203538 -0400 EDT Local )
    (now 2017-03-12 03:01:00.838035849 -0400 EDT Local )
    (now 2017-03-12 03:01:03.839273531 -0400 EDT Local )
    (now 2017-03-12 03:01:06.840455311 -0400 EDT Local )

The output shows that gocron.Every(1).Day().At("01:59").Do(pri1) runs properly, but gocron.Every(1).Day().At("03:01").Do(pri2) doesn't take any effect.

P.S. after 2017-03-12 01:59:59, daylight saving time switches from EST to EDT

alexbao commented 7 years ago

I had similar issue too. Guess in func (j *Job) At(t string) *Job, the now timestamp has to use the loc timezone. Something like time.Now().In(loc)