home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / libc / gen / ctime.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  4.4 KB  |  246 lines

  1. /*
  2.  * This routine converts time as follows.
  3.  * The epoch is 0000 Jan 1 1970 GMT.
  4.  * The argument time is in seconds since then.
  5.  * The localtime(t) entry returns a pointer to an array
  6.  * containing
  7.  *  seconds (0-59)
  8.  *  minutes (0-59)
  9.  *  hours (0-23)
  10.  *  day of month (1-31)
  11.  *  month (0-11)
  12.  *  year-1970
  13.  *  weekday (0-6, Sun is 0)
  14.  *  day of the year
  15.  *  daylight savings flag
  16.  *
  17.  * The routine calls the system to determine the local
  18.  * timezone and whether Daylight Saving Time is permitted locally.
  19.  * (DST is then determined by the current US standard rules)
  20.  * There is a table that accounts for the peculiarities
  21.  * undergone by daylight time in 1974-1975.
  22.  *
  23.  * The routine does not work
  24.  * in Saudi Arabia which runs on Solar time.
  25.  *
  26.  * asctime(tvec))
  27.  * where tvec is produced by localtime
  28.  * returns a ptr to a character string
  29.  * that has the ascii time in the form
  30.  *    Thu Jan 01 00:00:00 1970n0\\
  31.  *    01234567890123456789012345
  32.  *    0      1        2
  33.  *
  34.  * ctime(t) just calls localtime, then asctime.
  35.  */
  36.  
  37. #include <time.h>
  38. #include <sys/types.h>
  39. #include <sys/timeb.h>
  40.  
  41. static    char    cbuf[26];
  42. static    int    dmsize[12] =
  43. {
  44.     31,
  45.     28,
  46.     31,
  47.     30,
  48.     31,
  49.     30,
  50.     31,
  51.     31,
  52.     30,
  53.     31,
  54.     30,
  55.     31
  56. };
  57.  
  58. /*
  59.  * The following table is used for 1974 and 1975 and
  60.  * gives the day number of the first day after the Sunday of the
  61.  * change.
  62.  */
  63. static struct {
  64.     int    daylb;
  65.     int    dayle;
  66. } daytab[] = {
  67.     5,    333,    /* 1974: Jan 6 - last Sun. in Nov */
  68.     58,    303,    /* 1975: Last Sun. in Feb - last Sun in Oct */
  69. };
  70.  
  71. struct tm    *gmtime();
  72. char        *ct_numb();
  73. struct tm    *localtime();
  74. char    *ctime();
  75. char    *ct_num();
  76. char    *asctime();
  77.  
  78. char *
  79. ctime(t)
  80. long *t;
  81. {
  82.     return(asctime(localtime(t)));
  83. }
  84.  
  85. struct tm *
  86. localtime(tim)
  87. long *tim;
  88. {
  89.     register int dayno;
  90.     register struct tm *ct;
  91.     register daylbegin, daylend;
  92.     long copyt;
  93.     struct timeb systime;
  94.  
  95.     ftime(&systime);
  96.     copyt = *tim - (long)systime.timezone*60;
  97.     ct = gmtime(©t);
  98.     dayno = ct->tm_yday;
  99.     daylbegin = 119;    /* last Sun in Apr */
  100.     daylend = 303;        /* Last Sun in Oct */
  101.     if (ct->tm_year==74 || ct->tm_year==75) {
  102.         daylbegin = daytab[ct->tm_year-74].daylb;
  103.         daylend = daytab[ct->tm_year-74].dayle;
  104.     }
  105.     daylbegin = sunday(ct, daylbegin);
  106.     daylend = sunday(ct, daylend);
  107.     if (systime.dstflag &&
  108.         (dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) &&
  109.         (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) {
  110.         copyt += 1*60*60;
  111.         ct = gmtime(©t);
  112.         ct->tm_isdst++;
  113.     }
  114.     return(ct);
  115. }
  116.  
  117. /*
  118.  * The argument is a 0-origin day number.
  119.  * The value is the day number of the first
  120.  * Sunday on or after the day.
  121.  */
  122. static
  123. sunday(t, d)
  124. register struct tm *t;
  125. register int d;
  126. {
  127.     if (d >= 58)
  128.         d += dysize(t->tm_year) - 365;
  129.     return(d - (d - t->tm_yday + t->tm_wday + 700) % 7);
  130. }
  131.  
  132. struct tm *
  133. gmtime(tim)
  134. long *tim;
  135. {
  136.     register int d0, d1;
  137.     long hms, day;
  138.     register int *tp;
  139.     static struct tm xtime;
  140.  
  141.     /*
  142.      * break initial number into days
  143.      */
  144.     hms = *tim % 86400;
  145.     day = *tim / 86400;
  146.     if (hms<0) {
  147.         hms += 86400;
  148.         day -= 1;
  149.     }
  150.     tp = (int *)&xtime;
  151.  
  152.     /*
  153.      * generate hours:minutes:seconds
  154.      */
  155.     *tp++ = hms%60;
  156.     d1 = hms/60;
  157.     *tp++ = d1%60;
  158.     d1 /= 60;
  159.     *tp++ = d1;
  160.  
  161.     /*
  162.      * day is the day number.
  163.      * generate day of the week.
  164.      * The addend is 4 mod 7 (1/1/1970 was Thursday)
  165.      */
  166.  
  167.     xtime.tm_wday = (day+7340036)%7;
  168.  
  169.     /*
  170.      * year number
  171.      */
  172.     if (day>=0) for(d1=70; day >= dysize(d1); d1++)
  173.         day -= dysize(d1);
  174.     else for (d1=70; day<0; d1--)
  175.         day += dysize(d1-1);
  176.     xtime.tm_year = d1;
  177.     xtime.tm_yday = d0 = day;
  178.  
  179.     /*
  180.      * generate month
  181.      */
  182.  
  183.     if (dysize(d1)==366)
  184.         dmsize[1] = 29;
  185.     for(d1=0; d0 >= dmsize[d1]; d1++)
  186.         d0 -= dmsize[d1];
  187.     dmsize[1] = 28;
  188.     *tp++ = d0+1;
  189.     *tp++ = d1;
  190.     xtime.tm_isdst = 0;
  191.     return(&xtime);
  192. }
  193.  
  194. char *
  195. asctime(t)
  196. struct tm *t;
  197. {
  198.     register char *cp, *ncp;
  199.     register int *tp;
  200.  
  201.     cp = cbuf;
  202.     for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;);
  203.     ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday];
  204.     cp = cbuf;
  205.     *cp++ = *ncp++;
  206.     *cp++ = *ncp++;
  207.     *cp++ = *ncp++;
  208.     cp++;
  209.     tp = &t->tm_mon;
  210.     ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3];
  211.     *cp++ = *ncp++;
  212.     *cp++ = *ncp++;
  213.     *cp++ = *ncp++;
  214.     cp = ct_numb(cp, *--tp);
  215.     cp = ct_numb(cp, *--tp+100);
  216.     cp = ct_numb(cp, *--tp+100);
  217.     cp = ct_numb(cp, *--tp+100);
  218.     if (t->tm_year>=100) {
  219.         cp[1] = '2';
  220.         cp[2] = '0';
  221.     }
  222.     cp += 2;
  223.     cp = ct_numb(cp, t->tm_year+100);
  224.     return(cbuf);
  225. }
  226.  
  227. dysize(y)
  228. {
  229.     if((y%4) == 0)
  230.         return(366);
  231.     return(365);
  232. }
  233.  
  234. static char *
  235. ct_numb(cp, n)
  236. register char *cp;
  237. {
  238.     cp++;
  239.     if (n>=10)
  240.         *cp++ = (n/10)%10 + '0';
  241.     else
  242.         *cp++ = ' ';
  243.     *cp++ = n%10 + '0';
  244.     return(cp);
  245. }
  246.