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