#ifndef lint static char *sccsid = "@(#)time.c 1.4 (Berkeley) 3/20/86"; #endif /* * Collection of routines for dealing with ASCII time strings. * These may actually be useful in their own right. */ #include #include #include #include #include /* * dtol -- convert date to long integer. This is not implicitly * local time, or any other kind of time, for that matter. If you * pass it a date you think is GMT, you wind up with that number of * seconds... * * Parameters: "date_ascii" is in the form "yymmddhhmmss". * * Returns: Long integer containing number * of seconds since 000000 Jan 1, 1970, * and "date". -1 on error. * * Side effects: None. */ #define twodigtoi(x) (((*x++) - '0') + (*x++ - '0')*10) #define dysize(y) ((y % 4 ? 365 : 366)) static int dmsize[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; long dtol(date_ascii) char *date_ascii; { char date[32], *date_str; char *lhs, *rhs; char temp; long seconds; int year, month, day, hour, mins, secs; int len, i; len = strlen(date_ascii); if (len != sizeof("yymmddhhmmss")-1) return (-1); (void) strcpy(date, date_ascii); date_str = date; #ifdef debug printf("date_str = %s\n", date_str); #endif rhs = date_str + len - 1; lhs = date_str; for (; lhs < rhs; ++lhs, --rhs) { temp = *lhs; *lhs = *rhs; *rhs = temp; if (!isdigit(temp) || !isdigit(*lhs)) return (-1); } lhs = date_str; #ifdef debug printf("date_str = %s\n", date_str); #endif secs = twodigtoi(lhs); mins = twodigtoi(lhs); hour = twodigtoi(lhs); day = twodigtoi(lhs); month = twodigtoi(lhs); year = twodigtoi(lhs); if (month < 1 || month > 12 || day < 1 || day > 31 || mins < 0 || mins > 59 || secs < 0 || secs > 59) return (-1); if (hour == 24) { hour = 0; day++; } if (hour < 0 || hour > 23) return (-1); seconds = 0; year += 1900; for (i = 1970; i < year; i++) seconds += dysize(i); /* Leap year */ if (dysize(year) == 366 && month >= 3) seconds++; while (--month) seconds += dmsize[month-1]; seconds += day-1; seconds = 24 * seconds + hour; seconds = 60 * seconds + mins; seconds = 60 * seconds + secs; return (seconds); } /* * ltod -- convert long integer to date string. * * Parameters: "date" is in the number of seconds * since the epoch. * * Returns: Pointer to static data in the form * yymmddhhmmss\0. * * Side effects: None. */ char * ltod(date) long date; { static char timebuf[32]; struct tm *tp; tp = gmtime(&date); sprintf(timebuf, "%02d%02d%02d%02d%02d%02d", tp->tm_year, tp->tm_mon + 1, /* 0 to 11??? How silly. */ tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec); return (timebuf); } /* * local_to_gmt -- convert a local time (in form of number of * seconds since you-know-when) to GMT. * * Parameters: "date" is date we want converted, in * seconds since 000000 1 Jan 1970. * * Returns: Number of seconds corrected for local * and dst. */ long local_to_gmt(date) long date; { struct timeval tv; struct timezone tz; (void) gettimeofday(&tv, &tz); date += (long) tz.tz_minuteswest * 60; /* now fix up local daylight time */ if (localtime((time_t *)&date)->tm_isdst) date -= 60*60; return (date); } /* * gmt_to_local -- take a GMT time expressed in seconds since * the epoch, and convert it to local time. * * Parameters: "date" is the number of seconds... * * Returns: Number of seconds corrected to reflect * local time and dst. */ long gmt_to_local(date) long date; { struct timeval tv; struct timezone tz; (void) gettimeofday(&tv, &tz); date -= (long) tz.tz_minuteswest * 60; /* now fix up local daylight time */ if (localtime((time_t *)&date)->tm_isdst) date += 60*60; return (date); }