home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2170 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  5.5 KB

  1. From: jfh@rpp386.cactus.org (John F. Haugh II)
  2. Newsgroups: alt.sources
  3. Subject: UNIX-Time the right way ...
  4. Message-ID: <18760@rpp386.cactus.org>
  5. Date: 29 Nov 90 16:12:15 GMT
  6.  
  7. There is nothing worse than dumb, stupid, slow code.
  8.  
  9. These is also nothing worse than people whose IQ is so low
  10. that they can't take a hint and do something productive
  11. with it.  Please, people, some of you claim to be programmers,
  12. how about living up to those claims?  I'm really sorry I feel
  13. this need to insult some people, but gee guys, at least take
  14. the effort to try my suggestions before attacking me as
  15. writing buggy or inaccurate code.  Of course, having not been
  16. paid to write this code I will tell you that under certain
  17. conditions it may loop infinitely, but then you get what you
  18. pay for.  Try 2/31/88 for a nice time.
  19.  
  20. Test results after the source code.  You will notice that this
  21. code correctly handles daylight savings time, as well as
  22. hours, minutes, and seconds.  You will also notice that it
  23. calls localtime 1/15th or so less often.  It even does leap
  24. days.
  25.  
  26. There is nothing wrong with being "clever", but binary
  27. approximation is as old as Newton, if not older.
  28. --
  29. /*
  30.  * Copyright 1990, John F. Haugh II
  31.  * All rights reserved.
  32.  *
  33.  * Use, duplication, and disclosure prohibited without
  34.  * the express written permission of the author.
  35.  *
  36.  * Non-commercial (profit-making) source distribution permitted
  37.  * provided this notice remains intact.
  38.  */
  39.  
  40. #include <time.h>
  41.  
  42. /*
  43.  * days and juldays are used to compute the number of days in the
  44.  * current month, and the cummulative number of days in the preceding
  45.  * months.
  46.  */
  47.  
  48. static    short    days[12] = {
  49.     31,    28,    31,    30,    31,    30,    /* JAN - JUN */
  50.     31,    31,    30,    31,    30,    31 };    /* JUL - DEC */
  51.  
  52. static    short    juldays[12] = {
  53.     0,    31,    59,    90,    120,    151,    /* JAN - JUN */
  54.     181,    212,    243,    273,    304,    334 };    /* JUL - DEC */
  55.  
  56. static long
  57. dtime (tm, time)
  58. struct    tm    *tm;
  59. long    time;    /* no C */
  60. {
  61.     struct    tm    *sm;
  62.     long    diff;
  63.     long    julian1, julian2;
  64.  
  65.     sm = localtime (&time);
  66.  
  67.     julian1 = ((tm->tm_year - 70) * 365) +    /* days in whole years */
  68.         (((tm->tm_year + 1) - 70) / 4);    /* days in leap years */
  69.     julian1 += juldays[tm->tm_mon] +    /* days in whole months */
  70.         (tm->tm_mon > 1 && (tm->tm_year % 4) == 0 ? 1:0); /* leap day */
  71.     julian1 += tm->tm_mday - 1;        /* days so far this month */
  72.  
  73.     julian2 = ((sm->tm_year - 70) * 365) +    /* days in whole years */
  74.         (((sm->tm_year + 1) - 70) / 4);    /* days in leap years */
  75.     julian2 += juldays[sm->tm_mon] +    /* days in whole months */
  76.         (sm->tm_mon > 1 && (sm->tm_year % 4) == 0 ? 1:0); /* leap day */
  77.     julian2 += sm->tm_mday - 1;        /* days so far this month */
  78.  
  79.     diff = (julian1 - julian2) * (24L*3600);    /* add the days */
  80.     diff += (tm->tm_hour - sm->tm_hour) * (3600L);    /* add the hours */
  81.     diff += (tm->tm_min - sm->tm_min) * (60L);    /* add the minutes */
  82.     diff += (tm->tm_sec - sm->tm_sec);        /* add the seconds */
  83.  
  84.     return diff;                /* that's how far off */
  85. }
  86.  
  87. long
  88. mktime (tm)
  89. struct    tm    *tm;
  90. {
  91.     long    old, diff, new;
  92.     struct    tm    *t;
  93.  
  94.     for (old = 0L;(diff = dtime (tm, old)) != 0;old += diff) {
  95. #ifdef    TEST
  96.         new = old + diff;
  97.         printf ("old = %ld, new = %ld\n", old, new);
  98.  
  99.         t = localtime (&old);
  100.         printf ("old = %d/%d/%d %d:%d:%d\n",
  101.             t->tm_mon + 1, t->tm_mday, t->tm_year,
  102.             t->tm_hour, t->tm_min, t->tm_sec);
  103.  
  104.         t = localtime (&new);
  105.         printf ("new = %d/%d/%d %d:%d:%d\n",
  106.             t->tm_mon + 1, t->tm_mday, t->tm_year,
  107.             t->tm_hour, t->tm_min, t->tm_sec);
  108. #else
  109.         ;
  110. #endif
  111.     }
  112.     return old;
  113. }
  114. #ifdef    TEST
  115. main ()
  116. {
  117.     long    t;
  118.     struct    tm    tm;
  119.     struct    tm    *ptm;
  120.     char    buf[100];
  121.  
  122.     while (gets (buf)) {
  123.         memset (&tm, 0, sizeof tm);
  124.  
  125.         sscanf (buf, "%d/%d/%d %d:%d:%d",
  126.             &tm.tm_mon, &tm.tm_mday, &tm.tm_year,
  127.             &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
  128.  
  129.         tm.tm_mon--;
  130.  
  131.         t = mktime (&tm);
  132.  
  133.         ptm = localtime (&t);
  134.         printf ("guess = %d or %d/%d/%d %d:%d:%d\n",
  135.             t, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_year,
  136.             ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
  137.     }
  138. }
  139. #endif
  140. --
  141. Script is typescript, started Thu Nov 29 10:00:25 1990
  142. rpp386-> ./mktime
  143. 1/1/70 0:0:0
  144. old = 0, new = 21600
  145. old = 12/31/69 18:0:0
  146. new = 1/1/70 0:0:0
  147. guess = 21600 or 1/1/70 0:0:0
  148. 12/31/69 18:0:0
  149. guess = 0 or 12/31/69 18:0:0
  150. 11/29/90 10:00:25
  151. old = 0, new = 659894425
  152. old = 12/31/69 18:0:0
  153. new = 11/29/90 10:0:25
  154. guess = 659894425 or 11/29/90 10:0:25
  155. 6/1/90 12:00:00
  156. old = 0, new = 644263200
  157. old = 12/31/69 18:0:0
  158. new = 6/1/90 13:0:0
  159. old = 644263200, new = 644259600
  160. old = 6/1/90 13:0:0
  161. new = 6/1/90 12:0:0
  162. guess = 644259600 or 6/1/90 12:0:0
  163. 10/21/90 01:00:00
  164. old = 0, new = 656492400
  165. old = 12/31/69 18:0:0
  166. new = 10/21/90 2:0:0
  167. old = 656492400, new = 656488800
  168. old = 10/21/90 2:0:0
  169. new = 10/21/90 1:0:0
  170. guess = 656488800 or 10/21/90 1:0:0
  171. 10/21/90 02:00:00
  172. old = 0, new = 656496000
  173. old = 12/31/69 18:0:0
  174. new = 10/21/90 3:0:0
  175. old = 656496000, new = 656492400
  176. old = 10/21/90 3:0:0
  177. new = 10/21/90 2:0:0
  178. guess = 656492400 or 10/21/90 2:0:0
  179. 10/21/90 3:0:0
  180. old = 0, new = 656499600
  181. old = 12/31/69 18:0:0
  182. new = 10/21/90 4:0:0
  183. old = 656499600, new = 656496000
  184. old = 10/21/90 4:0:0
  185. new = 10/21/90 3:0:0
  186. guess = 656496000 or 10/21/90 3:0:0
  187. 10/28/90 1:0:0
  188. old = 0, new = 657097200
  189. old = 12/31/69 18:0:0
  190. new = 10/28/90 1:0:0
  191. guess = 657097200 or 10/28/90 1:0:0
  192. 10/28/90 2:0:0
  193. old = 0, new = 657100800
  194. old = 12/31/69 18:0:0
  195. new = 10/28/90 2:0:0
  196. guess = 657100800 or 10/28/90 2:0:0
  197. rpp386-> exit
  198. Script done Thu Nov 29 10:03:31 1990
  199. -- 
  200. John F. Haugh II                             UUCP: ...!cs.utexas.edu!rpp386!jfh
  201. Ma Bell: (512) 832-8832                           Domain: jfh@rpp386.cactus.org
  202. "SCCS, the source motel!  Programs check in and never check out!"
  203.         -- Ken Thompson
  204.