| /* |
| * This routine converts time as follows. |
| * The epoch is 0000 Jan 1 1970 GMT. |
| * The argument time is in seconds since then. |
| * The localtime(t) entry returns a pointer to an array |
| * containing |
| * |
| * seconds (0-59) |
| * minutes (0-59) |
| * hours (0-23) |
| * day of month (1-31) |
| * month (0-11) |
| * year-1970 |
| * weekday (0-6, Sun is 0) |
| * day of the year |
| * daylight savings flag |
| * |
| * The routine gets the daylight savings time from the environment. |
| * |
| * asctime(tvec)) |
| * where tvec is produced by localtime |
| * returns a ptr to a character string |
| * that has the ascii time in the form |
| * |
| * \\ |
| * Thu Jan 01 00:00:00 GMT 1970n0 |
| * 012345678901234567890123456789 |
| * 0 1 2 |
| * |
| * ctime(t) just calls localtime, then asctime. |
| */ |
| |
| #include <u.h> |
| #include <libc.h> |
| |
| #include "zoneinfo.h" |
| |
| static char dmsize[12] = |
| { |
| 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
| }; |
| |
| #define dysize ctimedysize |
| static int dysize(int); |
| static void ct_numb(char*, int); |
| |
| char* |
| ctime(long t) |
| { |
| return asctime(localtime(t)); |
| } |
| |
| Tm* |
| localtime(long tim) |
| { |
| Tinfo ti; |
| Tm *ct; |
| |
| if (zonelookuptinfo(&ti, tim)!=-1) { |
| ct = gmtime(tim+ti.tzoff); |
| strncpy(ct->zone, ti.zone, sizeof ct->zone); |
| ct->zone[sizeof ct->zone-1] = 0; |
| ct->tzoff = ti.tzoff; |
| return ct; |
| } |
| return gmtime(tim); |
| } |
| |
| Tm* |
| gmtime(long tim) |
| { |
| int d0, d1; |
| long hms, day; |
| static Tm xtime; |
| |
| /* |
| * break initial number into days |
| */ |
| hms = tim % 86400L; |
| day = tim / 86400L; |
| if(hms < 0) { |
| hms += 86400L; |
| day -= 1; |
| } |
| |
| /* |
| * generate hours:minutes:seconds |
| */ |
| xtime.sec = hms % 60; |
| d1 = hms / 60; |
| xtime.min = d1 % 60; |
| d1 /= 60; |
| xtime.hour = d1; |
| |
| /* |
| * day is the day number. |
| * generate day of the week. |
| * The addend is 4 mod 7 (1/1/1970 was Thursday) |
| */ |
| |
| xtime.wday = (day + 7340036L) % 7; |
| |
| /* |
| * year number |
| */ |
| if(day >= 0) |
| for(d1 = 1970; day >= dysize(d1); d1++) |
| day -= dysize(d1); |
| else |
| for (d1 = 1970; day < 0; d1--) |
| day += dysize(d1-1); |
| xtime.year = d1-1900; |
| xtime.yday = d0 = day; |
| |
| /* |
| * generate month |
| */ |
| |
| if(dysize(d1) == 366) |
| dmsize[1] = 29; |
| for(d1 = 0; d0 >= dmsize[d1]; d1++) |
| d0 -= dmsize[d1]; |
| dmsize[1] = 28; |
| xtime.mday = d0 + 1; |
| xtime.mon = d1; |
| strcpy(xtime.zone, "GMT"); |
| return &xtime; |
| } |
| |
| char* |
| asctime(Tm *t) |
| { |
| const char *ncp; |
| static char cbuf[30]; |
| |
| strcpy(cbuf, "Thu Jan 01 00:00:00 GMT 1970\n"); |
| ncp = &"SunMonTueWedThuFriSat"[t->wday*3]; |
| cbuf[0] = *ncp++; |
| cbuf[1] = *ncp++; |
| cbuf[2] = *ncp; |
| ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[t->mon*3]; |
| cbuf[4] = *ncp++; |
| cbuf[5] = *ncp++; |
| cbuf[6] = *ncp; |
| ct_numb(cbuf+8, t->mday); |
| ct_numb(cbuf+11, t->hour+100); |
| ct_numb(cbuf+14, t->min+100); |
| ct_numb(cbuf+17, t->sec+100); |
| ncp = t->zone; |
| cbuf[20] = *ncp++; |
| cbuf[21] = *ncp++; |
| cbuf[22] = *ncp; |
| if(t->year >= 100) { |
| cbuf[24] = '2'; |
| cbuf[25] = '0'; |
| } |
| ct_numb(cbuf+26, t->year+100); |
| return cbuf; |
| } |
| |
| static |
| int |
| dysize(int y) |
| { |
| |
| if(y%4 == 0 && (y%100 != 0 || y%400 == 0)) |
| return 366; |
| return 365; |
| } |
| |
| static |
| void |
| ct_numb(char *cp, int n) |
| { |
| |
| cp[0] = ' '; |
| if(n >= 10) |
| cp[0] = (n/10)%10 + '0'; |
| cp[1] = n%10 + '0'; |
| } |
| |