Cron Syntax
This article describes the cron syntax that BaseX uses to express recurring points in time. It is currently supported by the cron option of job:eval, and it is available to all features that schedule recurring work.
A cron expression describes when something happens, in contrast to a duration, which describes how often. Both have their place: a duration such as PT90M cannot be written as a cron expression, and a pattern such as “every weekday at 8am” cannot be written as a duration.
Syntax
An expression consists of five fields, separated by whitespace. A sixth field can be prepended to address individual seconds:
┌───────────── second (0-59, optional)
│ ┌─────────── minute (0-59)
│ │ ┌───────── hour (0-23)
│ │ │ ┌─────── day of month (1-31)
│ │ │ │ ┌───── month (1-12, JAN-DEC)
│ │ │ │ │ ┌─── day of week (0-7, SUN-SAT; 0 and 7 denote Sunday)
│ │ │ │ │ │
* * * * * *
If the second field is omitted, it defaults to 0, and the job is triggered at the beginning of a minute.
Each field is a comma-separated list of the following components:
| Component | Description | Example |
|---|---|---|
* | All values of the field. ? is an accepted synonym. | * |
value | A single value. | 15 |
from-to | All values of a range. If the first value is greater than the second one, the range wraps around (22-2 denotes the hours 22, 23, 0, 1, 2). | 9-17 |
from-to/step | Every stepth value of a range. | 9-17/4 |
*/step | Every stepth value of the field. | */15 |
from/step | Every stepth value, starting at from and ending with the last value of the field. | 10/6 |
Month and weekday names are case-insensitive and can be used wherever a numeric value is allowed (JAN, feb, Mon-Fri).
Days of Month and Days of Week
The two day fields interact in a way that surprises many users, but that is shared by all common cron implementations:
- If only one of the two fields is restricted, a date must match this field.
- If both fields are restricted, a date must match either of them.
A field counts as restricted if it does not match every value of its range. It is irrelevant how this is written: *, ?, */1 and 0-6 are equivalent in the weekday field, and none of them is a restriction.
0 0 13 * FRI is thus not limited to Friday the 13th: it is triggered on every 13th of a month and on every Friday. To address Friday the 13th, restrict a single field and check the other one in the query itself.
Time Zones and Daylight Saving
Cron expressions denote local wall-clock times. A job that is scheduled for 0 3 * * * will be triggered at 3am local time, both in winter and in summer.
Two special cases arise when clocks are adjusted:
- If a time is skipped (in spring), the job is triggered once at the end of the gap. A job scheduled for
30 2 * * *will be run at 3am on that day. - If a time occurs twice (in autumn), the job is triggered once, at the first occurrence.
Examples
job:next reports when an expression will be triggered. It is the quickest way to check a pattern before scheduling a job with it:
job:next('0 8 * * MON-FRI', 3)
| Expression | Description |
|---|---|
* * * * * | Every minute. |
*/5 * * * * | Every five minutes. |
30 * * * * * | Every minute, 30 seconds past the minute. |
15 * * * * | Every hour, 15 minutes past the hour. |
0 3 * * * | Every day at 3am. |
0 8 * * MON-FRI | Every weekday at 8am. |
0 */2 * * SAT,SUN | Every second hour on weekends. |
0 0 1 * * | On the first day of every month, at midnight. |
0 4 1 JAN * | Once a year, on January 1 at 4am. |
Unsupported Syntax
The following extensions of other cron dialects are not supported: L (last day), W (nearest weekday), # (nth weekday of the month), and year fields.
An error is raised if an expression cannot be parsed. Expressions that can never match a date, such as 0 0 30 2 * (February 30), are rejected as well; job:next returns an empty sequence for them. Executions are looked up eight years ahead, which covers the longest gap that a valid expression can have (0 0 29 2 * is not triggered between 2096 and 2104, as 2100 is no leap year).
Changelog
Version 13.0- Added: New article added.