mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-10-27 04:40:59 +01:00
unposted: more random calendar system fixes and improvements
This commit is contained in:
parent
7072c10ae2
commit
4b7b7f56f1
7 changed files with 189 additions and 92 deletions
12
ChangeLog
12
ChangeLog
|
|
@ -1,3 +1,15 @@
|
||||||
|
2007-03-26 Peter Stephenson <pws@csr.com>
|
||||||
|
|
||||||
|
* unposted (follow-on from 23228): Doc/Zsh/calsys.yo,
|
||||||
|
Functions/Calendar/calendar{,_edit,lockfiles,scandate,showdate}:
|
||||||
|
New calendar_edit (looks up file to edit and locks it);
|
||||||
|
calendar -a option; calendar_showdate -f fmt option;
|
||||||
|
make calendar_lockfiles use zsh/select to get higher resolution
|
||||||
|
timer to jitter delay; apply the summer time fix to
|
||||||
|
"<month>, <nth> <frob>day" as well; allow "2nd" as an
|
||||||
|
ordinal (also 1nd and 3nd, 4nd, ... since we aren't interested
|
||||||
|
in checking good English).
|
||||||
|
|
||||||
2007-03-25 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
2007-03-25 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||||
|
|
||||||
* usres/11333: Completion/Unix/Command/_ssh: users-hosts
|
* usres/11333: Completion/Unix/Command/_ssh: users-hosts
|
||||||
|
|
|
||||||
|
|
@ -309,8 +309,8 @@ subsect(Calendar system functions)
|
||||||
|
|
||||||
startitem()
|
startitem()
|
||||||
findex(calendar)
|
findex(calendar)
|
||||||
xitem(tt(calendar) [ tt(-dDsv) ] [ tt(-C) var(calfile) ] [ -n var(num) ] [ tt(-S) var(showprog) ] [ [ var(start) ] var(end) ])(
|
xitem(tt(calendar) [ tt(-adDsv) ] [ tt(-C) var(calfile) ] [ -n var(num) ] [ tt(-S) var(showprog) ] [ [ var(start) ] var(end) ])(
|
||||||
item(tt(calendar -r) [ tt(-dDrsv) ] [ tt(-C) var(calfile) ] [ -n var(num) ] [ tt(-S) var(showprog) ] [ var(start) ])(
|
item(tt(calendar -r) [ tt(-adDrsv) ] [ tt(-C) var(calfile) ] [ -n var(num) ] [ tt(-S) var(showprog) ] [ var(start) ])(
|
||||||
Show events in the calendar.
|
Show events in the calendar.
|
||||||
|
|
||||||
With no arguments, show events from the start of today until the end of
|
With no arguments, show events from the start of today until the end of
|
||||||
|
|
@ -338,6 +338,10 @@ tt(~/.zshrc) file.
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
startitem()
|
startitem()
|
||||||
|
item(tt(-a))(
|
||||||
|
Show all items in the calendar, regardless of the tt(start) and
|
||||||
|
tt(end).
|
||||||
|
)
|
||||||
item(tt(-C) var(calfile))(
|
item(tt(-C) var(calfile))(
|
||||||
Explicitly specify a calendar file instead of the value of
|
Explicitly specify a calendar file instead of the value of
|
||||||
the tt(calendar-file) style or the the default tt(~/calendar).
|
the tt(calendar-file) style or the the default tt(~/calendar).
|
||||||
|
|
@ -418,8 +422,19 @@ option tt(-L) indicates that tt(calendar_add) does not need to lock the
|
||||||
calendar file up the old one as it is already locked. These options will
|
calendar file up the old one as it is already locked. These options will
|
||||||
not usually be needed by users.
|
not usually be needed by users.
|
||||||
)
|
)
|
||||||
|
findex(calendar_edit)
|
||||||
|
item(tt(calendar_edit))(
|
||||||
|
This calls the user's editor to edit the calendar file. The editor
|
||||||
|
is given by the variable tt(VISUAL), if set, else the variable tt(EDITOR).
|
||||||
|
If the calendar scheduler was running, then after editing the file
|
||||||
|
tt(calendar -s) is called to update it.
|
||||||
|
|
||||||
|
This function locks out the calendar system during the edit.
|
||||||
|
Hence it should be used to edit the calendar file if there is any
|
||||||
|
possibility of a calendar event occurring meanwhile.
|
||||||
|
)
|
||||||
findex(calendar_showdate)
|
findex(calendar_showdate)
|
||||||
item(tt(calendar_showdate) [ tt(-r) ] var(date-spec ...))(
|
item(tt(calendar_showdate) [ tt(-r) ] [ tt(-f) var(fmt) ] var(date-spec ...))(
|
||||||
The given var(date-spec) is interpreted and the corresponding date and
|
The given var(date-spec) is interpreted and the corresponding date and
|
||||||
time printed. If the initial var(date-spec) begins with a tt(PLUS()) or
|
time printed. If the initial var(date-spec) begins with a tt(PLUS()) or
|
||||||
tt(-) it is treated as relative to the current time; var(date-spec)s after
|
tt(-) it is treated as relative to the current time; var(date-spec)s after
|
||||||
|
|
@ -427,8 +442,16 @@ the first are treated as relative to the date calculated so far and
|
||||||
a leading tt(PLUS()) is optional in that case. This allows one to
|
a leading tt(PLUS()) is optional in that case. This allows one to
|
||||||
use the system as a date calculator. For example, tt(calendar_showdate '+1
|
use the system as a date calculator. For example, tt(calendar_showdate '+1
|
||||||
month, 1st Friday') shows the date of the first Friday of next month.
|
month, 1st Friday') shows the date of the first Friday of next month.
|
||||||
|
|
||||||
With the option tt(-r) nothing is printed but the value of the date and
|
With the option tt(-r) nothing is printed but the value of the date and
|
||||||
timein seconds since the epoch is stored in the parameter tt(REPLY).
|
timein seconds since the epoch is stored in the parameter tt(REPLY).
|
||||||
|
|
||||||
|
With the option tt(-f) var(fmt) the given date/time conversion format
|
||||||
|
is passed to tt(strftime); see notes on the tt(date-format) style below.
|
||||||
|
|
||||||
|
In order to avoid ambiguity with negative relative date specifications,
|
||||||
|
options must occur in separate words; in other words, tt(-r) and tt(-f)
|
||||||
|
should not be combined in the same word.
|
||||||
)
|
)
|
||||||
findex(calendar_sort)
|
findex(calendar_sort)
|
||||||
item(tt(calendar_sort))(
|
item(tt(calendar_sort))(
|
||||||
|
|
@ -568,14 +591,24 @@ item(tt(calendar_lockfiles))(
|
||||||
Attempt to lock the files given in the argument. To prevent
|
Attempt to lock the files given in the argument. To prevent
|
||||||
problems with network file locking this is done in an ad hoc fashion
|
problems with network file locking this is done in an ad hoc fashion
|
||||||
by attempting to create a symbolic link to the file with the name
|
by attempting to create a symbolic link to the file with the name
|
||||||
var(file)tt(.lockfile). Otherwise, however, the function is not
|
var(file)tt(.lockfile). No other system level functions are used
|
||||||
specific to the calendar system. Three attempts are made to lock
|
for locking, i.e. the file can be accessed and modified by any
|
||||||
the file before giving up.
|
utility that does not use this mechanism. In particular, the user is not
|
||||||
|
prevented from editing the calendar file at the same time unless
|
||||||
|
tt(calendar_edit) is used.
|
||||||
|
|
||||||
|
Three attempts are made to lock the file before giving up. If the module
|
||||||
|
tt(zsh/zselect) is available, the times of the attempts are jittered so that
|
||||||
|
multiple instances of the calling function are unlikely to retry at the
|
||||||
|
same time.
|
||||||
|
|
||||||
The files locked are appended to the array tt(lockfiles), which should
|
The files locked are appended to the array tt(lockfiles), which should
|
||||||
be local to the caller.
|
be local to the caller.
|
||||||
|
|
||||||
If all files were successully, status zero is returned, else status one.
|
If all files were successully, status zero is returned, else status one.
|
||||||
|
|
||||||
|
This function may be used as a general file locking function, although
|
||||||
|
this will only work if only this mechanism is used to lock files.
|
||||||
)
|
)
|
||||||
findex(calendar_read)
|
findex(calendar_read)
|
||||||
item(tt(calendar_read))(
|
item(tt(calendar_read))(
|
||||||
|
|
@ -660,6 +693,11 @@ enditem()
|
||||||
texinode(Calendar Bugs)()(Calendar Utility Functions)(Calendar Function System)
|
texinode(Calendar Bugs)()(Calendar Utility Functions)(Calendar Function System)
|
||||||
sect(Bugs)
|
sect(Bugs)
|
||||||
|
|
||||||
|
As the system is based entirely on shell functions (with a little support
|
||||||
|
from the tt(zsh/datetime) module) the mechanisms used are not as robust as
|
||||||
|
those provided by a dedicated calendar utility. Consequently the user
|
||||||
|
should not rely on the shell for vital alerts.
|
||||||
|
|
||||||
There is no tt(calendar_delete) function.
|
There is no tt(calendar_delete) function.
|
||||||
|
|
||||||
There is no localization support for dates and times, nor any support
|
There is no localization support for dates and times, nor any support
|
||||||
|
|
@ -668,8 +706,6 @@ for the use of time zones.
|
||||||
Relative periods of months and years do not take into account the variable
|
Relative periods of months and years do not take into account the variable
|
||||||
number of days.
|
number of days.
|
||||||
|
|
||||||
Recurrent events are not yet supported.
|
|
||||||
|
|
||||||
The tt(calendar_show) function is currently hardwired to use tt(xmessage)
|
The tt(calendar_show) function is currently hardwired to use tt(xmessage)
|
||||||
for displaying alerts on X Window System displays. This should be
|
for displaying alerts on X Window System displays. This should be
|
||||||
configurable and ideally integrate better with the desktop.
|
configurable and ideally integrate better with the desktop.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ local line restline REPLY REPLY2 userange pruned nobackup datefmt
|
||||||
local calendar donefile sched newfile warnstr mywarnstr newdate
|
local calendar donefile sched newfile warnstr mywarnstr newdate
|
||||||
integer time start stop today ndays y m d next=-1 shown done nodone
|
integer time start stop today ndays y m d next=-1 shown done nodone
|
||||||
integer verbose warntime mywarntime t tcalc tsched i rstat remaining
|
integer verbose warntime mywarntime t tcalc tsched i rstat remaining
|
||||||
integer showcount icount repeating repeattime resched
|
integer showcount icount repeating repeattime resched showall
|
||||||
local -a calendar_entries calendar_addlines
|
local -a calendar_entries calendar_addlines
|
||||||
local -a times calopts showprog lockfiles match mbegin mend
|
local -a times calopts showprog lockfiles match mbegin mend
|
||||||
|
|
||||||
|
|
@ -96,6 +96,11 @@ while [[ ${argv[opti+1]} = -* ]]; do
|
||||||
###########################
|
###########################
|
||||||
# Options without arguments
|
# Options without arguments
|
||||||
###########################
|
###########################
|
||||||
|
(a)
|
||||||
|
# Show all entries
|
||||||
|
(( showall = 1 ))
|
||||||
|
;;
|
||||||
|
|
||||||
(d)
|
(d)
|
||||||
# Move out of date items to the done file.
|
# Move out of date items to the done file.
|
||||||
(( done = 1 ))
|
(( done = 1 ))
|
||||||
|
|
@ -279,7 +284,7 @@ fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
(( shown = 0 ))
|
(( shown = 0 ))
|
||||||
if (( t >= start && (remaining || t <= stop || icount < showcount) ))
|
if (( showall || (t >= start && (remaining || t <= stop || icount < showcount)) ))
|
||||||
then
|
then
|
||||||
$showprog $start $stop "$line"
|
$showprog $start $stop "$line"
|
||||||
(( icount++ ))
|
(( icount++ ))
|
||||||
|
|
|
||||||
21
Functions/Calendar/calendar_edit
Normal file
21
Functions/Calendar/calendar_edit
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
local editor=${VISUAL:-${EDITOR:-vi}}
|
||||||
|
local line calendar
|
||||||
|
local -a lockfiles
|
||||||
|
|
||||||
|
integer cal_running
|
||||||
|
|
||||||
|
sched | while read line; do
|
||||||
|
[[ $line = *" calendar -s "<->" "<-> ]] && (( cal_running = 1 ))
|
||||||
|
done
|
||||||
|
|
||||||
|
zstyle -s ':datetime:calendar:' calendar-file calendar || calendar=~/calendar
|
||||||
|
|
||||||
|
{
|
||||||
|
calendar_lockfiles $calendar || return 1
|
||||||
|
|
||||||
|
eval $editor \$calendar
|
||||||
|
} always {
|
||||||
|
(( ${#lockfiles} )) && rm -f $lockfiles
|
||||||
|
}
|
||||||
|
|
||||||
|
(( cal_running )) && calendar -s
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
local file lockfile msgdone
|
local file lockfile msgdone
|
||||||
# Number of attempts to lock a file. Probably not worth stylising.
|
# Number of attempts to lock a file. Probably not worth stylising.
|
||||||
integer lockattempts=3
|
integer lockattempts=3 loadtried
|
||||||
|
|
||||||
# The lockfile name is not stylised: it has to be a fixed
|
# The lockfile name is not stylised: it has to be a fixed
|
||||||
# derivative of the main fail.
|
# derivative of the main fail.
|
||||||
|
|
@ -18,7 +18,19 @@ for file; do
|
||||||
msgdone="${lockfile}: waiting to acquire lock"
|
msgdone="${lockfile}: waiting to acquire lock"
|
||||||
zle -M $msgdone
|
zle -M $msgdone
|
||||||
fi
|
fi
|
||||||
sleep 1
|
if (( ! loadtried )); then
|
||||||
|
zmodload -i zsh/zselect 2>/dev/null
|
||||||
|
(( loadtried = 1 ))
|
||||||
|
fi
|
||||||
|
if zmodload -e zsh/zselect; then
|
||||||
|
# This gives us finer grained timing (100th second).
|
||||||
|
# Randomize the sleep between .1 and 1 second so that
|
||||||
|
# we are much less likely to have multiple instances
|
||||||
|
# retrying at once.
|
||||||
|
zselect -t $(( 10 + RANDOM * 90 / 32768 ))
|
||||||
|
else
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
if [[ -n $msgdone ]]; then
|
if [[ -n $msgdone ]]; then
|
||||||
zle -M ${msgdone//?/ }
|
zle -M ${msgdone//?/ }
|
||||||
|
|
|
||||||
|
|
@ -341,8 +341,8 @@ if (( relative == 0 )); then
|
||||||
date_found=1
|
date_found=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
# Look for DAY[th/st/rd] MNAME[,] YEAR
|
# Look for DAY[th/st/nd/rd] MNAME[,] YEAR
|
||||||
((#bi)${~dspat}(<1-31>)(|th|st|rd)[[:space:]]##${~monthpat}(|,)[[:space:]]##((19|20)[0-9][0-9])*)
|
((#bi)${~dspat}(<1-31>)(|th|st|nd|rd)[[:space:]]##${~monthpat}(|,)[[:space:]]##((19|20)[0-9][0-9])*)
|
||||||
day=$match[2]
|
day=$match[2]
|
||||||
mname=$match[4]
|
mname=$match[4]
|
||||||
year=$match[6]
|
year=$match[6]
|
||||||
|
|
@ -350,8 +350,8 @@ if (( relative == 0 )); then
|
||||||
date_found=1
|
date_found=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
# Look for MNAME DAY[th/st/rd][,] YEAR
|
# Look for MNAME DAY[th/st/nd/rd][,] YEAR
|
||||||
((#bi)${~dspat}${~monthpat}[[:space:]]##(<1-31>)(|th|st|rd)(|,)[[:space:]]##((19|20)[0-9][0-9])*)
|
((#bi)${~dspat}${~monthpat}[[:space:]]##(<1-31>)(|th|st|nd|rd)(|,)[[:space:]]##((19|20)[0-9][0-9])*)
|
||||||
mname=$match[2]
|
mname=$match[2]
|
||||||
day=$match[3]
|
day=$match[3]
|
||||||
year=$match[6]
|
year=$match[6]
|
||||||
|
|
@ -359,8 +359,8 @@ if (( relative == 0 )); then
|
||||||
date_found=1
|
date_found=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
# Look for DAY[th/st/rd] MNAME; assume current year
|
# Look for DAY[th/st/nd/rd] MNAME; assume current year
|
||||||
((#bi)${~dspat}(<1-31>)(|th|st|rd)[[:space:]]##${~monthpat}(|,)([[:space:]]##*|))
|
((#bi)${~dspat}(<1-31>)(|th|st|nd|rd)[[:space:]]##${~monthpat}(|,)([[:space:]]##*|))
|
||||||
day=$match[2]
|
day=$match[2]
|
||||||
mname=$match[4]
|
mname=$match[4]
|
||||||
strftime -s year "%Y" $EPOCHSECONDS
|
strftime -s year "%Y" $EPOCHSECONDS
|
||||||
|
|
@ -368,8 +368,8 @@ if (( relative == 0 )); then
|
||||||
date_found=1
|
date_found=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
# Look for MNAME DAY[th/st/rd]; assume current year
|
# Look for MNAME DAY[th/st/nd/rd]; assume current year
|
||||||
((#bi)${~dspat}${~monthpat}[[:space:]]##(<1-31>)(|th|st|rd)(|,)([[:space:]]##*|))
|
((#bi)${~dspat}${~monthpat}[[:space:]]##(<1-31>)(|th|st|nd|rd)(|,)([[:space:]]##*|))
|
||||||
mname=$match[2]
|
mname=$match[2]
|
||||||
day=$match[3]
|
day=$match[3]
|
||||||
strftime -s year "%Y" $EPOCHSECONDS
|
strftime -s year "%Y" $EPOCHSECONDS
|
||||||
|
|
@ -378,8 +378,8 @@ if (( relative == 0 )); then
|
||||||
;;
|
;;
|
||||||
|
|
||||||
# Now it gets a bit ambiguous.
|
# Now it gets a bit ambiguous.
|
||||||
# Look for DAY[th/st/rd][/]MONTH[/ ,]YEAR
|
# Look for DAY[th/st/nd/rd][/]MONTH[/ ,]YEAR
|
||||||
((#bi)${~dspat}(<1-31>)(|th|st|rd)/(<1-12>)((|,)[[:space:]]##|/)((19|20)[0-9][0-9])*)
|
((#bi)${~dspat}(<1-31>)(|th|st|nd|rd)/(<1-12>)((|,)[[:space:]]##|/)((19|20)[0-9][0-9])*)
|
||||||
day=$match[2]
|
day=$match[2]
|
||||||
month=$match[4]
|
month=$match[4]
|
||||||
year=$match[7]
|
year=$match[7]
|
||||||
|
|
@ -387,8 +387,8 @@ if (( relative == 0 )); then
|
||||||
date_found=1
|
date_found=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
# Look for MONTH[/]DAY[th/st/rd][/ ,]YEAR
|
# Look for MONTH[/]DAY[th/st/nd/rd][/ ,]YEAR
|
||||||
((#bi)${~dspat}(<1-12>)/(<1-31>)(|th|st|rd)((|,)[[:space:]]##|/)((19|20)[0-9][0-9])*)
|
((#bi)${~dspat}(<1-12>)/(<1-31>)(|th|st|nd|rd)((|,)[[:space:]]##|/)((19|20)[0-9][0-9])*)
|
||||||
month=$match[2]
|
month=$match[2]
|
||||||
day=$match[3]
|
day=$match[3]
|
||||||
year=$match[7]
|
year=$match[7]
|
||||||
|
|
@ -597,7 +597,9 @@ if (( relative )); then
|
||||||
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
|
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
|
||||||
time_found=1
|
time_found=1
|
||||||
fi
|
fi
|
||||||
if [[ $relative = 2 && $line = (#bi)${~dspat_noday}(<->)(th|rd|st)(${~daypat})(|${~schars}*) ]]; then
|
# For the next three items we accumulate adjustments in "newadd".
|
||||||
|
# See note below for why they are special.
|
||||||
|
if [[ $relative = 2 && $line = (#bi)${~dspat_noday}(<->)(th|rd|nd|st)(${~daypat})(|${~schars}*) ]]; then
|
||||||
nth=$match[2]
|
nth=$match[2]
|
||||||
test=${(L)${${match[4]##${~schars}#}%%${~schars}#}[1,3]}
|
test=${(L)${${match[4]##${~schars}#}%%${~schars}#}[1,3]}
|
||||||
wday=${dayarr[(I)$test]}
|
wday=${dayarr[(I)$test]}
|
||||||
|
|
@ -618,81 +620,66 @@ if (( relative )); then
|
||||||
# whereas the day of the month calculated so far is...
|
# whereas the day of the month calculated so far is...
|
||||||
strftime -s day2 "%d" $reldate
|
strftime -s day2 "%d" $reldate
|
||||||
# so we need to compensate by...
|
# so we need to compensate by...
|
||||||
(( reladd += (day - day2) * daysecs ))
|
(( newadd += (day - day2) * daysecs ))
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(w|wk|week|weekly)${~repat} ]]; then
|
if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(w|wk|week|weekly)${~repat} ]]; then
|
||||||
[[ -z $match[2] ]] && match[2]=1
|
[[ -z $match[2] ]] && match[2]=1
|
||||||
(( newadd = relsign * 7 * daysecs * ${match[2]} ))
|
(( newadd += relsign * 7 * daysecs * ${match[2]} ))
|
||||||
if (( relative == 2 )); then
|
|
||||||
# See explanation of this correction under days, below.
|
|
||||||
strftime -s h1 "%H" $(( relative_start + reladd ))
|
|
||||||
strftime -s h2 "%H" $(( relative_start + reladd + newadd ))
|
|
||||||
(( hd = h2 - h1 ))
|
|
||||||
# and of course we might go past midnight...
|
|
||||||
if (( hd > 12 )); then
|
|
||||||
(( hd -= 24 ))
|
|
||||||
elif (( hd < -12 )); then
|
|
||||||
(( hd += 24 ))
|
|
||||||
fi
|
|
||||||
(( newadd -= hd * 3600 ))
|
|
||||||
fi
|
|
||||||
(( reladd += newadd ))
|
|
||||||
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
|
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
|
||||||
time_found=1
|
time_found=1
|
||||||
fi
|
fi
|
||||||
if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(d|dy|day|daily)${~repat} ]]; then
|
if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(d|dy|day|daily)${~repat} ]]; then
|
||||||
[[ -z $match[2] ]] && match[2]=1
|
[[ -z $match[2] ]] && match[2]=1
|
||||||
(( newadd = relsign * daysecs * ${match[2]} ))
|
(( newadd += relsign * daysecs * ${match[2]} ))
|
||||||
if (( relative == 2 )); then
|
|
||||||
# You thought a day was always the same time? Ho, ho, ho.
|
|
||||||
# If the clocks go forward or back, we can gain or lose
|
|
||||||
# an hour. Check this by seeing what the hour is before
|
|
||||||
# and after adding the number of days. If it changes,
|
|
||||||
# remove the difference.
|
|
||||||
#
|
|
||||||
# We need this correction for weeks, too, as above.
|
|
||||||
# (We could apply corrections for weeks and days together,
|
|
||||||
# in fact, but I've left it a little more modular).
|
|
||||||
# We don't need it for years and months because we calculated
|
|
||||||
# those by actually looking at the calendar for a given
|
|
||||||
# time of day, so the adjustment came out in the wash.
|
|
||||||
# We don't need it for hours or smaller periods because
|
|
||||||
# presumably if a user asks for something in 3 hours time
|
|
||||||
# they don't mean 4 hours if the clocks went back and
|
|
||||||
# 2 hours if they went forward. At least, I think so.
|
|
||||||
# Consider:
|
|
||||||
# % calendar_showdate +2d,1hr
|
|
||||||
# Sun Mar 25 00:37:00 GMT 2007
|
|
||||||
# % calendar_showdate +2d,2hr
|
|
||||||
# Sun Mar 25 02:37:09 BST 2007
|
|
||||||
# At first sight that looks wrong because the clock appears
|
|
||||||
# to jump two hours. (Yes, it took me all of 9 seconds to
|
|
||||||
# edit the line.) But actually it's only jumped the hour
|
|
||||||
# you asked for, because one is in GMT and the other in BST.
|
|
||||||
# In principle you could say the same thing about days:
|
|
||||||
# Sun Mar 25 00:00:00 GMT 2007 and Mon Mar 26 01:00:00 BST 2007
|
|
||||||
# are a day apart. But usually if you say "same time next Tuesday"
|
|
||||||
# you mean "when the clock says the same time, even if someone
|
|
||||||
# has nipped in and adjusted it in the mean time", although
|
|
||||||
# for some reason you don't usually bother saying that.
|
|
||||||
#
|
|
||||||
# Hope that's clear.
|
|
||||||
strftime -s h1 "%H" $(( relative_start + reladd ))
|
|
||||||
strftime -s h2 "%H" $(( relative_start + reladd + newadd ))
|
|
||||||
(( hd = h2 - h1 ))
|
|
||||||
# and of course we might go past midnight...
|
|
||||||
if (( hd > 12 )); then
|
|
||||||
(( hd -= 24 ))
|
|
||||||
elif (( hd < -12 )); then
|
|
||||||
(( hd += 24 ))
|
|
||||||
fi
|
|
||||||
(( newadd -= hd * 3600 ))
|
|
||||||
fi
|
|
||||||
(( reladd += newadd ))
|
|
||||||
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
|
line=${line[1,$mbegin[2]-1]}${line[$mend[4]+1,-1]}
|
||||||
time_found=1
|
time_found=1
|
||||||
fi
|
fi
|
||||||
|
if (( relative == 2 && newadd )); then
|
||||||
|
# You thought a day was always the same time? Ho, ho, ho.
|
||||||
|
# If the clocks go forward or back, we can gain or lose
|
||||||
|
# an hour. Check this by seeing what the hour is before
|
||||||
|
# and after adding the number of days. If it changes,
|
||||||
|
# remove the difference.
|
||||||
|
#
|
||||||
|
# We need this correction for days (including days of a given
|
||||||
|
# month) and weeks.
|
||||||
|
# We don't need it for years and months because we calculated
|
||||||
|
# those by actually looking at the calendar for a given
|
||||||
|
# time of day, so the adjustment came out in the wash.
|
||||||
|
# We don't need it for hours or smaller periods because
|
||||||
|
# presumably if a user asks for something in 3 hours time
|
||||||
|
# they don't mean 4 hours if the clocks went back and
|
||||||
|
# 2 hours if they went forward. At least, I think so.
|
||||||
|
# Consider:
|
||||||
|
# % calendar_showdate +2d,1hr
|
||||||
|
# Sun Mar 25 00:37:00 GMT 2007
|
||||||
|
# % calendar_showdate +2d,2hr
|
||||||
|
# Sun Mar 25 02:37:09 BST 2007
|
||||||
|
# At first sight that looks wrong because the clock appears
|
||||||
|
# to jump two hours. (Yes, it took me all of 9 seconds to
|
||||||
|
# edit the line.) But actually it's only jumped the hour
|
||||||
|
# you asked for, because one is in GMT and the other in BST.
|
||||||
|
# In principle you could say the same thing about days:
|
||||||
|
# Sun Mar 25 00:00:00 GMT 2007 and Mon Mar 26 01:00:00 BST 2007
|
||||||
|
# are a day apart. But usually if you say "same time next Tuesday"
|
||||||
|
# you mean "when the clock says the same time, even if someone
|
||||||
|
# has nipped in and adjusted it in the mean time", although
|
||||||
|
# for some reason you don't usually bother saying that.
|
||||||
|
#
|
||||||
|
# Hope that's clear.
|
||||||
|
strftime -s h1 "%H" $(( relative_start + reladd ))
|
||||||
|
strftime -s h2 "%H" $(( relative_start + reladd + newadd ))
|
||||||
|
(( hd = h2 - h1 ))
|
||||||
|
# and of course we might go past midnight...
|
||||||
|
if (( hd > 12 )); then
|
||||||
|
(( hd -= 24 ))
|
||||||
|
elif (( hd < -12 )); then
|
||||||
|
(( hd += 24 ))
|
||||||
|
fi
|
||||||
|
(( newadd -= hd * 3600 ))
|
||||||
|
fi
|
||||||
|
(( reladd += newadd ))
|
||||||
if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(h|hr|hour|hourly)${~repat} ]]; then
|
if [[ $line = (#bi)${~dspat}(<->|)[[:space:]]#(h|hr|hour|hourly)${~repat} ]]; then
|
||||||
[[ -z $match[2] ]] && match[2]=1
|
[[ -z $match[2] ]] && match[2]=1
|
||||||
(( reladd += relsign * 60 * 60 * ${match[2]} ))
|
(( reladd += relsign * 60 * 60 * ${match[2]} ))
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,39 @@ integer optr replyset
|
||||||
zstyle -s ':datetime:calendar_showdate:' date-format datefmt ||
|
zstyle -s ':datetime:calendar_showdate:' date-format datefmt ||
|
||||||
datefmt="%a %b %d %H:%M:%S %Z %Y"
|
datefmt="%a %b %d %H:%M:%S %Z %Y"
|
||||||
|
|
||||||
while [[ $argv[$OPTIND] != +* ]] && getopts "r" opt; do
|
# Memo to myself: both + and - are documented as giving relative
|
||||||
case $opt in
|
# times, so it's not a good idea to rewrite this to use getopts.
|
||||||
(r)
|
# We need to detect the small number of options this can actually
|
||||||
|
# handle.
|
||||||
|
while [[ $1 = -r || $1 = -- || $1 = -f* ]]; do
|
||||||
|
case $1 in
|
||||||
|
(-r)
|
||||||
|
shift
|
||||||
REPLY=0
|
REPLY=0
|
||||||
optr=1
|
optr=1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
(-f*)
|
||||||
|
if [[ $1 = -f?* ]]; then
|
||||||
|
datefmt=$1[3,-1]
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
shift
|
||||||
|
if [[ -z $1 || $1 != *%* ]]; then
|
||||||
|
print "$0: -f requires a date/time specification" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
datefmt=$1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
(--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
shift $(( OPTIND - 1 ))
|
|
||||||
|
|
||||||
(( optr )) || local REPLY
|
(( optr )) || local REPLY
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue