9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | 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