jfh@rpp386.cactus.org (John F. Haugh II) (11/30/90)
There is nothing worse than dumb, stupid, slow code. These is also nothing worse than people whose IQ is so low that they can't take a hint and do something productive with it. Please, people, some of you claim to be programmers, how about living up to those claims? I'm really sorry I feel this need to insult some people, but gee guys, at least take the effort to try my suggestions before attacking me as writing buggy or inaccurate code. Of course, having not been paid to write this code I will tell you that under certain conditions it may loop infinitely, but then you get what you pay for. Try 2/31/88 for a nice time. Test results after the source code. You will notice that this code correctly handles daylight savings time, as well as hours, minutes, and seconds. You will also notice that it calls localtime 1/15th or so less often. It even does leap days. There is nothing wrong with being "clever", but binary approximation is as old as Newton, if not older. -- /* * Copyright 1990, John F. Haugh II * All rights reserved. * * Use, duplication, and disclosure prohibited without * the express written permission of the author. * * Non-commercial (profit-making) source distribution permitted * provided this notice remains intact. */ #include <time.h> /* * days and juldays are used to compute the number of days in the * current month, and the cummulative number of days in the preceding * months. */ static short days[12] = { 31, 28, 31, 30, 31, 30, /* JAN - JUN */ 31, 31, 30, 31, 30, 31 }; /* JUL - DEC */ static short juldays[12] = { 0, 31, 59, 90, 120, 151, /* JAN - JUN */ 181, 212, 243, 273, 304, 334 }; /* JUL - DEC */ static long dtime (tm, time) struct tm *tm; long time; /* no C */ { struct tm *sm; long diff; long julian1, julian2; sm = localtime (&time); julian1 = ((tm->tm_year - 70) * 365) + /* days in whole years */ (((tm->tm_year + 1) - 70) / 4); /* days in leap years */ julian1 += juldays[tm->tm_mon] + /* days in whole months */ (tm->tm_mon > 1 && (tm->tm_year % 4) == 0 ? 1:0); /* leap day */ julian1 += tm->tm_mday - 1; /* days so far this month */ julian2 = ((sm->tm_year - 70) * 365) + /* days in whole years */ (((sm->tm_year + 1) - 70) / 4); /* days in leap years */ julian2 += juldays[sm->tm_mon] + /* days in whole months */ (sm->tm_mon > 1 && (sm->tm_year % 4) == 0 ? 1:0); /* leap day */ julian2 += sm->tm_mday - 1; /* days so far this month */ diff = (julian1 - julian2) * (24L*3600); /* add the days */ diff += (tm->tm_hour - sm->tm_hour) * (3600L); /* add the hours */ diff += (tm->tm_min - sm->tm_min) * (60L); /* add the minutes */ diff += (tm->tm_sec - sm->tm_sec); /* add the seconds */ return diff; /* that's how far off */ } long mktime (tm) struct tm *tm; { long old, diff, new; struct tm *t; for (old = 0L;(diff = dtime (tm, old)) != 0;old += diff) { #ifdef TEST new = old + diff; printf ("old = %ld, new = %ld\n", old, new); t = localtime (&old); printf ("old = %d/%d/%d %d:%d:%d\n", t->tm_mon + 1, t->tm_mday, t->tm_year, t->tm_hour, t->tm_min, t->tm_sec); t = localtime (&new); printf ("new = %d/%d/%d %d:%d:%d\n", t->tm_mon + 1, t->tm_mday, t->tm_year, t->tm_hour, t->tm_min, t->tm_sec); #else ; #endif } return old; } #ifdef TEST main () { long t; struct tm tm; struct tm *ptm; char buf[100]; while (gets (buf)) { memset (&tm, 0, sizeof tm); sscanf (buf, "%d/%d/%d %d:%d:%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); tm.tm_mon--; t = mktime (&tm); ptm = localtime (&t); printf ("guess = %d or %d/%d/%d %d:%d:%d\n", t, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_year, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); } } #endif -- Script is typescript, started Thu Nov 29 10:00:25 1990 rpp386-> ./mktime 1/1/70 0:0:0 old = 0, new = 21600 old = 12/31/69 18:0:0 new = 1/1/70 0:0:0 guess = 21600 or 1/1/70 0:0:0 12/31/69 18:0:0 guess = 0 or 12/31/69 18:0:0 11/29/90 10:00:25 old = 0, new = 659894425 old = 12/31/69 18:0:0 new = 11/29/90 10:0:25 guess = 659894425 or 11/29/90 10:0:25 6/1/90 12:00:00 old = 0, new = 644263200 old = 12/31/69 18:0:0 new = 6/1/90 13:0:0 old = 644263200, new = 644259600 old = 6/1/90 13:0:0 new = 6/1/90 12:0:0 guess = 644259600 or 6/1/90 12:0:0 10/21/90 01:00:00 old = 0, new = 656492400 old = 12/31/69 18:0:0 new = 10/21/90 2:0:0 old = 656492400, new = 656488800 old = 10/21/90 2:0:0 new = 10/21/90 1:0:0 guess = 656488800 or 10/21/90 1:0:0 10/21/90 02:00:00 old = 0, new = 656496000 old = 12/31/69 18:0:0 new = 10/21/90 3:0:0 old = 656496000, new = 656492400 old = 10/21/90 3:0:0 new = 10/21/90 2:0:0 guess = 656492400 or 10/21/90 2:0:0 10/21/90 3:0:0 old = 0, new = 656499600 old = 12/31/69 18:0:0 new = 10/21/90 4:0:0 old = 656499600, new = 656496000 old = 10/21/90 4:0:0 new = 10/21/90 3:0:0 guess = 656496000 or 10/21/90 3:0:0 10/28/90 1:0:0 old = 0, new = 657097200 old = 12/31/69 18:0:0 new = 10/28/90 1:0:0 guess = 657097200 or 10/28/90 1:0:0 10/28/90 2:0:0 old = 0, new = 657100800 old = 12/31/69 18:0:0 new = 10/28/90 2:0:0 guess = 657100800 or 10/28/90 2:0:0 rpp386-> exit Script done Thu Nov 29 10:03:31 1990 -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org "SCCS, the source motel! Programs check in and never check out!" -- Ken Thompson