=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/calendar/day.c,v retrieving revision 1.1 retrieving revision 1.5 diff -u -r1.1 -r1.5 --- src/usr.bin/calendar/day.c 1996/12/05 06:04:39 1.1 +++ src/usr.bin/calendar/day.c 1998/11/04 11:32:02 1.5 @@ -1,4 +1,4 @@ -/* $OpenBSD: day.c,v 1.1 1996/12/05 06:04:39 millert Exp $ */ +/* $OpenBSD: day.c,v 1.5 1998/11/04 11:32:02 pjanzen Exp $ */ /* * Copyright (c) 1989, 1993, 1994 @@ -43,7 +43,7 @@ #if 0 static const char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94"; #else -static char rcsid[] = "$OpenBSD: day.c,v 1.1 1996/12/05 06:04:39 millert Exp $"; +static char rcsid[] = "$OpenBSD: day.c,v 1.5 1998/11/04 11:32:02 pjanzen Exp $"; #endif #endif /* not lint */ @@ -97,10 +97,8 @@ for (i = 0; i < 7; i++) { tm.tm_wday = i; - strftime(buf, sizeof(buf), "%a", &tm); - for (l = strlen(buf); - l > 0 && isspace((int)buf[l - 1]); - l--) + l = strftime(buf, sizeof(buf), "%a", &tm); + for (; l > 0 && isspace((int)buf[l - 1]); l--) ; buf[l] = '\0'; if (ndays[i].name != NULL) @@ -109,10 +107,8 @@ errx(1, "cannot allocate memory"); ndays[i].len = strlen(buf); - strftime(buf, sizeof(buf), "%A", &tm); - for (l = strlen(buf); - l > 0 && isspace((int)buf[l - 1]); - l--) + l = strftime(buf, sizeof(buf), "%A", &tm); + for (; l > 0 && isspace((int)buf[l - 1]); l--) ; buf[l] = '\0'; if (fndays[i].name != NULL) @@ -124,10 +120,8 @@ for (i = 0; i < 12; i++) { tm.tm_mon = i; - strftime(buf, sizeof(buf), "%b", &tm); - for (l = strlen(buf); - l > 0 && isspace((int)buf[l - 1]); - l--) + l = strftime(buf, sizeof(buf), "%b", &tm); + for (; l > 0 && isspace((int)buf[l - 1]); l--) ; buf[l] = '\0'; if (nmonths[i].name != NULL) @@ -136,10 +130,8 @@ errx(1, "cannot allocate memory"); nmonths[i].len = strlen(buf); - strftime(buf, sizeof(buf), "%B", &tm); - for (l = strlen(buf); - l > 0 && isspace((int)buf[l - 1]); - l--) + l = strftime(buf, sizeof(buf), "%B", &tm); + for (; l > 0 && isspace((int)buf[l - 1]); l--) ; buf[l] = '\0'; if (fnmonths[i].name != NULL) @@ -155,7 +147,7 @@ time_t now; { tp = localtime(&now); - if (isleap(tp->tm_year + 1900)) { + if (isleap(tp->tm_year + TM_YEAR_BASE)) { yrdays = DAYSPERLYEAR; cumdays = daytab[1]; } else { @@ -173,8 +165,8 @@ setnnames(); } -/* convert Day[/Month][/Year] into unix time (since 1970) - * Day: two digits, Month: two digits, Year: digits +/* convert [Year][Month]Day into unix time (since 1970) + * Year: two or four digits, Month: two digits, Day: two digits */ time_t Mktime (date) char *date; @@ -187,32 +179,39 @@ tp = localtime(&t); len = strlen(date); + if (len < 2) + return((time_t)-1); tm.tm_sec = 0; tm.tm_min = 0; - tm.tm_hour = 0; + /* Avoid getting caught by a timezone shift; set time to noon */ + tm.tm_isdst = 0; + tm.tm_hour = 12; tm.tm_wday = 0; tm.tm_mday = tp->tm_mday; tm.tm_mon = tp->tm_mon; tm.tm_year = tp->tm_year; + /* Day */ + tm.tm_mday = atoi(date + len - 2); - /* day */ - *(date+2) = NULL; - tm.tm_mday = atoi(date); - - /* month */ + /* Month */ if (len >= 4) { - *(date+5) = NULL; - tm.tm_mon = atoi(date+3) - 1; + *(date + len - 2) = '\0'; + tm.tm_mon = atoi(date + len - 4) - 1; } /* Year */ - if (len >= 7) { - tm.tm_year = atoi(date+6); + if (len >= 6) { + *(date + len - 4) = '\0'; + tm.tm_year = atoi(date); - /* tm_year up 1900 ... */ - if (tm.tm_year > 1900) - tm.tm_year -= 1900; + /* tm_year up TM_YEAR_BASE ... */ + if (tm.tm_year < 69) /* Y2K */ + tm.tm_year += 2000 - TM_YEAR_BASE; + else if (tm.tm_year < 100) + tm.tm_year += 1900 - TM_YEAR_BASE; + else if (tm.tm_year > TM_YEAR_BASE) + tm.tm_year -= TM_YEAR_BASE; } #if DEBUG @@ -313,7 +312,7 @@ /* convert Weekday into *next* Day, * e.g.: 'Sunday' -> 22 - * 'SunayLast' -> ?? + * 'SundayLast' -> ?? */ if (flags & F_ISDAY) { #if DEBUG @@ -327,44 +326,35 @@ /* negative offset; last, -4 .. -1 */ if (day < 0) { v1 = day/10 - 1; /* offset -4 ... -1 */ - day = 10 + (day % 10); /* day 1 ... 7 */ + day = 10 + (day % 10); /* day 1 ... 7 */ - /* day, eg '22th' */ - v2 = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); + /* which weekday the end of the month is (1-7) */ + v2 = (cumdays[month + 1] - tp->tm_yday + + tp->tm_wday + 371) % 7 + 1; - /* (month length - day) / 7 + 1 */ - if (((int)((cumdays[month+1] - - cumdays[month] - v2) / 7) + 1) == -v1) - /* bingo ! */ - day = v2; - - /* set to yesterday */ - else - day = tp->tm_mday - 1; + /* and subtract enough days */ + day = cumdays[month + 1] - cumdays[month] + + (v1 + 1) * 7 - (v2 - day + 7) % 7; +#if DEBUG + fprintf(stderr, "\nMonth %d ends on weekday %d\n", month, v2); +#endif } /* first, second ... +1 ... +5 */ else { - v1 = day/10; /* offset: +1 (first Sunday) ... */ + v1 = day/10; /* offset */ day = day % 10; - /* day, eg '22th' */ - v2 = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); - - /* Hurrah! matched */ - if ( ((v2 - 1 + 7) / 7) == v1 ) - day = v2; - - /* set to yesterday */ - else - day = tp->tm_mday - 1; - } + /* which weekday the first of the month is */ + v2 = (cumdays[month] - tp->tm_yday + + tp->tm_wday + 372) % 7 + 1; + + /* and add enough days */ + day = 1 + (v1 - 1) * 7 + (day - v2 + 7) % 7; +#if DEBUG + fprintf(stderr, "\nMonth %d starts on weekday %d\n", month, v2); +#endif } - - /* wired */ - else { - day = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); - *varp = 1; } }