jmrozanec / jmrozanec/cron-utils

Bare L in day of week: description is wrong for all cron types, and the wrong day is scheduled for 0-7 definitions

Open
#716 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
1.2k
Forks
272
PR merge metrics
No merged PRs in 30d

Description

Bare `L` in the day-of-week field (as opposed to `nL`) has two separate defects. Scheduling was fixed for Quartz in #142 / 6.0.0, but the description was not, and the fix does not carry over to definitions that number days differently.

### 1. Description is wrong for every cron type

```java
CronDescriptor d = CronDescriptor.instance(Locale.UK);
CronParser quartz = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
d.describe(quartz.parse("0 0 0 ? * L *"));
```

Actual: `at 00:00 last Sunday of every month`
Expected: something like `at 00:00 every Saturday`

Both halves are wrong — it is not restricted to the last week of the month, and the day is Saturday, not Sunday. The scheduling for `QUARTZ` is correct (every Saturday: 2025-06-07, 06-14, 06-21, 06-28, 07-05, matching `org.quartz.CronExpression` 2.5.0 exactly), so this is purely a describer bug and the two surfaces disagree with each other.

### 2. Wrong day scheduled for definitions with a 0-7 / Monday=1 range

```java
CronParser spring53 = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.SPRING53));
ExecutionTime.forCron(spring53.parse("0 0 0 ? * L"));
```

| | next 5 executions |
|---|---|
| `QUARTZ` | 2025-06-07, 06-14, 06-21, 06-28, 07-05 — all Saturday, correct |
| `SPRING53` | 2025-06-08, 06-15, 06-22, 06-29, 07-06 — all **Sunday** |

Bare `L` should mean the last day of the week regardless of how the definition numbers its days.

### Cause

`OnDayOfWeekValueGenerator` holds Saturday as a literal in Quartz numbering:

```java
private static final On ON_SATURDAY = new On(new IntegerFieldValue(7));
```

and `generateNoneValues` then normalizes that value using the *current definition's* scheme:

```java
final int requiredDoW = ConstantsMapper.weekDayMapping(mondayDoWValue, ConstantsMapper.JAVA8, on.getTime().getValue());
```

For `QUARTZ` (`mondayDoWValue = 2`, 1=Sun..7=Sat) the literal `7` maps to Saturday, which is why #142 looks fixed. For `SPRING53` (`mondayDoWValue = 1`, plus `withIntMapping(7, 0)`) the same literal maps to Sunday. The constant is in one numbering but is interpreted in another, so it only happens to be right for Quartz.

Version: both reproduced on `master` (`bac6e86`); #2 also affects released 9.2.1 via `SPRING53`.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with OnDayOfWeekValueGenerator and inspect how generateNoneValues maps the bare L value across cron definitions. Reproduce the examples with CronDescriptor and ExecutionTime for QUARTZ and SPRING53, then verify that descriptions identify the last day of the week and executions select Saturday consistently across both definitions.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.