ctime.c - 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 |