Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CronExpression doesn't handle Quartz weekday of month expressions correctly #27966

Closed
marschall opened this issue Jan 21, 2022 · 1 comment
Closed
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Milestone

Comments

@marschall
Copy link
Contributor

I believe a found a bug in how CronExpression handles Quartz weekday of month expressions.

The cron expression 0 0 0 1W * ? to my understanding should match the weekday (Monday-Friday) that is closest to the first day of a month. For example 2021-08-01 is a Sunday, so #next should to my understanding produce 2021-08-02 the first weekday on the month of August in the year 2021. However it produces 2021-09-01.

In addition the Quartz documentation says:

However if you specify “1W” as the value for day-of-month, and the 1st is a Saturday, the trigger will fire on Monday the 3rd, as it will not ‘jump’ over the boundary of a month’s days.

If we check this very specific scenario with 2022-01-01 which is a Saturday we would expect #next to produce 2022-01-03 but it produces 2022-02-01, "jumping" over the boundary of a month’s days.

Here are two tests for these scenarios

class WeekdayOfMonthQuartzExpressionTests {

  @Test
  void firstWeekdayOfMonth_fromSaturday() {
    CronExpression firstWeekdayOfMonth = CronExpression.parse("0 0 0 1W * ?");
    LocalDate saturday = LocalDate.of(2022, 1, 1);
    assertSame(DayOfWeek.SATURDAY, saturday.getDayOfWeek());
    LocalDate monday = LocalDate.of(2022, 1, 3);
    assertSame(DayOfWeek.MONDAY, monday.getDayOfWeek());
    assertEquals(monday.atStartOfDay(), firstWeekdayOfMonth.next(saturday.atStartOfDay()));
  }

  @Test
  void firstWeekdayOfMonth_fromSunday() {
    CronExpression firstWeekdayOfMonth = CronExpression.parse("0 0 0 1W * ?");
    LocalDate sunday = LocalDate.of(2021, 8, 1);
    assertSame(DayOfWeek.SUNDAY, sunday.getDayOfWeek());
    LocalDate monday = LocalDate.of(2021, 8, 2);
    assertSame(DayOfWeek.MONDAY, monday.getDayOfWeek());
    assertEquals(monday.atStartOfDay(), firstWeekdayOfMonth.next(sunday.atStartOfDay()));
  }

}

I tested with Spring 5.3.15.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 21, 2022
@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Jan 21, 2022
@jhoeller jhoeller added this to the Triage Queue milestone Jan 21, 2022
@poutsma poutsma self-assigned this Jan 28, 2022
@poutsma poutsma modified the milestones: Triage Queue, 5.3.16 Jan 31, 2022
@poutsma poutsma added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Feb 1, 2022
@poutsma poutsma closed this as completed in 8f9a1cd Feb 1, 2022
@marschall
Copy link
Contributor Author

Awesome, thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants