/* ** Copyright (C) 1994, 1995 Enterprise Integration Technologies Corp. ** VeriFone Inc./Hewlett-Packard. All Rights Reserved. ** Kevin Hughes, kev@kevcom.com 3/11/94 ** Kent Landfield, kent@landfield.com 4/6/97 ** Tom von Alten, tom_vonalten@boi.hp.com 9 Oct 1998 ** ** This program and library is free software; you can redistribute it and/or ** modify it under the terms of the GNU (Library) General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU (Library) General Public License for more details. ** ** You should have received a copy of the GNU (Library) General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* ** Date stuff. Everything here is my own code, with the exception ** of getnweekday(), which is in the public domain. -- Kevin */ /* ** Fix routines using two-digit dates, for y2k. -- TvA */ #include "hypermail.h" #include /* ** This converts a long date string into the form D/M/Y. */ /* ** Returns the day of the year. */ int getnweekday(int mn, int dy, int yr) { int n1, n2; if (mn < 3) { mn += 12; yr -= 1; } n1 = (26 * (mn + 1)) / 10; n2 = (int) ((125 * (long) yr) / 100); return ((dy + n1 + n2 - (yr / 100) + (yr / 400) + -1) % 7); } /* ** Fix to use 4 digit years -- TvA */ void convtoshortdate(char *date, char *shortdate) { char c, d, e; int i, month; if (date[3] == ' ') { /* (Wed Mar 19 19:15:53 1997 CST) format */ c = date[4]; d = date[5]; e = date[6]; for (i = 0; !(c == (months[i])[0] && d == (months[i])[1] && e == (months[i])[2]); i++) ; month = i + 1; shortdate[0] = (month > 9) ? '1' : '0'; shortdate[1] = monthnums[month]; shortdate[2] = '/'; shortdate[3] = (date[8] == ' ') ? '0' : date[8]; shortdate[4] = date[9]; shortdate[5] = '/'; shortdate[6] = date[20]; shortdate[7] = date[21]; shortdate[8] = date[22]; shortdate[9] = date[23]; shortdate[10] = '\0'; } else if (date[3] == ',') { /* (Wed, 19 Mar 19:15:53 1997 CST) */ /* (Wed, 19 Mar 19:15:53 97 CST) */ /* (Wed, 9 Mar 19:15:53 1997 CST) */ /* (Wed, 9 Mar 19:15:53 97 CST) */ /* Determine the day. */ if (date[7] == ' ') { /* Day > 9 */ c = date[8]; d = date[9]; e = date[10]; } else { /* Day <= 9 */ c = date[7]; d = date[8]; e = date[9]; } /* Determine the month. */ for (i = 0; !(c == (months[i])[0] && d == (months[i])[1] && e == (months[i])[2]); i++) ; month = i + 1; shortdate[0] = (month > 9) ? '1' : '0'; shortdate[1] = monthnums[month]; shortdate[2] = '/'; if (date[4] == ' ' && date[6] == ' ') { /* day < 9 */ shortdate[3] = '0'; shortdate[4] = date[5]; } else { shortdate[3] = date[5]; shortdate[4] = date[6]; } shortdate[5] = '/'; /* Determine the year. */ /* This was looking earlier in the string, as if the time wasn't there? I changed to match the format in the comment shown above, at "else if" -- TvA */ /* Two digit year formats assumed to be a 20th century atavism */ if (date[4] == ' ' && date[6] == ' ' && date[10] == ' ') { /* day<9 */ if (date[22] == ' ') { /* two digit year */ shortdate[6] = thisyear[0]; shortdate[7] = thisyear[1]; shortdate[8] = date[20]; shortdate[9] = date[21]; } else { shortdate[6] = date[20]; shortdate[7] = date[21]; shortdate[8] = date[22]; shortdate[9] = date[23]; } } else { if (date[23] == ' ') { /* two digit year */ shortdate[6] = thisyear[0]; shortdate[7] = thisyear[1]; shortdate[7] = date[21]; shortdate[8] = date[22]; } else { shortdate[6] = date[21]; shortdate[7] = date[22]; shortdate[8] = date[23]; shortdate[9] = date[24]; } } shortdate[10] = '\0'; } else fprintf(stderr,"Date: [%s]\n", date); } /* ** Splits a short date (M[M]/D[D]/YYYY) into month, day, and year components. ** Fixed from YY -- TvA */ void splitshortdate(char *shortdate, int *month, int *day, int *year) { if (shortdate[0] == ' ' || shortdate[0] == '0') *month = (shortdate[1] - '0'); else if (shortdate[1] == '/') *month = (shortdate[0] - '0'); else if (shortdate[2] == '/') *month = (shortdate[0] - '0') * 10 + (shortdate[1] - '0'); if (shortdate[2] =='/') { if (shortdate[5] == '/') { *day = (shortdate[3] - '0') * 10 + (shortdate[4] - '0'); *year = (shortdate[6] - '0') * 1000 + (shortdate[7] - '0') * 100 + (shortdate[8] - '0') * 10 + (shortdate[9] - '0'); } else if (shortdate[4] == '/') { *day = (shortdate[3] - '0'); *year = (shortdate[5] - '0') * 1000 + (shortdate[6] - '0') * 100 + (shortdate[7] - '0') * 10 + (shortdate[8] - '0'); } } else if (shortdate[1] =='/') { if (shortdate[4] == '/') { *day = (shortdate[2] - '0') * 10 + (shortdate[3] - '0'); *year = (shortdate[5] - '0') * 1000 + (shortdate[6] - '0') * 100 + (shortdate[7] - '0') * 10 + (shortdate[8] - '0'); } else if (shortdate[3] == '/') { *day = (shortdate[2] - '0'); *year = (shortdate[4] - '0') * 1000 + (shortdate[5] - '0') * 100 + (shortdate[6] - '0') * 10 + (shortdate[7] - '0'); } } } /* ** Given a short date (M/D/YYYY), it returns the number of seconds ** since BASEYEAR. (Fixed from M/D/YY -- TvA) */ long getyearsecs(char *shortdate) { int i, month, day, year; long dayspast = 0; splitshortdate(shortdate, &month, &day, &year); /* year += CENTURY; */ for (i = BASEYEAR; i < year; i++) { if (IS_LEAP(i)) dayspast++; dayspast += DAYSPERYEAR; } for (i = 0; i < month - 1; i++) { dayspast += monthdays[i]; } if (month > 2 && IS_LEAP(year)) dayspast++; dayspast += day; return (dayspast * SECSPERDAY); } /* ** Given a long date string, it returns the number of seconds ** since BASEYEAR. */ long convtoyearsecs(char *date) { char hourstr[3], minstr[3], secstr[3], shortdate[SHORTDATELEN]; int hours, minutes, seconds; long yearsecs; convtoshortdate(date, shortdate); yearsecs = getyearsecs(shortdate); sprintf(hourstr, "%c%c", date[11], date[12]); sprintf(minstr, "%c%c", date[14], date[15]); sprintf(secstr, "%c%c", date[17], date[18]); hours = atoi(hourstr); minutes = atoi(minstr); seconds = atoi(secstr); return (yearsecs+(hours * SECSPERHOUR)+(minutes * SECSPERMIN)+seconds); } /* ** Gets the local time and returns it formatted. */ char *getlocaltime() { static char s[DATESTRLEN]; time_t tp; time(&tp); if (eurodate) strftime(s,DATESTRLEN,"%a %d %b %Y - %H:%M:%S",localtime(&tp)); else strftime(s,DATESTRLEN,"%a %b %d %Y - %H:%M:%S",localtime(&tp)); sprintf(s, "%s %s", s, timezonestr); return s; } /* ** Gets the local time zone. */ void gettimezone() { time_t tp; time(&tp); strftime(timezonestr, TIMEZONELEN, "%Z", localtime(&tp)); } /* ** Gets the current year. */ void getthisyear() { time_t tp; time(&tp); strftime(thisyear, YEARLEN, "%Y", localtime(&tp)); } /* ** From the number of seconds since BASEYEAR, this pretty-prints ** a date for you. */ char *getdatestr(long yearsecs) { register int day, year, month, hours, minutes; static char date[DATESTRLEN]; for (day = 0; yearsecs >= SECSPERDAY; day++) yearsecs -= SECSPERDAY; for (year = BASEYEAR; day > DAYSPERYEAR; year++) { if (IS_LEAP(year)) day--; day -= DAYSPERYEAR; } for (month = 0; day > monthdays[month]; month++) { if (month == 1 && IS_LEAP(year)) { if (day == 29) break; else day--; } day -= monthdays[month]; } for (hours = 0; yearsecs >= SECSPERHOUR; hours++) yearsecs -= SECSPERHOUR; for (minutes = 0; yearsecs >= SECSPERMIN; minutes++) yearsecs -= SECSPERMIN; if (eurodate) { sprintf(date, "%s%s %02d %d - %02d:%02d:%02ld %s", days[getnweekday(month + 1, day, year)], months[month], day, year, hours, minutes, yearsecs, timezonestr); } else { sprintf(date, "%s%02d %s %d - %02d:%02d:%02ld %s", days[getnweekday(month + 1, day, year)], day, months[month], year, hours, minutes, yearsecs, timezonestr); } return date; }