[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Extended example "3.2.3 Every second Sunday"
From: |
Felix Lechner |
Subject: |
Extended example "3.2.3 Every second Sunday" |
Date: |
Fri, 01 Dec 2023 09:14:47 -0800 |
Hi,
Thanks for mcron! You maintain a cool and nifty program that dovetails
neatly with GNU Guix. I love it!
For some time, I have wondered about the example in Chapter 3.2.3 in the
manual. [1] It is suppposed to schedule "my-program" on the second
Sunday of every month:
(job (lambda (current-time)
(let* ((next-month (next-month-from current-time))
(first-day (tm:wday (localtime next-month)))
(second-sunday (if (eqv? first-day 0)
7
(- 14 first-day))))
(+ next-month (* 24 60 60 second-sunday))))
"my-program")
The manual also asks interested readers to think about how the code
works. Well, I loaded the code into a Guile REPL. I'm not sure it's
working the way I expect.
Today is December 1. My epoch right now is 1701448607. The lambda above
schedules the next run for epoch 1705219200. According to 'date -d
@1705219200' from GNU coreutils, that will be on January 14 of next
year.
The way I see it, the example skips the second Sunday in December, which
is coming up on December 17. More broadly, will the example ever
schedule a run in the current month?
Perhaps it only matters for equipment that reboots from time to time.
On my system, I use a more complicated strategy: To capture the next
appointment (below, for 1 AM) I calculate the time for the current month
as well as the time for the next month. I pick the appointment for next
month only when the present time is already past the appointment for
this month. I believe it's working.
Am I overthinking the issue? Thank you!
Kind regards
Felix Lechner
[1] https://www.gnu.org/software/mcron/manual/html_node/Every-second-Sunday.html
* * *
(lambda (now)
(let* ((second-sunday-in-month
(lambda (timestamp)
(let* ((day-of-month (tm:mday (localtime timestamp)))
(beginning-of-month (- timestamp (* 24 60 60
day-of-month)))
(day-of-week (tm:wday (localtime beginning-of-month)))
(second-sunday-offset (if (eqv? 0 day-of-week)
7
(- 14 day-of-week))))
(+ beginning-of-month (* 24 60 60 second-sunday-offset)))))
(scheduled-in-month
(lambda (timestamp)
(let ((second-sunday-morning (localtime (second-sunday-in-month
timestamp))))
(set-tm:hour second-sunday-morning 1)
(set-tm:min second-sunday-morning 0)
(set-tm:sec second-sunday-morning 0)
(car (mktime second-sunday-morning)))))
(scheduled-this-month (scheduled-in-month now))
(scheduled-next-month (scheduled-in-month (next-month-from now))))
(if (< now scheduled-this-month)
scheduled-this-month
scheduled-next-month)))
- Extended example "3.2.3 Every second Sunday",
Felix Lechner <=