73 #include <sys/param.h>
74 #include <sys/types.h>
76 #include <sys/clock.h>
78 #define DAY (24 * 60 * 60)
80 #define LYC (4 * YEAR + 1)
81 #define T1980 (10 * 365 + 2)
85 #define FEB (JAN + 28)
86 #define MAR (FEB + 31)
87 #define APR (MAR + 30)
88 #define MAY (APR + 31)
89 #define JUN (MAY + 30)
90 #define JUL (JUN + 31)
91 #define AUG (JUL + 31)
92 #define SEP (AUG + 30)
93 #define OCT (SEP + 31)
94 #define NOV (OCT + 30)
95 #define DEC (NOV + 31)
99 #define ENC(y,m) (((y) << 9) | ((m) << 5))
101 static const struct {
138 timespec2fattime(
struct timespec *tsp,
int utc, uint16_t *ddp, uint16_t *dtp, uint8_t *dhp)
148 *dhp = (tsp->tv_sec & 1) * 100 + tsp->tv_nsec / 10000000;
150 *dtp = (t1 / 2) % 30;
151 *dtp |= ((t1 / 60) % 60) << 5;
152 *dtp |= ((t1 / 3600) % 24) << 11;
166 if (t2 >= ((2100 - 1980) / 4 *
LYC +
FEB))
178 while (m < 47 &&
mtab[m + 1].
days <= t2)
182 *ddp +=
mtab[m].coded;
185 t2 -=
mtab[m].days - 1;
197 #define DCOD(m, y, l) ((m) + YEAR * (y) + (l))
199 0,
DCOD( 0, 0, 0),
DCOD(
JAN, 0, 0),
DCOD(
FEB, 0, 1),
200 DCOD(
MAR, 0, 1),
DCOD(
APR, 0, 1),
DCOD(
MAY, 0, 1),
DCOD(
JUN, 0, 1),
201 DCOD(
JUL, 0, 1),
DCOD(
AUG, 0, 1),
DCOD(
SEP, 0, 1),
DCOD(
OCT, 0, 1),
203 0,
DCOD( 0, 1, 1),
DCOD(
JAN, 1, 1),
DCOD(
FEB, 1, 1),
204 DCOD(
MAR, 1, 1),
DCOD(
APR, 1, 1),
DCOD(
MAY, 1, 1),
DCOD(
JUN, 1, 1),
205 DCOD(
JUL, 1, 1),
DCOD(
AUG, 1, 1),
DCOD(
SEP, 1, 1),
DCOD(
OCT, 1, 1),
207 0,
DCOD( 0, 2, 1),
DCOD(
JAN, 2, 1),
DCOD(
FEB, 2, 1),
208 DCOD(
MAR, 2, 1),
DCOD(
APR, 2, 1),
DCOD(
MAY, 2, 1),
DCOD(
JUN, 2, 1),
209 DCOD(
JUL, 2, 1),
DCOD(
AUG, 2, 1),
DCOD(
SEP, 2, 1),
DCOD(
OCT, 2, 1),
211 0,
DCOD( 0, 3, 1),
DCOD(
JAN, 3, 1),
DCOD(
FEB, 3, 1),
212 DCOD(
MAR, 3, 1),
DCOD(
APR, 3, 1),
DCOD(
MAY, 3, 1),
DCOD(
JUN, 3, 1),
213 DCOD(
JUL, 3, 1),
DCOD(
AUG, 3, 1),
DCOD(
SEP, 3, 1),
DCOD(
OCT, 3, 1),
223 tsp->tv_sec = (dt & 0x1f) << 1;
224 tsp->tv_sec += ((dt & 0x7e0) >> 5) * 60;
225 tsp->tv_sec += ((dt & 0xf800) >> 11) * 3600;
226 tsp->tv_sec += dh / 100;
227 tsp->tv_nsec = (dh % 100) * 10000000;
230 day = (dd & 0x1f) - 1;
233 day +=
LYC * ((dd >> 11) & 0x1f);
236 day +=
daytab[(dd >> 5) & 0x3f];
242 if (day >= ((2100 - 1980) / 4 *
LYC +
FEB))
248 tsp->tv_sec +=
DAY * day;
260 main(
int argc __unused,
char **
argv __unused)
270 for (i = 0; i < 10000; i++) {
272 ts.tv_sec = random();
273 }
while (
ts.tv_sec <
T1980 * 86400);
274 ts.tv_nsec = random() % 1000000000;
276 printf(
"%10d.%03ld -- ",
ts.tv_sec,
ts.tv_nsec / 1000000);
278 gmtime_r(&
ts.tv_sec, &tm);
279 strftime(buf,
sizeof buf,
"%Y %m %d %H %M %S", &tm);
282 a =
ts.tv_sec +
ts.tv_nsec * 1e-9;
284 timet2fattime(&
ts, &d, &t, &p);
285 printf(
"%04x %04x %02x -- ", d, t, p);
286 printf(
"%3d %02d %02d %02d %02d %02d -- ",
287 ((d >> 9) & 0x7f) + 1980,
292 ((t >> 0) & 0x1f) * 2);
294 ts.tv_sec =
ts.tv_nsec = 0;
295 fattime2timet(d, t, p, &
ts);
296 printf(
"%10d.%03ld == ",
ts.tv_sec,
ts.tv_nsec / 1000000);
297 gmtime_r(&
ts.tv_sec, &tm);
298 strftime(buf,
sizeof buf,
"%Y %m %d %H %M %S", &tm);
300 a -=
ts.tv_sec +
ts.tv_nsec * 1e-9;
static const uint16_t daytab[64]
void timespec2fattime(struct timespec *tsp, int utc, uint16_t *ddp, uint16_t *dtp, uint8_t *dhp)
int printf(const char *fmt,...)
static const struct @10 mtab[48]
void fattime2timespec(unsigned dd, unsigned dt, unsigned dh, int utc, struct timespec *tsp)