From 7276752e7cbc87aead678ae84ec8a83e7603a141 Mon Sep 17 00:00:00 2001 From: vikey Date: Sat, 12 Feb 2022 18:51:24 +0800 Subject: [PATCH] Fix CronExpression issue with DST This commit fixes an issue with CronExpression fails to calculate next execution on the day of daylight saving time. Closes gh-28038 --- .../springframework/scheduling/support/CronField.java | 9 +++++++-- .../scheduling/support/CronExpressionTests.java | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java index bed9506634..e01e00b632 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/CronField.java @@ -260,7 +260,7 @@ abstract class CronField { * Roll forward the give temporal until it reaches the next higher * order field. Calling this method is equivalent to calling * {@link #elapseUntil(Temporal, int)} with goal set to the - * minimum value of this field's range. + * minimum value of this field's range, except for daylight saving. * @param temporal the temporal to roll forward * @param the type of temporal * @return the rolled forward temporal @@ -269,7 +269,12 @@ abstract class CronField { int current = get(temporal); ValueRange range = temporal.range(this.field); long amount = range.getMaximum() - current + 1; - return this.field.getBaseUnit().addTo(temporal, amount); + T result = this.field.getBaseUnit().addTo(temporal, amount); + //adjust daylight saving + if (get(result) != range.getMinimum()) { + result = this.field.adjustInto(result,result.range(this.field).getMinimum()); + } + return result; } /** diff --git a/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java b/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java index 5abce9e2de..5de5362fc1 100644 --- a/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java +++ b/spring-context/src/test/java/org/springframework/scheduling/support/CronExpressionTests.java @@ -1336,6 +1336,14 @@ class CronExpressionTests { actual = cronExpression.next(last); assertThat(actual).isNotNull(); assertThat(actual).isEqualTo(expected); + + cronExpression = CronExpression.parse("0 5 0 * * *"); + + last = ZonedDateTime.parse("2021-03-28T01:00:00+01:00[Europe/Amsterdam]"); + expected = ZonedDateTime.parse("2021-03-29T00:05+02:00[Europe/Amsterdam]"); + actual = cronExpression.next(last); + assertThat(actual).isNotNull(); + assertThat(actual).isEqualTo(expected); } @Test