提交 27bfcbbc 编写于 作者: A Arjen Poutsma

Fix daylight saving issue in CronExpression

Closes gh-26830
上级 b153b5e5
......@@ -157,6 +157,11 @@ abstract class CronField {
return this.type;
}
@SuppressWarnings("unchecked")
protected static <T extends Temporal & Comparable<? super T>> T cast(Temporal temporal) {
return (T) temporal;
}
/**
* Represents the type of cron field, i.e. seconds, minutes, hours,
......@@ -236,16 +241,17 @@ abstract class CronField {
*/
public <T extends Temporal & Comparable<? super T>> T elapseUntil(T temporal, int goal) {
int current = get(temporal);
ValueRange range = temporal.range(this.field);
if (current < goal) {
T result = this.field.getBaseUnit().addTo(temporal, goal - current);
current = get(result);
if (current > goal) { // can occur due to daylight saving, see gh-26744
result = this.field.getBaseUnit().addTo(result, goal - current);
if (range.isValidIntValue(goal)) {
return cast(temporal.with(this.field, goal));
}
else {
// goal is invalid, eg. 29th Feb, lets try to get as close as possible
return this.field.getBaseUnit().addTo(temporal, goal - current);
}
return result;
}
else {
ValueRange range = temporal.range(this.field);
long amount = goal + range.getMaximum() - current + 1 - range.getMinimum();
return this.field.getBaseUnit().addTo(temporal, amount);
}
......
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -326,12 +326,6 @@ final class QuartzCronField extends CronField {
}
}
@SuppressWarnings("unchecked")
private static <T extends Temporal & Comparable<? super T>> T cast(Temporal temporal) {
return (T) temporal;
}
@Override
public <T extends Temporal & Comparable<? super T>> T nextOrSame(T temporal) {
T result = adjust(temporal);
......
......@@ -1276,6 +1276,14 @@ class CronExpressionTests {
actual = cronExpression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
cronExpression = CronExpression.parse("0 10 2 * * *");
last = ZonedDateTime.parse("2013-03-31T01:09:00+01:00[Europe/Amsterdam]");
expected = ZonedDateTime.parse("2013-04-01T02:10:00+02:00[Europe/Amsterdam]");
actual = cronExpression.next(last);
assertThat(actual).isNotNull();
assertThat(actual).isEqualTo(expected);
}
......
......@@ -822,13 +822,13 @@ class CronTriggerTests {
// 2:00 AM on March 31, 2013: start of Daylight Saving Time for CET in 2013.
// Setting up last completion:
// - PST: Sun Mar 31 10:10:54 CEST 2013
// - CET: Sun Mar 31 01:10:54 CET 2013
// - PST: Sun Mar 31 10:09:54 CEST 2013
// - CET: Sun Mar 31 01:09:54 CET 2013
this.calendar.set(Calendar.DAY_OF_MONTH, 31);
this.calendar.set(Calendar.MONTH, Calendar.MARCH);
this.calendar.set(Calendar.YEAR, 2013);
this.calendar.set(Calendar.HOUR_OF_DAY, 1);
this.calendar.set(Calendar.MINUTE, 10); // changing to any minute from 0-9 causes the test to fail for CET.
this.calendar.set(Calendar.MINUTE, 9);
this.calendar.set(Calendar.SECOND, 54);
Date lastCompletionTime = this.calendar.getTime();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册