Hello,
The following patch seems to allow calendar to better handle the fifth
weekday and 31st events. Currently, both events match also at the
beginning of certain months which doesn't seem to make sense. For
example, March 02 is considered a 31st this year and July 03 is
considered a Fifth Sunday:
$ sh /tmp/calendar.sh
calendar -f /tmp/calendar.We1Ga8 -t 20160101
Jan 03* Fifth Sunday.
calendar -f /tmp/calendar.We1Ga8 -t 20160130
Jan 31* Fifth Sunday.
Jan 31* 31st.
calendar -f /tmp/calendar.We1Ga8 -t 20160301
Mar 02* 31st.
calendar -f /tmp/calendar.We1Ga8 -t 20160701
Jul 01* 31st.
Jul 03* Fifth Sunday.
calendar -f /tmp/calendar.We1Ga8 -t 20160729
Jul 31* Fifth Sunday.
Jul 31* 31st.
Here is how it behaves with the patch:
$ sh /tmp/calendar.sh /usr/src/usr.bin/calendar/obj/calendar
/usr/src/usr.bin/calendar/obj/calendar -f /tmp/calendar.83O1qH -t 20160101
/usr/src/usr.bin/calendar/obj/calendar -f /tmp/calendar.83O1qH -t 20160130
Jan 31* Fifth Sunday.
Jan 31* 31st.
/usr/src/usr.bin/calendar/obj/calendar -f /tmp/calendar.83O1qH -t 20160301
/usr/src/usr.bin/calendar/obj/calendar -f /tmp/calendar.83O1qH -t 20160701
/usr/src/usr.bin/calendar/obj/calendar -f /tmp/calendar.83O1qH -t 20160729
Jul 31* Fifth Sunday.
Jul 31* 31st.
Here is calendar.sh:
$ cat /tmp/calendar.sh
PROG=${1:-calendar}
CALENDAR=$(mktemp -t calendar.XXXXXX)
printf '
Sunday+5\tFifth Sunday.
31 *\t31st.
' >"$CALENDAR"
for date in 20160101 20160130 20160301 20160701 20160729
do
set -- "$PROG" -f "$CALENDAR" -t "$date"
echo "$@"
eval "$@"
done
rm "$CALENDAR"
And here is the patch:
Index: calendar/day.c
===================================================================
RCS file: /home/cvs/src/usr.bin/calendar/day.c,v
retrieving revision 1.32
diff -u -p -r1.32 day.c
--- calendar/day.c 8 Dec 2015 19:04:50 -0000 1.32
+++ calendar/day.c 9 Jul 2016 20:53:13 -0000
@@ -543,8 +543,9 @@ isnow(char *endp, int bodun)
tdiff = difftime(ttmp, f_time)/ SECSPERDAY;
if (tdiff <= offset + f_dayAfter ||
(bodun && tdiff == -1)) {
- if (tdiff >= 0 ||
- (bodun && tdiff == -1)) {
+ if ((tmtmp.tm_mon == month) &&
+ (tdiff >= 0 ||
+ (bodun && tdiff == -1))) {
if ((tmp = malloc(sizeof(struct
match))) == NULL)
err(1, NULL);
tmp->when = ttmp;
This works because when variable_weekday returns it places a value in v1
that is larger than a month's worth of days. For example, for July 1,
2016, Sunday+5 gets a value of 33 in tmtmp.tm_mday for which mktime
advances advances the month to account for the extra days when creating
the timestamp. Now the months are different and should probably not
count as a match.
Are there any bad side-effects in this approach?
Thanks,
Andy
--
TAI64 timestamp: 400000005781686f