Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
static	char	dmsize[12] =
37
{
38
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
39
};
40
 
41
/*
42
 * The following table is used for 1974 and 1975 and
43
 * gives the day number of the first day after the Sunday of the
44
 * change.
45
 */
46
 
47
static	int	dysize(int);
48
static	void	ct_numb(char*, int);
49
 
50
#define	TZSIZE	150
51
static	void	readtimezone(void);
52
static	int	rd_name(char**, char*);
53
static	int	rd_long(char**, long*);
54
static
55
struct
56
{
57
	char	stname[4];
58
	char	dlname[4];
59
	long	stdiff;
60
	long	dldiff;
61
	long	dlpairs[TZSIZE];
62
} timezone;
63
 
64
char*
65
ctime(long t)
66
{
67
	return asctime(localtime(t));
68
}
69
 
70
Tm*
71
localtime(long tim)
72
{
73
	Tm *ct;
74
	long t, *p;
75
	int dlflag;
76
 
77
	if(timezone.stname[0] == 0)
78
		readtimezone();
79
	t = tim + timezone.stdiff;
80
	dlflag = 0;
81
	for(p = timezone.dlpairs; *p; p += 2)
82
		if(t >= p[0])
83
		if(t < p[1]) {
84
			t = tim + timezone.dldiff;
85
			dlflag++;
86
			break;
87
		}
88
	ct = gmtime(t);
89
	if(dlflag){
90
		strcpy(ct->zone, timezone.dlname);
91
		ct->tzoff = timezone.dldiff;
92
	} else {
93
		strcpy(ct->zone, timezone.stname);
94
		ct->tzoff = timezone.stdiff;
95
	}
96
	return ct;
97
}
98
 
99
Tm*
100
gmtime(long tim)
101
{
102
	int d0, d1;
103
	long hms, day;
104
	static Tm xtime;
105
 
106
	/*
107
	 * break initial number into days
108
	 */
109
	hms = (ulong)tim % 86400L;
110
	day = (ulong)tim / 86400L;
111
	if(hms < 0) {
112
		hms += 86400L;
113
		day -= 1;
114
	}
115
 
116
	/*
117
	 * generate hours:minutes:seconds
118
	 */
119
	xtime.sec = hms % 60;
120
	d1 = hms / 60;
121
	xtime.min = d1 % 60;
122
	d1 /= 60;
123
	xtime.hour = d1;
124
 
125
	/*
126
	 * day is the day number.
127
	 * generate day of the week.
128
	 * The addend is 4 mod 7 (1/1/1970 was Thursday)
129
	 */
130
 
131
	xtime.wday = (day + 7340036L) % 7;
132
 
133
	/*
134
	 * year number
135
	 */
136
	if(day >= 0)
137
		for(d1 = 1970; day >= dysize(d1); d1++)
138
			day -= dysize(d1);
139
	else
140
		for (d1 = 1970; day < 0; d1--)
141
			day += dysize(d1-1);
142
	xtime.year = d1-1900;
143
	xtime.yday = d0 = day;
144
 
145
	/*
146
	 * generate month
147
	 */
148
 
149
	if(dysize(d1) == 366)
150
		dmsize[1] = 29;
151
	for(d1 = 0; d0 >= dmsize[d1]; d1++)
152
		d0 -= dmsize[d1];
153
	dmsize[1] = 28;
154
	xtime.mday = d0 + 1;
155
	xtime.mon = d1;
156
	strcpy(xtime.zone, "GMT");
157
	return &xtime;
158
}
159
 
