Schedule cronjob for the first Monday of every month, the funky way
blog.healthchecks.io
blog.healthchecks.io
Here are some thing that's possible:
Weekly on Tuesday and Thursday for five weeks
Every other week on Monday, Wednesday, and Friday until December 24, 1997, starting on Monday, September 1, 1997
Every other month on the first and last Sunday of the month for 10 occurrences
Every 18 months on the 10th thru 15th of the month
(Almost all of those are well supported by the UI on Apple Calendar and Google Calendar.)I only wish it could incorporate astronomical phenomena such as phases of the moon into account. Wouldn't it be great if it can express concepts like "the first Sunday after the full moon that occurs on or after the spring equinox" (no I'm not making this example up)?
0 9 * * * anvandare is-today-the-day.py && celebrate.sh
With is-today-the-day.py being: #!/usr/bin/env python3
import sys
from dateutil.easter import easter
from datetime import datetime as dt
today = dt.today().date()
(easter(2023) - today).days == 0 and sys.exit(0) or sys.exit(1)
Or, if we didn't have the easter function already (just adding this because it was fun to work it out): #!/usr/bin/env python3
import sys, ephem as e, datetime as dt
setup = '2022/09/25'
date = (e.next_full_moon(e.next_equinox(setup))).datetime()
easter2023 = (date + dt.timedelta(7 - date.isoweekday())).date()
today = dt.datetime.today().date()
(easter2023 - today).days == 0 and sys.exit(0) or sys.exit(1)https://en.m.wikipedia.org/wiki/Date_of_Easter
… and you would still be wrong, depending in which country it gets calculated.
You probably could hack something up around rfc 7529 (non-gregorian recurrence)
https://crontab.guru/#0_0_*/100,1-7_*_MON
This is a nice hack, but readability has gone out the window and it's really just much safer to fail early in the job itself.
I guess I’m confused. Isn’t that exactly correct?
There is surely a better DSL for this.
Personally I like ruby’s whenever gem, that transpiles to cron, where you can do things like
every :sunday, at: '12pm' do
foo
end
But I guess we are just stuck with crontab OnCalendar=Mon *-*-* 12:00:00
Here's the list of examples from man systemd.time: The following special expressions may be used as shorthands for longer normalized forms:
minutely → *-*-* *:*:00
hourly → *-*-* *:00:00
daily → *-*-* 00:00:00
monthly → *-*-01 00:00:00
weekly → Mon *-*-* 00:00:00
yearly → *-01-01 00:00:00
quarterly → *-01,04,07,10-01 00:00:00
semiannually → *-01,07-01 00:00:00
Examples for valid timestamps and their normalized form:
Sat,Thu,Mon..Wed,Sat..Sun → Mon..Thu,Sat,Sun *-*-* 00:00:00
Mon,Sun 12-*-* 2,1:23 → Mon,Sun 2012-*-* 01,02:23:00
Wed *-1 → Wed *-*-01 00:00:00
Wed..Wed,Wed *-1 → Wed *-*-01 00:00:00
Wed, 17:48 → Wed *-*-* 17:48:00
Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
*-*-7 0:0:0 → *-*-07 00:00:00
10-15 → *-10-15 00:00:00
monday *-12-* 17:00 → Mon *-12-* 17:00:00
Mon,Fri *-*-3,1,2 *:30:45 → Mon,Fri *-*-01,02,03 *:30:45
12,14,13,12:20,10,30 → *-*-* 12,13,14:10,20,30:00
12..14:10,20,30 → *-*-* 12..14:10,20,30:00
mon,fri *-1/2-1,3 *:30:45 → Mon,Fri *-01/2-01,03 *:30:45
03-05 08:05:40 → *-03-05 08:05:40
08:05:40 → *-*-* 08:05:40
05:40 → *-*-* 05:40:00
Sat,Sun 12-05 08:05:40 → Sat,Sun *-12-05 08:05:40
Sat,Sun 08:05:40 → Sat,Sun *-*-* 08:05:40
2003-03-05 05:40 → 2003-03-05 05:40:00
05:40:23.4200004/3.1700005 → *-*-* 05:40:23.420000/3.170001
2003-02..04-05 → 2003-02..04-05 00:00:00
2003-03-05 05:40 UTC → 2003-03-05 05:40:00 UTC
2003-03-05 → 2003-03-05 00:00:00
03-05 → *-03-05 00:00:00
hourly → *-*-* *:00:00
daily → *-*-* 00:00:00
daily UTC → *-*-* 00:00:00 UTC
monthly → *-*-01 00:00:00
weekly → Mon *-*-* 00:00:00
weekly Pacific/Auckland → Mon *-*-* 00:00:00 Pacific/Auckland
yearly → *-01-01 00:00:00
annually → *-01-01 00:00:00
*:2/3 → *-*-* *:02/3:00i'm not familiar with the systemd syntax but according to the desc you provided, wouldnt that be a weekly monday job, not "first monday of the month" the article wanted?
$ systemd-analyze calendar 'Mon *-*-1..7 10:00'
Original form: Mon *-*-1..7 10:00
Normalized form: Mon *-*-01..07 10:00:00
Next elapse: Mon 2022-10-03 10:00:00 BST
(in UTC): Mon 2022-10-03 09:00:00 UTC
From now: 1 week 1 day left
Credit: https://www.redpill-linpro.com/sysadvent/2016/12/07/systemd-...I know, with eventbridge and lambdas this problem could be alleviated a bit, since eventbridge uses cron syntax but with some added bells and whistles ( https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-...) which would make the expression for the first monday of each month much easier to write.
I’m not affiliated, just a happy user. Having alerts when your cron fails is quite nice.
R/.../FREQ=MO;BYDA=1MO