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
|
// a dst leap occurred
|
||||||
if offsetDiff > 0 {
|
if offsetDiff > 0 {
|
||||||
|
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 {
|
if dstFlags&DSTLeapUnskip != 0 {
|
||||||
return findTimeOfDSTChange(prev, t).Add(1 * time.Second)
|
// return the earliest time right after the leap
|
||||||
|
return dstChangeTime.Add(1 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
return expr.roundTime(t)
|
// return the next scheduled time right after the leap
|
||||||
|
return expr.roundTime(dstChangeTime.Add(1 * time.Second))
|
||||||
|
}
|
||||||
|
|
||||||
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
// a dst fall occurred
|
// a dst fall occurred
|
||||||
|
@ -401,13 +413,13 @@ func workdayOfMonth(targetDom, lastDom time.Time) int {
|
||||||
return dom
|
return dom
|
||||||
}
|
}
|
||||||
|
|
||||||
func utcOffset(t time.Time) int {
|
func utcOffset(t time.Time) time.Duration {
|
||||||
_, offset := t.Zone()
|
_, offset := t.Zone()
|
||||||
return offset
|
return time.Duration(offset) * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
func noTZ(t time.Time) time.Time {
|
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 {
|
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
|
// a fall occurs within the next 12 hours
|
||||||
if offsetDiff < 0 {
|
if offsetDiff < 0 {
|
||||||
border := findTimeOfDSTChange(t, t.Add(12*time.Hour))
|
border := findTimeOfDSTChange(t, t.Add(12*time.Hour))
|
||||||
t0 := border.Add(time.Duration(offsetDiff) * time.Second)
|
t0 := border.Add(offsetDiff)
|
||||||
|
|
||||||
if t0.After(t) {
|
if t0.After(t) {
|
||||||
return t
|
return t
|
||||||
|
@ -468,9 +480,9 @@ func findTwinTime(t time.Time) time.Time {
|
||||||
// a fall occurred in the past 12 hours
|
// a fall occurred in the past 12 hours
|
||||||
if offsetDiff < 0 {
|
if offsetDiff < 0 {
|
||||||
border := findTimeOfDSTChange(t.Add(-12*time.Hour), t)
|
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
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -333,6 +333,30 @@ func TestDST(t *testing.T) {
|
||||||
time.Date(2014, 3, 12, 2, 0, 0, 0, locs[0]),
|
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]),
|
fmt.Sprintf("%s hourly leap skip", locs[0]),
|
||||||
"0 0 * * * * *",
|
"0 0 * * * * *",
|
||||||
|
@ -477,6 +501,30 @@ func TestDST(t *testing.T) {
|
||||||
time.Date(1981, 4, 4, 2, 0, 0, 0, locs[1]),
|
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]),
|
fmt.Sprintf("%s hourly leap skip", locs[1]),
|
||||||
"0 0 * * * * *",
|
"0 0 * * * * *",
|
||||||
|
@ -573,6 +621,30 @@ func TestDST(t *testing.T) {
|
||||||
time.Date(2014, 10, 8, 2, 0, 0, 0, locs[2]),
|
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]),
|
fmt.Sprintf("%s hourly leap skip", locs[2]),
|
||||||
"0 0 * * * * *",
|
"0 0 * * * * *",
|
||||||
|
|
Loading…
Reference in New Issue