summaryrefslogtreecommitdiff
path: root/Functions/Calendar
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2007-01-31 16:53:31 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2007-01-31 16:53:31 +0000
commit483810a525b138f91dcb11f5864817a6e9ba6699 (patch)
tree9ba7a31bd5566d01148c7db20fadf76476148323 /Functions/Calendar
parenta1476c1ee262e2b75bf12ade0e1225158e835453 (diff)
downloadzsh-483810a525b138f91dcb11f5864817a6e9ba6699.tar.gz
zsh-483810a525b138f91dcb11f5864817a6e9ba6699.zip
23142: calendar enhancements: relative times, recurring events
Diffstat (limited to 'Functions/Calendar')
-rw-r--r--Functions/Calendar/calendar88
-rw-r--r--Functions/Calendar/calendar_add31
-rw-r--r--Functions/Calendar/calendar_scandate167
-rw-r--r--Functions/Calendar/calendar_show2
-rw-r--r--Functions/Calendar/calendar_showdate48
5 files changed, 270 insertions, 66 deletions
diff --git a/Functions/Calendar/calendar b/Functions/Calendar/calendar
index 124fd9786..ea81c7ae7 100644
--- a/Functions/Calendar/calendar
+++ b/Functions/Calendar/calendar
@@ -1,21 +1,18 @@
emulate -L zsh
setopt extendedglob
-# standard ctime date/time format
-local ctime="%a %b %d %H:%M:%S %Z %Y"
-
-local line REPLY REPLY2 userange pruned
-local calendar donefile sched newfile warnstr mywarnstr
+local line restline REPLY REPLY2 userange pruned nobackup datefmt
+local calendar donefile sched newfile warnstr mywarnstr newdate
integer time start stop today ndays y m d next=-1 shown done nodone
-integer verbose warntime mywarntime t tsched i rstat remaining
-integer showcount icount
-local -a calendar_entries
+integer verbose warntime mywarntime t tcalc tsched i rstat remaining
+integer showcount icount repeating repeattime resched
+local -a calendar_entries calendar_addlines
local -a times calopts showprog lockfiles match mbegin mend
zmodload -i zsh/datetime || return 1
zmodload -i zsh/zutil || return 1
-autoload -U calendar_{read,scandate,show,lockfiles}
+autoload -U calendar_{add,read,scandate,show,lockfiles}
# Read the calendar file from the calendar-file style
zstyle -s ':datetime:calendar:' calendar-file calendar || calendar=~/calendar
@@ -27,6 +24,9 @@ zstyle -a ':datetime:calendar:' show-prog showprog ||
# Amount of time before an event when it should be flagged.
# May be overridden in individual entries
zstyle -s ':datetime:calendar:' warn-time warnstr || warnstr="0:05"
+# default to standard ctime date/time format
+zstyle -s ':datetime:calendar:' date-format datefmt ||
+ datefmt="%a %b %d %H:%M:%S %Z %Y"
if [[ -n $warnstr ]]; then
if [[ $warnstr = <-> ]]; then
@@ -169,11 +169,11 @@ strftime -s wd "%u" $start
if (( $# && !remaining )); then
if [[ $1 = +* ]]; then
- if ! calendar_scandate -ar ${1[2,-1]}; then
+ if ! calendar_scandate -a -R $start ${1[2,-1]}; then
print "$0: failed to parse relative time: $1" >&2
return 1
fi
- (( stop = start + REPLY ))
+ (( stop = REPLY ))
elif [[ $1 = <-> ]]; then
stop=$1
else
@@ -184,8 +184,8 @@ if (( $# && !remaining )); then
stop=$REPLY
fi
if (( stop < start )); then
- strftime -s REPLY $ctime $start
- strftime -s REPLY2 $ctime $stop
+ strftime -s REPLY $datefmt $start
+ strftime -s REPLY2 $datefmt $stop
print "$0: requested end time is before start time:
start: $REPLY
end: $REPLY2" >&2
@@ -224,12 +224,12 @@ autoload -Uz matchdate
if (( verbose )); then
print -n "start: "
- strftime $ctime $start
+ strftime $datefmt $start
print -n "stop: "
if (( remaining )); then
print "none"
else
- strftime $ctime $stop
+ strftime $datefmt $stop
fi
fi
@@ -248,22 +248,32 @@ fi
# REPLY2 to the line with the date and time removed.
calendar_scandate -as $line || continue
(( t = REPLY ))
+ restline=$REPLY2
# Look for specific warn time.
- pruned=${REPLY2#(|*[[:space:],])WARN[[:space:]]}
+ pruned=${restline#(|*[[:space:],])WARN[[:space:]]}
(( mywarntime = warntime ))
mywarnstr=$warnstr
- if [[ $pruned != $REPLY2 ]]; then
- if calendar_scandate -ars $pruned; then
- (( mywarntime = REPLY ))
+ if [[ $pruned != $restline ]]; then
+ if calendar_scandate -asm -R $t $pruned; then
+ (( mywarntime = t - REPLY ))
mywarnstr=${pruned%%"$REPLY2"}
fi
fi
+ # Look for a repeat time.
+ (( repeating = 0 ))
+ pruned=${restline#(|*[[:space:],])RPT[[:space:]]}
+ if [[ $pruned != $restline ]]; then
+ if calendar_scandate -a -R $t $pruned; then
+ (( repeattime = REPLY, repeating = 1 ))
+ fi
+ fi
+
if (( verbose )); then
print "Examining: $line"
print -n " Date/time: "
- strftime $ctime $t
+ strftime $datefmt $t
if [[ -n $sched ]]; then
print " Warning $mywarntime seconds ($mywarnstr) before"
fi
@@ -272,7 +282,9 @@ fi
if (( t >= start && (remaining || t <= stop || icount < showcount) ))
then
$showprog $start $stop "$line"
- (( shown = 1, icount++ ))
+ (( icount++ ))
+ # Doesn't count as "shown" unless the event has now passed.
+ (( t <= EPOCHSECONDS )) && (( shown = 1 ))
elif [[ -n $sched ]]; then
(( tsched = t - mywarntime ))
if (( tsched >= start && tsched <= stop)); then
@@ -280,22 +292,36 @@ fi
fi
fi
if [[ -n $sched ]]; then
- if (( t - mywarntime > EPOCHSECONDS )); then
+ if (( shown && repeating )); then
+ # Done and dusted, but a repeated event is due.
+ strftime -s newdate $datefmt $repeattime
+ calendar_addlines+=("$newdate$restline")
+
+ # We'll add this back in below, but we check in case the
+ # repeated event is the next one due. It's not
+ # actually a disaster if there's an error and we fail
+ # to add the time. Always try to reschedule this event.
+ (( tcalc = repeattime, resched = 1 ))
+ else
+ (( tcalc = t ))
+ fi
+
+ if (( tcalc - mywarntime > EPOCHSECONDS )); then
# schedule for a warning
- (( tsched = t - mywarntime ))
+ (( tsched = tcalc - mywarntime, resched = 1 ))
else
# schedule for event itself
- (( tsched = t ))
+ (( tsched = tcalc ))
+ # but don't schedule unless the event has not yet been shown.
+ (( !shown )) && (( resched = 1 ))
fi
- if (( (tsched > EPOCHSECONDS || ! shown) &&
- (next < 0 || tsched < next) )); then
+ if (( resched && (next < 0 || tsched < next) )); then
(( next = tsched ))
fi
fi
if [[ -n $donefile ]]; then
- if (( t <= EPOCHSECONDS && shown )); then
+ if (( shown )); then
# Done and dusted.
- # TODO: handle repeated times from REPLY2.
if ! print -r $line >>$donefile; then
if (( done != 3 )); then
(( done = 3 ))
@@ -346,9 +372,15 @@ New calendar left in $newfile." >&2
Old calendar left in $calendar.old." >&2
(( rstat = 1 ))
fi
+ nobackup=-B
elif [[ -n $donefile ]]; then
rm -f $newfile
fi
+
+ # Reschedule repeating events.
+ for line in $calendar_addlines; do
+ calendar_add -L $nobackup $line
+ done
} always {
(( ${#lockfiles} )) && rm -f $lockfiles
}
diff --git a/Functions/Calendar/calendar_add b/Functions/Calendar/calendar_add
index f7f60e136..8e6eca8b6 100644
--- a/Functions/Calendar/calendar_add
+++ b/Functions/Calendar/calendar_add
@@ -10,12 +10,29 @@
emulate -L zsh
setopt extendedglob
-local calendar newfile REPLY lastline
+local calendar newfile REPLY lastline opt
local -a calendar_entries lockfiles
-integer newdate done rstat
+integer newdate done rstat nolock nobackup
autoload -U calendar_{read,lockfiles,scandate}
+while getopts "BL" opt; do
+ case $opt in
+ (B)
+ nobackup=1
+ ;;
+
+ (L)
+ nolock=1
+ ;;
+
+ (*)
+ return 1
+ ;;
+ esac
+done
+shift $(( OPTIND - 1 ))
+
# Read the calendar file from the calendar-file style
zstyle -s ':datetime:calendar_add:' calendar-file calendar ||
calendar=~/calendar
@@ -31,7 +48,7 @@ fi
# start of block for following always to clear up lockfiles.
{
- calendar_lockfiles $calendar || return 1
+ (( nolock )) || calendar_lockfiles $calendar || return 1
if [[ -f $calendar ]]; then
calendar_read $calendar
@@ -48,10 +65,12 @@ fi
done
(( done )) || print -r -- "$*"
} >$newfile
- if ! mv $calendar $calendar.old; then
- print "Couldn't back up $calendar to $calendar.old.
+ if (( ! nobackup )); then
+ if ! mv $calendar $calendar.old; then
+ print "Couldn't back up $calendar to $calendar.old.
New calendar left in $newfile." >&2
- (( rstat = 1 ))
+ (( rstat = 1 ))
+ fi
fi
else
print -r -- $line >$newfile
diff --git a/Functions/Calendar/calendar_scandate b/Functions/Calendar/calendar_scandate
index 825aaf65b..53d0a9edf 100644
--- a/Functions/Calendar/calendar_scandate
+++ b/Functions/Calendar/calendar_scandate
@@ -46,7 +46,7 @@
# HH:MM.SS[.FFFFF] [am|pm|a.m.|p.m.]
# in which square brackets indicate optional elements, possibly with
# alternatives. Fractions of a second are recognised but ignored.
-# Unless -r is given (see below), a date is mandatory but a time of day is
+# Unless -r or -R are given (see below), a date is mandatory but a time of day is
# not; the time returned is at the start of the date.
#
# Time zones are not handled, though if one is matched following a time
@@ -122,10 +122,12 @@
# are optional, but are required between items, although a comma
# may be used (with or without spaces).
#
-# Note that a year here is 365.25 days and a month is 30 days. TODO:
-# improve this by passing down base time and adjusting. (This will
-# be crucial for events repeating monthly.) TODO: it then makes
-# sense to make PERIODly = 1 PERIOD (also for PERIOD = dai!)
+# Note that a year here is 365.25 days and a month is 30 days.
+#
+# With -R start_time, a relative time is parsed and start_time is treated
+# as the start of the period. This allows months and years to be calculated
+# accurately. If the option -m (minus) is also given the relative time is
+# taken backwards from the start time.
#
# This allows forms like:
# 30 years 3 months 4 days 3:42:41
@@ -151,7 +153,9 @@ local tspat_noanchor="(|*${tschars})"
# separator characters between elements. comma is fairly
# natural punctuation; otherwise only allow whitespace.
local schars="[.,[:space:]]"
-local daypat="${schars}#(sun|mon|tue|wed|thu|fri|sat)[a-z]#${schars}#"
+local -a dayarr
+dayarr=(sun mon tue wed thu fri sat)
+local daypat="${schars}#((#B)(${(j.|.)dayarr})[a-z]#~month*)"
# Start pattern for date: treat , as space for simplicity. This
# is illogical at the start but saves lots of minor fiddling later.
# Date start pattern when anchored at the start.
@@ -160,7 +164,7 @@ local daypat="${schars}#(sun|mon|tue|wed|thu|fri|sat)[a-z]#${schars}#"
# (The problem in the other case is that matching anything before
# the day of the week is greedy, so the day of the week gets ignored
# if it's optional.)
-local dspat_anchor="(|(#B)${daypat}(#b)${schars}#)"
+local dspat_anchor="(|(#B)(${daypat}|)(#b)${schars}#)"
local dspat_anchor_noday="(|${schars}#)"
# Date start pattern when not anchored at the start.
local dspat_noanchor="(|*${schars})"
@@ -170,10 +174,10 @@ local repat="(|s)(|${schars}*)"
# of the system for the purpose of finding out where they occur.
# We may need some completely different heuristic.
local monthpat="(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]#"
-# days, not handled but we need to ignore them. also not localized.
+integer daysecs=$(( 24 * 60 * 60 ))
-integer year month day hour minute second then
-local opt line orig_line mname MATCH MBEGIN MEND tz
+integer year year2 month month2 day day2 hour minute second then nth wday wday2
+local opt line orig_line mname MATCH MBEGIN MEND tz test
local -a match mbegin mend
# Flags that we found a date or a time (maybe a relative time)
integer date_found time_found
@@ -183,9 +187,10 @@ integer time_ok
# These are actual character indices as zsh would normally use, i.e.
# line[time_start,time_end] is the string for the time.
integer time_start time_end date_start date_end
-integer anchor anchor_end debug relative reladd setvar
+integer anchor anchor_end debug setvar
+integer relative relative_start reladd reldate relsign=1
-while getopts "aAdrst" opt; do
+while getopts "aAdmrR:st" opt; do
case $opt in
(a)
# anchor
@@ -202,10 +207,21 @@ while getopts "aAdrst" opt; do
(( debug = 1 ))
;;
+ (m)
+ # relative with negative offsets
+ (( relsign = -1 ))
+ ;;
+
(r)
+ # relative with no fixed start
(( relative = 1 ))
;;
+ (R)
+ # relative with fixed start supplied
+ (( relative_start = OPTARG, relative = 2 ))
+ ;;
+
(s)
(( setvar = 1 ))
;;
@@ -381,7 +397,7 @@ if (( relative == 0 )); then
;;
# Look for WEEKDAY
- ((#bi)${~dspat_noday}(${~daypat})*)
+ ((#bi)${~dspat_noday}(${~daypat})(|${~schars})*)
integer wday_now wday
local wdaystr=${(L)match[3]}
date_start=$mbegin[2] date_end=$mend[2]
@@ -405,15 +421,22 @@ if (( relative == 0 )); then
;;
# Look for "today", "yesterday", "tomorrow"
- ((#bi)${~dspat_noday}(yesterday|today|tomorrow)(|${schars})*)
+ ((#bi)${~dspat_noday}(yesterday|today|tomorrow|now)(|${~schars})*)
(( then = EPOCHSECONDS ))
case ${(L)match[2]} in
(yesterday)
- (( then -= 24 * 60 * 60 ))
+ (( then -= daysecs ))
;;
(tomorrow)
- (( then += 24 * 60 * 60 ))
+ (( then += daysecs ))
+ ;;
+
+ (now)
+ time_found=1 time_end=0 time_start=1
+ strftime -s hour "%H" $then
+ strftime -s minute "%M" $then
+ strftime -s second "%S" $then
;;
esac
strftime -s year "%Y" $then
@@ -429,7 +452,7 @@ if (( date_found || (time_ok && time_found) )); then
# date found
# see if there's a day at the start
if (( date_found )); then
- if [[ ${line[1,$date_start-1]} = (#bi)${~daypat} ]]; then
+ if [[ ${line[1,$date_start-1]} = (#bi)${~daypat}${~schars}# ]]; then
date_start=$mbegin[1]
fi
line=${line[1,$date_start-1]}${line[$date_end+1,-1]}
@@ -512,38 +535,117 @@ if (( date_found || (time_ok && time_found) )); then
fi
if (( relative )); then
- if [[ $line = (#bi)${~dspat}(<->)[[:blank:]]#(y|yr|year)${~repat} ]]; then
- (( reladd += ((365*4+1) * 24 * 60 * 60 * ${match[2]} + 1) / 4 ))
+ if (( relative == 2 )); then
+ # Relative years and months are variable, and we may need to
+ # be careful about days.
+ strftime -s year "%Y" $relative_start
+ strftime -s month "%m" $relative_start
+ strftime -s day "%d" $relative_start
+ strftime -rs then "%Y:%m:%d" "${year}:${month}:${day}"
+ fi
+ if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(y|yr|year|yearly)${~repat} ]]; then
+ [[ -z $match[2] ]] && match[2]=1
+ if (( relative == 2 )); then
+ # We need the difference between relative_start & the
+ # time ${match[2]} years later. This means keeping the month and
+ # day the same and changing the year.
+ (( year2 = year + relsign * ${match[2]} ))
+ strftime -rs reldate "%Y:%m:%d" "${year2}:${month}:${day}"
+
+ # If we've gone from a leap year to a non-leap year, go back a day.
+ strftime -s month2 "%m" $reldate
+ (( month2 != month )) && (( reldate -= daysecs ))
+
+ # Keep this as a difference for now since we may need to add in other stuff.
+ (( reladd += reldate - then ))
+ else
+ (( reladd += relsign * ((365*4+1) * daysecs * ${match[2]} + 1) / 4 ))
+ fi
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
time_found=1
fi
- if [[ $line = (#bi)${~dspat}(<->)[[:blank:]]#(mth|mon|mnth|month)${~repat} ]]; then
- (( reladd += 30 * 24 * 60 * 60 * ${match[2]} ))
+ if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(mth|mon|mnth|month|monthly)${~repat} ]]; then
+ [[ -z $match[2] ]] && match[2]=1
+ if (( relative == 2 )); then
+ # Need to add on ${match[2]} months as above.
+ (( month2 = month + relsign * ${match[2]} ))
+ if (( month2 <= 0 )); then
+ # going backwards beyond start of given year
+ (( year2 = year + month2 / 12 - 1, month2 = month2 + (year-year2)*12 ))
+ else
+ (( year2 = year + (month2 - 1)/ 12, month2 = (month2 - 1) % 12 + 1 ))
+ fi
+ strftime -rs reldate "%Y:%m:%d" "${year2}:${month2}:${day}"
+
+ # If we've gone past the end of the month because it was too short,
+ # we have two options (i) get the damn calendar fixed (ii) wind
+ # back to the end of the previous month. (ii) is easier for now.
+ if (( day > 28 )); then
+ while true; do
+ strftime -s day2 "%d" $reldate
+ # There are only up to 3 days in it, so just wind back one at a time.
+ # Saves counting.
+ (( day2 >= 28 )) && break
+ (( reldate -= daysecs ))
+ done
+ fi
+
+ (( reladd += reldate - then ))
+ else
+ (( reladd += relsign * 30 * daysecs * ${match[2]} ))
+ fi
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
time_found=1
fi
- if [[ $line = (#bi)${~dspat}(<->)[[:blank:]]#(w|wk|week)${~repat} ]]; then
- (( reladd += 7 * 24 * 60 * 60 * ${match[2]} ))
+ if [[ $relative = 2 && $line = (#bi)${~dspat_noday}(<->)(th|rd|st)(${~daypat})(|${~schars}*) ]]; then
+ nth=$match[2]
+ test=${(L)${${match[4]##${~schars}#}%%${~schars}#}[1,3]}
+ wday=${dayarr[(I)$test]}
+ if (( wday )); then
+ line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
+ time_found=1
+ # We want weekday 0 to 6
+ (( wday-- ))
+ (( reldate = relative_start + reladd ))
+ strftime -s year2 "%Y" $reldate
+ strftime -s month2 "%m" $reldate
+ # Find day of week of the first of the month we've landed on.
+ strftime -rs then "%Y:%m:%d" "${year2}:${month2}:1"
+ strftime -s wday2 "%w" $then
+ # Calculate day of month
+ (( day = 1 + (wday - wday2) + (nth - 1) * 7 ))
+ (( wday < wday2 )) && (( day += 7 ))
+ # whereas the day of the month calculated so far is...
+ strftime -s day2 "%d" $reldate
+ # so we need to compensate by...
+ (( reladd += (day - day2) * daysecs ))
+ fi
+ fi
+ if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(w|wk|week|weekly)${~repat} ]]; then
+ [[ -z $match[2] ]] && match[2]=1
+ (( reladd += relsign * 7 * daysecs * ${match[2]} ))
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
time_found=1
fi
- if [[ $line = (#bi)${~dspat}(<->)[[:blank:]]#(d|dy|day)${~repat} ]]; then
- (( reladd += 24 * 60 * 60 * ${match[2]} ))
+ if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(d|dy|day|daily)${~repat} ]]; then
+ [[ -z $match[2] ]] && match[2]=1
+ (( reladd += relsign * daysecs * ${match[2]} ))
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
time_found=1
fi
- if [[ $line = (#bi)${~dspat}(<->)[[:blank:]]#(h|hr|hour)${~repat} ]]; then
- (( reladd += 60 * 60 * ${match[2]} ))
+ if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(h|hr|hour|hourly)${~repat} ]]; then
+ [[ -z $match[2] ]] && match[2]=1
+ (( reladd += relsign * 60 * 60 * ${match[2]} ))
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
time_found=1
fi
- if [[ $line = (#bi)${~dspat}(<->)[[:blank:]]#(min|minute)${~repat} ]]; then
- (( reladd += 60 * ${match[2]} ))
+ if [[ $line = (#bi)${~dspat}(<->)[[:space:]]#(min|minute)${~repat} ]]; then
+ (( reladd += relsign * 60 * ${match[2]} ))
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
time_found=1
fi
- if [[ $line = (#bi)${~dspat}(<->)[[:blank:]]#(s|sec|second)${~repat} ]]; then
- (( reladd += ${match[2]} ))
+ if [[ $line = (#bi)${~dspat}(<->)[[:space:]]#(s|sec|second)${~repat} ]]; then
+ (( reladd += relsign * ${match[2]} ))
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
time_found=1
fi
@@ -558,7 +660,8 @@ if (( relative )); then
return 1
fi
fi
- (( REPLY = reladd + (hour * 60 + minute) * 60 + second ))
+ # relative_start is zero if we're not using it
+ (( REPLY = relative_start + reladd + (hour * 60 + minute) * 60 + second ))
[[ -n $setvar ]] && REPLY2=$line
return 0
fi
diff --git a/Functions/Calendar/calendar_show b/Functions/Calendar/calendar_show
index f731d07a5..77f025ec5 100644
--- a/Functions/Calendar/calendar_show
+++ b/Functions/Calendar/calendar_show
@@ -22,3 +22,5 @@ if [[ -n $DISPLAY && $start -eq $stop ]]; then
($cmd "$*" &)
fi
fi
+
+return 0
diff --git a/Functions/Calendar/calendar_showdate b/Functions/Calendar/calendar_showdate
new file mode 100644
index 000000000..b35a0a91f
--- /dev/null
+++ b/Functions/Calendar/calendar_showdate
@@ -0,0 +1,48 @@
+emulate -L zsh
+setopt extendedglob
+
+local optm datefmt
+integer optr replyset
+
+zstyle -s ':datetime:calendar_showdate:' date-format datefmt ||
+ datefmt="%a %b %d %H:%M:%S %Z %Y"
+
+if [[ $1 = -r ]]; then
+ shift
+ REPLY=0
+ optr=1
+else
+ local REPLY
+fi
+
+if (( ! $# )); then
+ print "Usage: $0 datespec [ ... ]" >&2
+ return 1
+fi
+
+while (( $# )); do
+ optm=
+ if [[ $1 = [-+]* ]]; then
+ # relative
+ [[ $1 = -* ]] && optm=-m
+ 1=${1[2,-1]}
+ # if this is the first argument, use current time
+ # don't make assumptions about type of reply in case global
+ if (( ! replyset )); then
+ REPLY=$EPOCHSECONDS
+ replyset=1
+ fi
+ fi
+
+ if (( replyset )); then
+ calendar_scandate $optm -R $REPLY -aA $1 || return 1
+ replyset=1
+ else
+ calendar_scandate -aA $1 || return 1
+ fi
+
+ shift
+done
+
+(( optr )) && return
+strftime $datefmt $REPLY