]> git.plutz.net Git - shellwiki/commitdiff
slightly improved recurrence calculation, put date parsing in library
authorPaul Hänsch <paul@plutz.net>
Tue, 16 Jan 2024 20:41:39 +0000 (21:41 +0100)
committerPaul Hänsch <paul@plutz.net>
Tue, 16 Jan 2024 20:41:39 +0000 (21:41 +0100)
datetime.sh [new file with mode: 0755]
macros/event

diff --git a/datetime.sh b/datetime.sh
new file mode 100755 (executable)
index 0000000..124ccfb
--- /dev/null
@@ -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
+}
index 2bf3b05770c50882a93756242737c8ca94ec4a4a..2d0a14cc115474e62386767fcfc6ea78a37f2581 100755 (executable)
@@ -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