From d1513c4d506a8628fb6037bc504960c6a4734f29 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Fri, 2 Feb 2024 19:54:41 +0100 Subject: [PATCH] nth-last-weekday recurrence --- datetime.sh | 25 +++++++++++++++++++++++++ macros/calendar | 26 +++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/datetime.sh b/datetime.sh index 124ccfb..2b4bba9 100755 --- a/datetime.sh +++ b/datetime.sh @@ -74,3 +74,28 @@ istime(){ printf '%02i:%02i\n' "${h#0}" "${m#0}" return 0 } + +numdays(){ + # return number of days in a month (i.e. 28, 29, 30, or 31) + local y="$1" m="${2#0}" + + case $m in + 1|3|5|7|10|12) + printf 31\\n + ;; + 4|6|8|9|11) + printf 30\\n + ;; + 2) if [ "$((y % 400))" -eq 0 ]; then + printf 29\\n + elif [ "$((y % 100))" -eq 0 ]; then + printf 28\\n + elif [ "$((y % 4))" -eq 0 ]; then + printf 29\\n + else + printf 28\\n + fi + ;; + *) return 1;; + esac +} diff --git a/macros/calendar b/macros/calendar index 3d013f2..5a48675 100755 --- a/macros/calendar +++ b/macros/calendar @@ -182,20 +182,40 @@ rrex_weekday() { nth=$(( ( $(date -ud @$start +%_d) - 1) / 7)) - nend=$(( 0 * 604800 - (dstart - end) % (rrfreq * 604800) + dstart )) + nend=$(( 0 * 604800 - (dstart - end) % 604800 + dstart )) nstart=$(( start - end + nend)) while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do [ "$nstart" -ge "$start" -a "$nstart" -ge "$dstart" ] \ && [ "$(( ( $(date -ud @$nstart +%_d) -1) / 7 ))" -eq "$nth" ] \ && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" - nstart="$((nstart + rrfreq * 7 * 86400))" + nstart="$((nstart + 7 * 86400))" nend="$((nstart - start + end))" done } rrex_lastweekday() { -: + # helper for rrexpand: Nth last weekday of a month (e.g. 2nd last tuesday, etc.) + local nstart nend Y m d nth + + read Y m d <<-EOF + $(date -ud @$start +"%Y %_m %_d") + EOF + nth=$(( ( $(numdays $Y $m) - d ) / 7)) + + nend=$(( 0 * 604800 - (dstart - end) % 604800 + dstart )) + nstart=$(( start - end + nend)) + + while [ "$nstart" -lt "$rrend" -a "$nstart" -lt "$dend" ]; do + read Y m d <<-EOF + $(date -ud @$nstart +"%Y %_m %_d") + EOF + [ "$nstart" -ge "$start" -a "$nstart" -ge "$dstart" ] \ + && [ "$(( ( $(numdays $Y $m) - d ) / 7 ))" -eq "$nth" ] \ + && printf '%i %i %s %s\n' "$nstart" "$nend" "$evtitle" "$evlink" + nstart="$((nstart + 7 * 86400))" + nend="$((nstart - start + end))" + done } events="$( -- 2.39.2