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


Reply via email to