home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / unixlib36d / src / c / mktime < prev    next >
Text File  |  1994-03-08  |  4KB  |  178 lines

  1. static char sccs_id[] = "@(#) mktime.c 3.0 " __DATE__ " HJR";
  2.  
  3. /* mktime.c (c) Copyright 1990 H.Rogers */
  4.  
  5. #include <time.h>
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <stdlib.h>
  9.  
  10. static unsigned int __tmonth[12] =
  11. {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  12.  
  13. static struct tm __tz[1] =    /* time struct */
  14. {
  15.   {0, 0, 0, 0, 0, 0, 0, 0, -1, 0, ""}
  16. };
  17.  
  18. /* Time zones are "[TZNAME][H][:M][DSTNAME]" where H:M gives the time *west*
  19.  * of GMT for the timezone. If DSTNAME appears then the time zone follows
  20.  * DST rules according to DSTNAME. Examples:
  21.  *
  22.  * "EST5EDT"            USA Eastern time zone
  23.  * "CST6CDT"            USA Central time zone
  24.  * "NFLDT3:30NFLD"      Newfoundland time (1:30 ahead of Eastern)
  25.  * "OZCST-9:30"         Australian Central time zone (no DST)
  26.  *
  27.  * DST is currently unimplemented: Other implementations involve very nasty
  28.  * code in order to cater for exception years (e.g. USA 1972). Also most
  29.  * assume USA rules for DST (which have changed 3 times since 1970), not UK
  30.  * rules (which have changed more often and are more complex :-( ). It's
  31.  * simpler to rely on the SysAdmin changing the system clock twice a year
  32.  * according to local custom. Leap seconds and the century offset are ignored,
  33.  * but the routines are correct to within a second till at least 2038... */
  34.  
  35. int timezone = 0;
  36.  
  37. void
  38. tzset (void)
  39. {
  40.   char *z;
  41.   register int i;
  42.  
  43.   if (!(z = getenv ("TZ")))
  44.     z = "GMT0UK";        /* default to GMT/UKDST */
  45.  
  46.   i = 0;
  47.   while (isalpha (*z))
  48.     {
  49.       if (i < 3)
  50.     {
  51.       __tz->tm_zone[i] = *z;
  52.       i++;
  53.     }
  54.       z++;
  55.     }
  56.   __tz->tm_zone[i] = 0;
  57.  
  58.   i = (int) strtol (z, &z, 10) * 3600;
  59.   if (*z == ':')
  60.     {
  61.       z++;
  62.       i += (int) strtol (z, &z, 10) * 60;
  63.     }
  64.  
  65.   __tz->tm_gmtoff = timezone = i;
  66. }
  67.  
  68. static struct tm *__mktm (register time_t);
  69.  
  70. struct tm *
  71. gmtime (register const time_t * tp)
  72. {
  73.   if (!(__tz->tm_zone[0]))
  74.     tzset ();
  75.  
  76.   return (__mktm (*tp));
  77. }
  78.  
  79. struct tm *
  80. localtime (register const time_t * tp)
  81. {
  82.   if (!(__tz->tm_zone[0]))
  83.     tzset ();
  84.  
  85.   return (__mktm ((*tp) - __tz->tm_gmtoff));
  86. }
  87.  
  88. static struct tm *
  89. __mktm (register time_t tm)
  90. {
  91.   register struct tm *t = __tz;
  92.   register time_t i, j, k;
  93.  
  94.   t->tm_isdst = -1;
  95.  
  96.   t->tm_wday = (tm / 86400 + 4) % 7;    /* 1st Jan 1970 = Thursday */
  97.  
  98.   t->tm_sec = tm % 60;
  99.   tm /= 60;
  100.   t->tm_min = tm % 60;
  101.   tm /= 60;
  102.   t->tm_hour = tm % 24;
  103.   tm /= 24;
  104.  
  105.   i = (365 << 1);        /* two years */
  106.  
  107.   if (tm >= i)            /* >= 1972 */
  108.     {
  109.       j = (tm - i) / 1461;
  110.       tm -= i + j * 1461;
  111.       k = tm ? ((tm - 1) / 365) : 0;
  112.       if (k)
  113.     {
  114.       tm -= 1 + k * 365;
  115.       __tmonth[1] = 28;
  116.     }
  117.       else
  118.     __tmonth[1] = 29;    /* Feb. hath 29 days in a leap year */
  119.       k += 2 + (j << 2);
  120.     }
  121.   else
  122.     /* < 1972 */
  123.     {
  124.       k = tm / 365;
  125.       tm -= k * 365;
  126.       __tmonth[1] = 28;
  127.     }
  128.  
  129.   t->tm_year = k + 70;
  130.   t->tm_yday = tm;
  131.  
  132.   k = tm;
  133.   j = 0;
  134.   while (k >= (i = __tmonth[j]))
  135.     k -= i, j++;
  136.  
  137.   t->tm_mon = j;
  138.   t->tm_mday = k + 1;
  139.  
  140.   return (t);
  141. }
  142.  
  143. time_t
  144. mktime (register struct tm * t)
  145. {
  146.   register time_t r;
  147.  
  148.   if ((t->tm_year - 70) < 0)
  149.     return ((time_t) - 1);
  150.  
  151.   r = t->tm_year - 70;
  152.  
  153.   if (r < 2)
  154.     r = r * 365;
  155.   else
  156.     {
  157.       register int i, j;
  158.  
  159.       i = (r - 2) & 3;
  160.       j = ((r - 2) >> 2) * 1461;
  161.       if (i)
  162.     {
  163.       r = (365 << 1) + j + 1 + i * 365;
  164.     }
  165.       else
  166.     r = (365 << 1) + j;
  167.     }
  168.  
  169.   r += t->tm_yday;
  170.   r = r * 24 + t->tm_hour;
  171.   r = r * 60 + t->tm_min;
  172.   r = r * 60 + t->tm_sec;
  173.  
  174.   r += t->tm_gmtoff;        /* mktime() is passed a localtime() struct */
  175.  
  176.   return (r);
  177. }
  178.