ctime.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       ctime.c (3082B)
       ---
            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  *
            8  *        seconds (0-59)
            9  *        minutes (0-59)
           10  *        hours (0-23)
           11  *        day of month (1-31)
           12  *        month (0-11)
           13  *        year-1970
           14  *        weekday (0-6, Sun is 0)
           15  *        day of the year
           16  *        daylight savings flag
           17  *
           18  * The routine gets the daylight savings time from the environment.
           19  *
           20  * asctime(tvec))
           21  * where tvec is produced by localtime
           22  * returns a ptr to a character string
           23  * that has the ascii time in the form
           24  *
           25  *                                    \\
           26  *        Thu Jan 01 00:00:00 GMT 1970n0
           27  *        012345678901234567890123456789
           28  *        0          1            2
           29  *
           30  * ctime(t) just calls localtime, then asctime.
           31  */
           32 
           33 #include <u.h>
           34 #include <libc.h>
           35 
           36 #include "zoneinfo.h"
           37 
           38 static        char        dmsize[12] =
           39 {
           40         31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
           41 };
           42 
           43 #define dysize ctimedysize
           44 static        int        dysize(int);
           45 static        void        ct_numb(char*, int);
           46 
           47 char*
           48 ctime(long t)
           49 {
           50         return asctime(localtime(t));
           51 }
           52 
           53 Tm*
           54 localtime(long tim)
           55 {
           56         Tinfo ti;
           57         Tm *ct;
           58 
           59         if (zonelookuptinfo(&ti, tim)!=-1) {
           60                 ct = gmtime(tim+ti.tzoff);
           61                 strncpy(ct->zone, ti.zone, sizeof ct->zone);
           62                 ct->zone[sizeof ct->zone-1] = 0;
           63                 ct->tzoff = ti.tzoff;
           64                 return ct;
           65         }
           66         return gmtime(tim);
           67 }
           68 
           69 Tm*
           70 gmtime(long tim)
           71 {
           72         int d0, d1;
           73         long hms, day;
           74         static Tm xtime;
           75 
           76         /*
           77          * break initial number into days
           78          */
           79         hms = tim % 86400L;
           80         day = tim / 86400L;
           81         if(hms < 0) {
           82                 hms += 86400L;
           83                 day -= 1;
           84         }
           85 
           86         /*
           87          * generate hours:minutes:seconds
           88          */
           89         xtime.sec = hms % 60;
           90         d1 = hms / 60;
           91         xtime.min = d1 % 60;
           92         d1 /= 60;
           93         xtime.hour = d1;
           94 
           95         /*
           96          * day is the day number.
           97          * generate day of the week.
           98          * The addend is 4 mod 7 (1/1/1970 was Thursday)
           99          */
          100 
          101         xtime.wday = (day + 7340036L) % 7;
          102 
          103         /*
          104          * year number
          105          */
          106         if(day >= 0)
          107                 for(d1 = 1970; day >= dysize(d1); d1++)
          108                         day -= dysize(d1);
          109         else
          110                 for (d1 = 1970; day < 0; d1--)
          111                         day += dysize(d1-1);
          112         xtime.year = d1-1900;
          113         xtime.yday = d0 = day;
          114 
          115         /*
          116          * generate month
          117          */
          118 
          119         if(dysize(d1) == 366)
          120                 dmsize[1] = 29;
          121         for(d1 = 0; d0 >= dmsize[d1]; d1++)
          122                 d0 -= dmsize[d1];
          123         dmsize[1] = 28;
          124         xtime.mday = d0 + 1;
          125         xtime.mon = d1;
          126         strcpy(xtime.zone, "GMT");
          127         return &xtime;
          128 }
          129 
          130 char*
          131 asctime(Tm *t)
          132 {
          133         char *ncp;
          134         static char cbuf[30];
          135 
          136         strcpy(cbuf, "Thu Jan 01 00:00:00 GMT 1970\n");
          137         ncp = &"SunMonTueWedThuFriSat"[t->wday*3];
          138         cbuf[0] = *ncp++;
          139         cbuf[1] = *ncp++;
          140         cbuf[2] = *ncp;
          141         ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[t->mon*3];
          142         cbuf[4] = *ncp++;
          143         cbuf[5] = *ncp++;
          144         cbuf[6] = *ncp;
          145         ct_numb(cbuf+8, t->mday);
          146         ct_numb(cbuf+11, t->hour+100);
          147         ct_numb(cbuf+14, t->min+100);
          148         ct_numb(cbuf+17, t->sec+100);
          149         ncp = t->zone;
          150         cbuf[20] = *ncp++;
          151         cbuf[21] = *ncp++;
          152         cbuf[22] = *ncp;
          153         if(t->year >= 100) {
          154                 cbuf[24] = '2';
          155                 cbuf[25] = '0';
          156         }
          157         ct_numb(cbuf+26, t->year+100);
          158         return cbuf;
          159 }
          160 
          161 static
          162 int
          163 dysize(int y)
          164 {
          165 
          166         if(y%4 == 0 && (y%100 != 0 || y%400 == 0))
          167                 return 366;
          168         return 365;
          169 }
          170 
          171 static
          172 void
          173 ct_numb(char *cp, int n)
          174 {
          175 
          176         cp[0] = ' ';
          177         if(n >= 10)
          178                 cp[0] = (n/10)%10 + '0';
          179         cp[1] = n%10 + '0';
          180 }
          181