The cron
package implements a cron job scheduler with a lot of non-standard extensions.
It allowes to run jobs periodically at fixed times, dates, frequencies and intervals.
The cron expression
is a string with 5, 6 or 7 fields separated by any number of
whitespace like SP
(0x20
) or HT
(0x09
) from the ASCII table. Additionally,
this cron
package implements and supports a lot of Non-Standard Macros
as listed below.
The standard crontab supports only 5 fields and cannot be scaled to seconds or years. The current implementation completes the fields as following:
- If only 5 fields are present, the
seconds
field with value0
is added to the begin and theyear
field with value*
is added to the end of the fields list. - If only 6 fields are present, the
year
field with value*
is added to the end of the fields list.
Field name | Required | Description | Allowed values | Allowed special characters |
---|---|---|---|---|
seconds |
✕ | Represents seconds. | 0-59 |
, - * / . R |
minutes |
✓ | Represents minutes. | 0-59 |
, - * / . R |
hours |
✓ | Represents hours. | 0-23 |
, - * / . R |
dom |
✓ | Represents days-of-month. | 1-31 |
, - * / . R ? L W |
month |
✓ | Represents months. | 1-12 or JAN-DEC |
, - * / . R |
dow |
✓ | Represents days-of-week. | 0-7 or SUN-SAT |
, - * / . R ? L # |
year |
✕ | Represents years. | 1970-2099 |
, - * / . R |
Note: Both,
0
and7
value in thedow
(days-of-week) field is interpreted asSUN
(Sunday).
Note: The names in
month
anddow
(days-of-week) fields and the special charactersR
,L
andW
are case insensitive. For example,FRI
is the same asFri
orfri
.
Special Character | Description |
---|---|
, |
Commas are used to separate values in a field. For example, using MON,FRI,SUN in the dow (days-of-week) field means Monday, Friday and Sunday . |
- |
Hyphen defines ranges. For example, JAN-MAR in the month field means Januar, Februar and March . The current implementation supports ranges with "range-overflows" for all expression fields excepting the year field. For example, FRI-MON in the dow (days-of-week) field means Friday, Saturday, Sunday and Monday . A mix of names and numeric values in month and dow (days-of-week) fields is supported, too. For example, JAN-MAR is the same as JAN-3 . |
* |
Asterisk is used to select all possible values within a field. For example, * in the month field means daily or every day . |
/ |
Slash can be used to specify frequencies. For example, */10 in the seconds field means every 10 seconds . And 10/15 in the minutes field means the minutes 10, 25, 40 and 55 . |
. |
Dot can be used to specify the current date or time value on the startup. For example, 0 . . * * * * would be updated to 0 9 15 * * * * if the cron is started-up at 09:15. |
? |
Question mark is used for leaving either, dom (day-of-month) or dow (day-of-week) blank. For example, 0 0 0 15 * ? * would trigger the cronjob at 15th of every month regardless of what day-of-week it is. |
R |
R stands for random . R can be combined with ranges, e.g. 10-30/R in the minutes field. Once generated during parsing, the random number remains constant for current field. If used in the dom (day-of-month) field without ranges, the possible values are limited to the range 1-28 . To be able to use the total range set 1-31/R to the dom (day-of-month) field. |
L |
L stands for last . When this character is used in the dom (day-of-month) field, it specifies the last day of the month. For example, 31 January or 29 February in a leap year. In the dow (day-of-week) field, it specifies the last day of the week and simply means the SAT or 6 . When this character is used in the dow (day-of-week) field and is prefixed with a number, it means the last X day of the month . For example, 1L means the last Monday of the month . MONL is the same as 1L . |
W |
W stands for weekday (Monday-Friday). W is used to specify the business day nearest the given day in the given month. It never jumps over the boundary of the month's days. For example, if 1W is a Saturday, the cronjob would trigger at Monday, the 3rd. The L and W special characters can also be combined in the dom (day-of-month) field as LW , which means last weekday of the month . |
# |
Hash allows to specifying constructs such as the second Friday of a given month. For example, 5#3 in the dow (day-of-week) field means the third Friday of every month . The value before the # has the range 0-7 or SUN-SAT . The value after the # has the range 1-5 . |
Note: Be careful with the use of
?
and*
special characters in thedom
(day-of-month) ordow
(day-of-week) fields.
Note: Avoid cronjobs at
daylight saving times
. Cronjobs can be skiped or repeated depending on whether the time moves back or jumps forward.
Note: It is not allowed to combine the
?
with other values within a field. This special character can only be used exclusively within a field.
Note: It is not allowed to define the
?
special character in both,dom
(days-of-month) anddow
(days-of-week) fields at the same time.
Note: If both, the
dom
(day-of-month) anddow
(day-of-week) fields contain any values excepting the?
, the day is calculated from the best possible value of the both fields.
Macro | Description | Equivalent expression |
---|---|---|
@yearly |
Run once a year at midnight of 1 January. | 0 0 0 1 1 * * |
@annually |
The same as @yearly . |
0 0 0 1 1 * * |
@monthly |
Run once a month at midnight of the first day of the month. | 0 0 0 1 * * * |
@weekly |
Run once a week at midnight on Sunday. | 0 0 0 * * 0 * |
@daily |
Run once a day at midnight. | 0 0 0 * * * * |
@midnight |
The same as @daily . |
0 0 0 * * * * |
@hourly |
Run once an hour at the beginning of the hour. | 0 0 * * * * * |
@minutely |
Run once a minute at the beginning of the minute. | 0 * * * * * * |
@every_minute |
The same as @minutely . |
0 * * * * * * |
@secondly |
Run secondly. | * * * * * * * |
@every_second |
The same as @secondly . |
* * * * * * * |
@reboot |
Run once at startup. | ✕ |
Expression | Description |
---|---|
0 11 11 11 11 ? * |
Run every November 11th at 11:11am. |
59 59 23 31 12 ? * |
Run at every turn of the year. |
0 0 0 ? * LW * |
Run at every last business day on the month. |
0 0 0 ? * 5L * |
Run at every last Friday on the month. |
0 0 0 29 2 ? * |
Run every February 29th on every leap year. |
0 0 R * * * * |
Run once a day at a random hour. |
0 0 2-6/R * * * * |
Run once a day at a random hour between 2:00am and 6:00am. |
import "github.com/alex-schneider/cron"
func main() {
ctx := context.Background()
ch, err := cron.NewJobCh(ctx, "@hourly")
if err != nil {
// Handle err
}
myLoop:
for {
select {
case job := <-ch:
switch job.State {
case int(cron.StateFound):
go func() { /* ... */ }() // Trigger some job...
case int(cron.StateNoMatches): // "* * * * * * 2021"
fallthrough
case int(cron.StateOnceExec): // "@reboot"
break myLoop // Handle an end of a job...
}
case <-ctx.Done():
/* ... */
}
}
}