Fixed dst leap adjustment.
This commit is contained in:
parent
276721802b
commit
1a49152fbc
|
@ -247,11 +247,23 @@ func (expr *Expression) nextTime(prev, next time.Time) time.Time {
|
|||
|
||||
// a dst leap occurred
|
||||
if offsetDiff > 0 {
|
||||
if dstFlags&DSTLeapUnskip != 0 {
|
||||
return findTimeOfDSTChange(prev, t).Add(1 * time.Second)
|
||||
dstChangeTime := findTimeOfDSTChange(prev, t)
|
||||
|
||||
// since a dst leap occured, t is offsetDiff seconds ahead
|
||||
t = t.Add(-1 * offsetDiff)
|
||||
|
||||
// check if t is within the skipped interval (offsetDiff)
|
||||
if noTZDiff(dstChangeTime, t) < offsetDiff {
|
||||
if dstFlags&DSTLeapUnskip != 0 {
|
||||
// return the earliest time right after the leap
|
||||
return dstChangeTime.Add(1 * time.Second)
|
||||
}
|
||||
|
||||
// return the next scheduled time right after the leap
|
||||
return expr.roundTime(dstChangeTime.Add(1 * time.Second))
|
||||
}
|
||||
|
||||
return expr.roundTime(t)
|
||||
return t
|
||||
}
|
||||
|
||||
// a dst fall occurred
|
||||
|
@ -401,13 +413,13 @@ func workdayOfMonth(targetDom, lastDom time.Time) int {
|
|||
return dom
|
||||
}
|
||||
|
||||
func utcOffset(t time.Time) int {
|
||||
func utcOffset(t time.Time) time.Duration {
|
||||
_, offset := t.Zone()
|
||||
return offset
|
||||
return time.Duration(offset) * time.Second
|
||||
}
|
||||
|
||||
func noTZ(t time.Time) time.Time {
|
||||
return t.UTC().Add(time.Duration(utcOffset(t)) * time.Second)
|
||||
return t.UTC().Add(utcOffset(t))
|
||||
}
|
||||
|
||||
func noTZDiff(t1, t2 time.Time) time.Duration {
|
||||
|
@ -454,7 +466,7 @@ func findTwinTime(t time.Time) time.Time {
|
|||
// a fall occurs within the next 12 hours
|
||||
if offsetDiff < 0 {
|
||||
border := findTimeOfDSTChange(t, t.Add(12*time.Hour))
|
||||
t0 := border.Add(time.Duration(offsetDiff) * time.Second)
|
||||
t0 := border.Add(offsetDiff)
|
||||
|
||||
if t0.After(t) {
|
||||
return t
|
||||
|
@ -468,9 +480,9 @@ func findTwinTime(t time.Time) time.Time {
|
|||
// a fall occurred in the past 12 hours
|
||||
if offsetDiff < 0 {
|
||||
border := findTimeOfDSTChange(t.Add(-12*time.Hour), t)
|
||||
t0 := border.Add(time.Duration(offsetDiff) * time.Second)
|
||||
t0 := border.Add(offsetDiff)
|
||||
|
||||
if t0.Add(time.Duration(-2*offsetDiff) * time.Second).Before(t) {
|
||||
if t0.Add(-2 * offsetDiff).Before(t) {
|
||||
return t
|
||||
}
|
||||
|
||||
|
|
|
@ -333,6 +333,30 @@ func TestDST(t *testing.T) {
|
|||
time.Date(2014, 3, 12, 2, 0, 0, 0, locs[0]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s time after daily leap skip", locs[0]),
|
||||
"0 5 14 * * * *",
|
||||
cronexpr.Options{DSTFlags: cronexpr.DSTFallFireLate},
|
||||
time.Date(2016, 3, 12, 14, 6, 0, 0, locs[0]),
|
||||
[]time.Time{
|
||||
time.Date(2016, 3, 13, 14, 5, 0, 0, locs[0]),
|
||||
time.Date(2016, 3, 14, 14, 5, 0, 0, locs[0]),
|
||||
time.Date(2016, 3, 15, 14, 5, 0, 0, locs[0]),
|
||||
time.Date(2016, 3, 16, 14, 5, 0, 0, locs[0]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s time after daily leap unskip", locs[0]),
|
||||
"0 5 14 * * * *",
|
||||
cronexpr.Options{DSTFlags: cronexpr.DSTLeapUnskip | cronexpr.DSTFallFireLate},
|
||||
time.Date(2016, 3, 12, 14, 6, 0, 0, locs[0]),
|
||||
[]time.Time{
|
||||
time.Date(2016, 3, 13, 14, 5, 0, 0, locs[0]),
|
||||
time.Date(2016, 3, 14, 14, 5, 0, 0, locs[0]),
|
||||
time.Date(2016, 3, 15, 14, 5, 0, 0, locs[0]),
|
||||
time.Date(2016, 3, 16, 14, 5, 0, 0, locs[0]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s hourly leap skip", locs[0]),
|
||||
"0 0 * * * * *",
|
||||
|
@ -477,6 +501,30 @@ func TestDST(t *testing.T) {
|
|||
time.Date(1981, 4, 4, 2, 0, 0, 0, locs[1]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s time after daily leap skip", locs[1]),
|
||||
"0 5 14 * * * *",
|
||||
cronexpr.Options{DSTFlags: cronexpr.DSTFallFireEarly},
|
||||
time.Date(1981, 3, 31, 15, 0, 0, 0, locs[1]),
|
||||
[]time.Time{
|
||||
time.Date(1981, 4, 1, 14, 5, 0, 0, locs[1]),
|
||||
time.Date(1981, 4, 2, 14, 5, 0, 0, locs[1]),
|
||||
time.Date(1981, 4, 3, 14, 5, 0, 0, locs[1]),
|
||||
time.Date(1981, 4, 4, 14, 5, 0, 0, locs[1]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s time after daily leap unskip", locs[1]),
|
||||
"0 5 14 * * * *",
|
||||
cronexpr.Options{DSTFlags: cronexpr.DSTLeapUnskip | cronexpr.DSTFallFireEarly},
|
||||
time.Date(1981, 3, 31, 15, 0, 0, 0, locs[1]),
|
||||
[]time.Time{
|
||||
time.Date(1981, 4, 1, 14, 5, 0, 0, locs[1]),
|
||||
time.Date(1981, 4, 2, 14, 5, 0, 0, locs[1]),
|
||||
time.Date(1981, 4, 3, 14, 5, 0, 0, locs[1]),
|
||||
time.Date(1981, 4, 4, 14, 5, 0, 0, locs[1]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s hourly leap skip", locs[1]),
|
||||
"0 0 * * * * *",
|
||||
|
@ -573,6 +621,30 @@ func TestDST(t *testing.T) {
|
|||
time.Date(2014, 10, 8, 2, 0, 0, 0, locs[2]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s time after daily leap skip", locs[2]),
|
||||
"0 5 14 * * * *",
|
||||
cronexpr.Options{DSTFlags: cronexpr.DSTFallFireEarly},
|
||||
time.Date(2014, 10, 4, 15, 0, 0, 0, locs[2]),
|
||||
[]time.Time{
|
||||
time.Date(2014, 10, 5, 14, 5, 0, 0, locs[2]),
|
||||
time.Date(2014, 10, 6, 14, 5, 0, 0, locs[2]),
|
||||
time.Date(2014, 10, 7, 14, 5, 0, 0, locs[2]),
|
||||
time.Date(2014, 10, 8, 14, 5, 0, 0, locs[2]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s time after daily leap unskip", locs[2]),
|
||||
"0 5 14 * * * *",
|
||||
cronexpr.Options{DSTFlags: cronexpr.DSTLeapUnskip | cronexpr.DSTFallFireEarly},
|
||||
time.Date(2014, 10, 4, 15, 0, 0, 0, locs[2]),
|
||||
[]time.Time{
|
||||
time.Date(2014, 10, 5, 14, 5, 0, 0, locs[2]),
|
||||
time.Date(2014, 10, 6, 14, 5, 0, 0, locs[2]),
|
||||
time.Date(2014, 10, 7, 14, 5, 0, 0, locs[2]),
|
||||
time.Date(2014, 10, 8, 14, 5, 0, 0, locs[2]),
|
||||
},
|
||||
},
|
||||
{
|
||||
fmt.Sprintf("%s hourly leap skip", locs[2]),
|
||||
"0 0 * * * * *",
|
||||
|
|
Loading…
Reference in New Issue