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