160
char*
161
asctime(Tm *t)
162
{
163
	char *ncp;
164
	static char cbuf[30];
165
 
166
	strcpy(cbuf, "Thu Jan 01 00:00:00 GMT 1970\n");
167
	ncp = &"SunMonTueWedThuFriSat"[t->wday*3];
168
	cbuf[0] = *ncp++;
169
	cbuf[1] = *ncp++;
170
	cbuf[2] = *ncp;
171
	ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[t->mon*3];
172
	cbuf[4] = *ncp++;
173
	cbuf[5] = *ncp++;
174
	cbuf[6] = *ncp;
175
	ct_numb(cbuf+8, t->mday);
176
	ct_numb(cbuf+11, t->hour+100);
177
	ct_numb(cbuf+14, t->min+100);
178
	ct_numb(cbuf+17, t->sec+100);
179
	ncp = t->zone;
180
	cbuf[20] = *ncp++;
181
	cbuf[21] = *ncp++;
182
	cbuf[22] = *ncp;
183
	if(t->year >= 100) {
184
		cbuf[24] = '2';
185
		cbuf[25] = '0';
186
	}
187
	ct_numb(cbuf+26, t->year+100);
188
	return cbuf;
189
}
190
 
191
static
192
dysize(int y)
193
{
194
 
195
	if(y%4 == 0 && (y%100 != 0 || y%400 == 0))
196
		return 366;
197
	return 365;
198
}
199
 
200
static
201
void
202
ct_numb(char *cp, int n)
203
{
204
 
205
	cp[0] = ' ';
206
	if(n >= 10)
207
		cp[0] = (n/10)%10 + '0';
208
	cp[1] = n%10 + '0';
209
}
210
 
211
static
212
void
213
readtimezone(void)
214
{
215
	char buf[TZSIZE*11+30], *p;
216
	int i;
217
 
218
	memset(buf, 0, sizeof(buf));
219
	i = open("/env/timezone", 0);
220
	if(i < 0)
221
		goto error;
222
	if(read(i, buf, sizeof(buf)) >= sizeof(buf)){
223
		close(i);
224
		goto error;
225
	}
226
	close(i);
227
	p = buf;
228
	if(rd_name(&p, timezone.stname))
229
		goto error;
230
	if(rd_long(&p, &timezone.stdiff))
231
		goto error;
232
	if(rd_name(&p, timezone.dlname))
233
		goto error;
234
	if(rd_long(&p, &timezone.dldiff))
235
		goto error;
236
	for(i=0; i<TZSIZE; i++) {
237
		if(rd_long(&p, &timezone.dlpairs[i]))
238
			goto error;
239
		if(timezone.dlpairs[i] == 0)
240
			return;
241
	}
242
 
243
error:
244
	timezone.stdiff = 0;
245
	strcpy(timezone.stname, "GMT");
246
	timezone.dlpairs[0] = 0;
247
}
248
 
249
static
250
rd_name(char **f, char *p)
251
{
252
	int c, i;
253
 
254
	for(;;) {
255
		c = *(*f)++;
256
		if(c != ' ' && c != '\n')
257
			break;
258
	}
259
	for(i=0; i<3; i++) {
260
		if(c == ' ' || c == '\n')
261
			return 1;
262
		*p++ = c;
263
		c = *(*f)++;
264
	}
265
	if(c != ' ' && c != '\n')
266
		return 1;
267
	*p = 0;
268
	return 0;
269
}
270
 
271
static
272
rd_long(char **f, long *p)
273
{
274
	int c, s;
275
	long l;
276
 
277
	s = 0;
278
	for(;;) {
279
		c = *(*f)++;
280
		if(c == '-') {
281
			s++;
282
			continue;
283
		}
284
		if(c != ' ' && c != '\n')
285
			break;
286
	}
287
	if(c == 0) {
288
		*p = 0;
289
		return 0;
290
	}
291
	l = 0;
292
	for(;;) {
293
		if(c == ' ' || c == '\n')
294
			break;
295
		if(c < '0' || c > '9')
296
			return 1;
297
		l = l*10 + c-'0';
298
		c = *(*f)++;
299
	}
300
	if(s)
301
		l = -l;
302
	*p = l;
303
	return 0;
304
}