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
- 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