Spring cron expression parser
Paste the string from @Scheduled(cron = "...") to see what it means and exactly when it will fire next. Spring uses six fields starting at seconds, so a five-field expression copied from a Unix crontab will not start.
Next runs
Try one
The six fields
| Position | Field | Range | Extras |
|---|---|---|---|
| 1 | Second | 0-59 | * , - / |
| 2 | Minute | 0-59 | * , - / |
| 3 | Hour | 0-23 | * , - / |
| 4 | Day of month | 1-31 | ? L L-n nW LW |
| 5 | Month | 1-12 or JAN-DEC | * , - / |
| 6 | Day of week | 0-7 or SUN-SAT | ? dL d#n |
Day-of-week counts Sunday as both 0 and 7. Names are case-insensitive.
The mistake that costs an hour: Unix cron has five fields and starts at minutes. Spring has six and starts at seconds. Pasting 0 9 * * * into@Scheduled does not run at 9am — the application fails to start. Prefix a0 to get 0 0 9 * * *.
Two day fields, combined with OR
When day-of-month and day-of-week are both restricted, Spring fires ifeither matches — they are not intersected. So0 0 0 1 * MON runs on the 1st and on every Monday, which is rarely what people mean. Put ? in the field you do not care about:
0 0 0 1 * ?— the 1st of the month, whatever day that is0 0 0 ? * MON— every Monday
Macros
| Macro | Expands to |
|---|---|
@yearly / @annually | 0 0 0 1 1 * |
@monthly | 0 0 0 1 * * |
@weekly | 0 0 0 * * 0 |
@daily / @midnight | 0 0 0 * * * |
@hourly | 0 0 * * * * |
Which time zone does it use
By default @Scheduled uses the JVM's default time zone, which on a server is often UTC even when your laptop is not. Set it explicitly rather than finding out in production:
@Scheduled(cron = "0 0 9 * * MON-FRI", zone = "Asia/Seoul")The next-run times above are computed in your browser's time zone. If your server runs elsewhere, its schedule shifts accordingly.