Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
#include	"all.h"
2
 
3
static	int	sunday(Tm *t, int d);
4
static	int	dysize(int);
5
static	void	ct_numb(char*, int);
6
static	void	klocaltime(long tim, Tm *ct);
7
static	void	kgmtime(long tim, Tm *ct);
8
 
9
static	char	dmsize[12] =
10
{
11
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
12
};
13
 
14
/*
15
 * The following table is used for 1974 and 1975 and
16
 * gives the day number of the first day after the Sunday of the
17
 * change.
18
 */
19
static	struct
20
{
21
	short	yrfrom;
22
	short	yrto;
23
	short	daylb;
24
	short	dayle;
25
} daytab[] =
26
{
27
	87,	999,	97,	303,
28
	76,	86,	119,	303,
29
	75,	75,	58,	303,
30
	74,	74,	5,	333,
31
	0,	73,	119,	303,
32
};
33
 
34
static struct
35
{
36
	short	minuteswest;	/* minutes west of Greenwich */
37
	short	dsttime;	/* dst correction */
38
} timezone =
39
{
40
	5*60, 1
41
};
42
 
43
static void
44
klocaltime(long tim, Tm *ct)
45
{
46
	int daylbegin, daylend, dayno, i;
47
	long copyt;
48
 
49
	copyt = tim - timezone.minuteswest*60L;
50
	kgmtime(copyt, ct);
51
	dayno = ct->yday;
52
	for(i=0;; i++)
53
		if(ct->year >= daytab[i].yrfrom &&
54
		   ct->year <= daytab[i].yrto) {
55
			daylbegin = sunday(ct, daytab[i].daylb);
56
			daylend = sunday(ct, daytab[i].dayle);
57
			break;
58
		}
59
	if(timezone.dsttime &&
60
	    (dayno>daylbegin || (dayno==daylbegin && ct->hour>=2)) &&
61
	    (dayno<daylend || (dayno==daylend && ct->hour<1))) {
62
		copyt += 60L*60L;
63
		kgmtime(copyt, ct);
64
	}
65
}
66
 
67
/*
68
 * The argument is a 0-origin day number.
69
 * The value is the day number of the last
70
 * Sunday before or after the day.
71
 */
72
static
73
sunday(Tm *t, int d)
74
{
75
	if(d >= 58)
76
		d += dysize(t->year) - 365;
77
	return d - (d - t->yday + t->wday + 700) % 7;
78
}
79
 
80
static void
81
kgmtime(long tim, Tm *ct)
82
{
83
	int d0, d1;
84
	long hms, day;
85
 
86
	/*
87
	 * break initial number into days
88
	 */
89
	hms = tim % 86400L;
90
	day = tim / 86400L;
91
	if(hms < 0) {
92
		hms += 86400L;
93
		day -= 1;
94
	}
95
 
96
	/*
97
	 * generate hours:minutes:seconds
98
	 */
99
	ct->sec = hms % 60;
100
	d1 = hms / 60;
101
	ct->min = d1 % 60;
102
	d1 /= 60;
103
	ct->hour = d1;
104
 
105
	/*
106
	 * day is the day number.
107
	 * generate day of the week.
108
	 * The addend is 4 mod 7 (1/1/1970 was Thursday)
109
	 */
110
 
111
	ct->wday = (day + 7340036L) % 7;
112
 
113
	/*
114
	 * year number
115
	 */
116
	if(day >= 0)
117
		for(d1 = 70; day >= dysize(d1); d1++)
118
			day -= dysize(d1);
119
	else
120
		for (d1 = 70; day < 0; d1--)
121
			day += dysize(d1-1);
122
	ct->year = d1;
123
	ct->yday = d0 = day;
124
 
125
	/*
126
	 * generate month
127
	 */
128
 
129
	if(dysize(d1) == 366)
130
		dmsize[1] = 29;
131
	for(d1 = 0; d0 >= dmsize[d1]; d1++)
132
		d0 -= dmsize[d1];
133
	dmsize[1] = 28;
134
	ct->mday = d0 + 1;
135
	ct->mon = d1;
136
}
137
 
138
void
139
datestr(char *s, long t)
140
{
141
	Tm tm;
142
 
143
	klocaltime(t, &tm);
144
	sprint(s, "%.4d%.2d%.2d", tm.year+1900, tm.mon+1, tm.mday);
145
}
146
 
147
int
148
Tfmt(Fmt *f1)
149
{
150
	char s[30];
151
	char *cp;
152
	long t;
153
	Tm tm;
154
 
155
	t = va_arg(f1->args, long);
156
	if(t == 0)
157
		return fmtstrcpy(f1, "The Epoch");
158
 
159
	klocaltime(t, &tm);
160
	strcpy(s, "Day Mon 00 00:00:00 1900");
161
	cp = &"SunMonTueWedThuFriSat"[tm.wday*3];
162
	s[0] = cp[0];
163
	s[1] = cp[1];
164
	s[2] = cp[2];
165
	cp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[tm.mon*3];
166
	s[4] = cp[0];
167
	s[5] = cp[1];
168
	s[6] = cp[2];
169
	ct_numb(s+8, tm.mday);
170
	ct_numb(s+11, tm.hour+100);
171
	ct_numb(s+14, tm.min+100);
172
	ct_numb(s+17, tm.sec+100);
173
	if(tm.year >= 100) {
174
		s[20] = '2';
175
		s[21] = '0';
176
	}
177
	ct_numb(s+22, tm.year+100);
178
 
179
	return fmtstrcpy(f1, s);
180
}
181
 
182
static
183
dysize(int y)
184
{
185
 
186
	if((y%4) == 0)
187
		return 366;
188
	return 365;
189
}
190
 
191
static
192
void
193
ct_numb(char *cp, int n)
194
{
195
 
196
	if(n >= 10)
197
		cp[0] = (n/10)%10 + '0';
198
	else
199
		cp[0] = ' ';
200
	cp[1] = n%10 + '0';
201
}
202
 
203
/*
204
 * compute the next time after t
205
 * that has hour hr and is not on
206
 * day in bitpattern --
207
 * for automatic dumps
208
 */
209
long
210
nextime(long t, int hr, int day)
211
{
212
	Tm tm;
213
	int nhr;
214
 
215
	if(hr < 0 || hr >= 24)
216
		hr = 5;
217
	if((day&0x7f) == 0x7f)
218
		day = 0;
219
 
220
loop:
221
	klocaltime(t, &tm);
222
	t -= tm.sec;
223
	t -= tm.min*60;
224
	nhr = tm.hour;
225
	do {
226
		t += 60*60;
227
		nhr++;
228
	} while(nhr%24 != hr);
229
	klocaltime(t, &tm);
230
	if(tm.hour != hr) {
231
		t += 60*60;
232
		klocaltime(t, &tm);
233
		if(tm.hour != hr) {
234
			t -= 60*60;
235
			klocaltime(t, &tm);
236
		}
237
	}
238
	if(day & (1<<tm.wday)) {
239
		t += 12*60*60;
240
		goto loop;
241
	}
242
	return t;
243
}