From 27059a1286b67a507a4fac19ac4b5af2fccc884e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Paul=20H=C3=A4nsch?= Date: Tue, 16 Jan 2024 21:41:39 +0100 Subject: [PATCH] slightly improved recurrence calculation, put date parsing in library --- datetime.sh | 76 ++++++++++++++++++++++++++++++++++ macros/event | 113 +++++++++++++++++---------------------------------- 2 files changed, 114 insertions(+), 75 deletions(-) create mode 100755 datetime.sh diff --git a/datetime.sh b/datetime.sh new file mode 100755 index 0000000..124ccfb --- /dev/null +++ b/datetime.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +[ "$include_datetime" ] && return 0 +include_datetime="$0" + +# Copyright 2023 - 2024 Paul Hänsch +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +isdate(){ + local date="$1" y m d + + if printf %s "$date" \ + | grep -xEq '[0-9]{4}-((01|03|05|07|08|10|12)-(0[1-9]|[12][0-9]|3[01])|(04|06|09|11)-(0[1-9]|[12][0-9]|30)|02-(0[1-9]|[12][0-9]))' + then # y-m-d (ISO Date) + y="${date%%-*}" d="${date##*-}" m="${date%-*}" m="${m#*-}" + elif printf %s "$date" \ + | grep -xEq '((0?1|0?3|0?5|0?7|0?8|10|12)/(0?[1-9]|[12][0-9]|3[01])|(0?4|0?6|0?9|11)/(0?[1-9]|[12][0-9]|30)|0?2-(0[1-9]|[12][0-9]))/([0-9]{2}|[0-9]{4})' + then # m/d/y (US Date) + y="${date##*/}" m="${date%%/*}" d="${date%/*}" d="${d#*/}" + elif printf %s "$date" \ + | grep -xEq '((0?[1-9]|[12][0-9]|3[01])[\./](0?1|0?3|0?5|0?7|0?8|10|12)|(0?[1-9]|[12][0-9]|30)[\./](0?4|0?6|0?9|11)|(0[1-9]|[12][0-9])[\./]0?2)[\./]([0-9]{2}|[0-9]{4})' + then # d/m/y or d.m.y (European Date / German Date) + y="${date##*.}" d="${date%%.*}" m="${date%.*}" m="${m#*.}" + else + return 1 + fi + [ $y -lt 100 -a $y -gt 50 ] && y=$((y + 1900)) + [ $y -lt 100 -a $y -le 50 ] && y=$((y + 2000)) + date="$(printf "%04i-%02i-%02i" $y ${m#0} ${d#0})" + + # leap year + if [ "$m" -eq 2 -a "$d" -eq 29 ]; then + if [ "$((y % 400))" -eq 0 ]; then + : + elif [ "$((y % 100))" -eq 0 ]; then + return 1 + elif [ "$((y % 4))" -eq 0 ]; then + : + else + return 1 + fi + fi + + printf '%04i-%02i-%02i\n' "$y" "${m#0}" "${d#0}" + return 0 +} + +istime(){ + time="$1" h= m= + + if printf %s "$time" | grep -xEq '(0?[1-9]|1[012])(:[0-5][0-9])? ?(am|AM)\.?'; then + time="${time%?[aA][mM]}" h="${time%:*}" h="$(h % 12)" + [ "$h" != "$time" ] && m="${time#*:}" || m=0 + elif printf %s "$time" | grep -xEq '(0?[1-9]|1[012])(:[0-5][0-9])? ?(pm|PM)\.?'; then + time="${time%?[aA][mM]}" h="${time%:*}" h="$(h % 12 + 12)" + [ "$h" != "$time" ] && m="${time#*:}" || m=0 + elif printf %s "$time" | grep -xEq '(0?[0-9]|1[0-9]|2[0-3]):[0-5][0-9]'; then + time="${time%?[aA][mM]}" h="${time%:*}" m="${time#*:}" + else + return 1 + fi + + printf '%02i:%02i\n' "${h#0}" "${m#0}" + return 0 +} diff --git a/macros/event b/macros/event index 2bf3b05..2d0a14c 100755 --- a/macros/event +++ b/macros/event @@ -1,7 +1,8 @@ #!/bin/sh . $_EXEC/cgilite/cgilite.sh -. $_EXEC/cgilite/session.sh +. $_EXEC/cgilite/storage.sh +. $_EXEC/datetime.sh _(){ printf %s\\n "$*"; } [ "${LANGUAGE}" -a -r "${_EXEC}/l10n/${LANGUAGE}.sh" ] && . "${_EXEC}/l10n/${LANGUAGE}.sh" @@ -11,64 +12,6 @@ rec_freq= rec_int= error_msg= rec_end= title= start= end= nstart= nend= -isdate(){ - local date="$1" y m d - - if printf %s "$date" \ - | grep -xEq '[0-9]{4}-((01|03|05|07|08|10|12)-(0[1-9]|[12][0-9]|3[01])|(04|06|09|11)-(0[1-9]|[12][0-9]|30)|02-(0[1-9]|[12][0-9]))' - then # y-m-d (ISO Date) - y="${date%%-*}" d="${date##*-}" m="${date%-*}" m="${m#*-}" - elif printf %s "$date" \ - | grep -xEq '((0?1|0?3|0?5|0?7|0?8|10|12)/(0?[1-9]|[12][0-9]|3[01])|(0?4|0?6|0?9|11)/(0?[1-9]|[12][0-9]|30)|0?2-(0[1-9]|[12][0-9]))/([0-9]{2}|[0-9]{4})' - then # m/d/y (US Date) - y="${date##*/}" m="${date%%/*}" d="${date%/*}" d="${d#*/}" - elif printf %s "$date" \ - | grep -xEq '((0?[1-9]|[12][0-9]|3[01])[\./](0?1|0?3|0?5|0?7|0?8|10|12)|(0?[1-9]|[12][0-9]|30)[\./](0?4|0?6|0?9|11)|(0[1-9]|[12][0-9])[\./]0?2)[\./]([0-9]{2}|[0-9]{4})' - then # d/m/y or d.m.y (European Date / German Date) - y="${date##*.}" d="${date%%.*}" m="${date%.*}" m="${m#*.}" - else - return 1 - fi - [ $y -lt 100 -a $y -gt 50 ] && y=$((y + 1900)) - [ $y -lt 100 -a $y -le 50 ] && y=$((y + 2000)) - date="$(printf "%04i-%02i-%02i" $y ${m#0} ${d#0})" - - # leap year - if [ "$m" -eq 2 -a "$d" -eq 29 ]; then - if [ "$((y % 400))" -eq 0 ]; then - : - elif [ "$((y % 100))" -eq 0 ]; then - return 1 - elif [ "$((y % 4))" -eq 0 ]; then - : - else - return 1 - fi - fi - - printf '%04i-%02i-%02i\n' "$y" "${m#0}" "${d#0}" - return 0 -} - -istime(){ - time="$1" h= m= - - if printf %s "$time" | grep -xEq '(0?[1-9]|1[012])(:[0-5][0-9])? ?(am|AM)\.?'; then - time="${time%?[aA][mM]}" h="${time%:*}" h="$(h % 12)" - [ "$h" != "$time" ] && m="${time#*:}" || m=0 - elif printf %s "$time" | grep -xEq '(0?[1-9]|1[012])(:[0-5][0-9])? ?(pm|PM)\.?'; then - time="${time%?[aA][mM]}" h="${time%:*}" h="$(h % 12 + 12)" - [ "$h" != "$time" ] && m="${time#*:}" || m=0 - elif printf %s "$time" | grep -xEq '(0?[0-9]|1[0-9]|2[0-3]):[0-5][0-9]'; then - time="${time%?[aA][mM]}" h="${time%:*}" m="${time#*:}" - else - return 1 - fi - - printf '%02i:%02i\n' "${h#0}" "${m#0}" - return 0 -} - while [ $# -gt 0 ]; do case $1 in --from|from|--start|start) if isdate "$2" && istime "$3" ; then @@ -184,19 +127,17 @@ if [ "$rec_end" ]; then rec_end="$(date -d "$rec_end" +%s)" fi -if [ -s './#events' ]; then - t1="$(stat -c %Y './#page.md')" - read t2 junk <"./#events" - if [ "$t1" -ge "$t2" ]; then - truncate -s 0 "./#events" - fi +if LOCK './#events'; then + sed -i "/^${_DATE} /!d" './#events' + evid="$(wc -l './#events' || printf 0)" + debug "PAGE: $PATH_INFO $evid" + printf '%i %i %i %i %s %i %s\n' \ + "$_DATE" "$(date -d "$start_date $start_time" +%s)" "$(date -d "$end_date $end_time" +%s)" \ + "${rec_freq:-0}" "${rec_int:-\\}" "${rec_end:--1}" "$(STRING "${PATH_INFO}#event${evid}")" \ + >>'./#events' + RELEASE './#events' fi -printf '%i %i %i %i %s %i\n' \ - "$_DATE" "$(date -d "$start_date $start_time" +%s)" "$(date -d "$end_date $end_time" +%s)" \ - "${rec_freq:-0}" "${rec_int:-\\}" "${rec_end:--1}" \ - >>'./#events' - start="$(date -d "$start_date $start_time" +%s)" end="$(date -d "$end_date $end_time" +%s)" @@ -221,30 +162,52 @@ fi EOF _m=$((_y * 12 + _m)) m=$((y * 12 + m)) while :; do - mod=$(( (_m - m) % rec_freq )); [ $mod -eq 0 ] && mod="$rec_freq"; - m=$(( rec_freq - mod + _m )) + # mod=$(( (_m - m) % rec_freq )); [ $mod -eq 0 ] && mod="$rec_freq"; + m=$(( rec_freq - ((_m - m - 1) % rec_freq + 1) + _m )) y=$((m / 12)) m=$((m % 12)); [ $m -eq 0 ] && y=$((y - 1)) m=12; nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")" - isdate "$nstart" >/dev/null && [ $(date -d "$nstart" +%s) -ge $_DATE ] && break - debug loop + if isdate "$nstart" && [ $(date -d "$nstart" +%s) -ge $_DATE ]; then + break + fi >/dev/null m=$((y * 12 + m)) _m="$((_m + rec_freq))" done nstart="$(date -d "$nstart $start_time" +%s)" nend="$((end - start + nstart))" ;; year) + { read _y _m _d; read y m d; } <<-EOF + $(date -d @$_DATE +"%Y %_m %_d" + date -d @$start +"%Y %_m %_d" + ) + EOF + while :; do + # mod=$(( ( _y - y ) % rec_freq )); [ $mod -eq 0 ] && mod="$rec_freq" + y=$(( rec_freq - ((_y - y - 1) % rec_freq + 1) + _y )) + nstart="$(printf '%04i-%02i-%02i' "$y" "$m" "$d")" + if isdate "$nstart" && [ $(date -d "$nstart" +%s) -ge $_DATE ]; then + break + fi >/dev/null + _y="$((_y + rec_freq))" + done + nstart="$(date -d "$nstart $start_time" +%s)" + nend="$((end - start + nstart))" ;; '') nstart="$start" nend="$end" ;; esac +if [ "$nstart" -gt "$rec_end" ]; then + nstart="$start" nend="$end" +fi + "$_EXEC/cgilite/html-sh.sed" <<-EOF - [div .macro .event + [div .macro .event #event${evid} [label . $(HTML "$title")] [dl [dt $(_ Start:)][dd $(date -d @$nstart +"%F %T")] [dt $(_ End:)][dd $(date -d @$nend +"%F %T")] + [dt $(_ Until:)][dd $(date -d @$rec_end +"%F %T")] ] ] EOF -- 2.39.2