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