Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/subr_fattime.c
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
* Obviously we cannot calculate the correct table index going from | * Obviously we cannot calculate the correct table index going from | ||||
* a posix seconds count to Y/M/D, but we can get pretty close by | * a posix seconds count to Y/M/D, but we can get pretty close by | ||||
* dividing the daycount by 32 (giving a too low index), and then | * dividing the daycount by 32 (giving a too low index), and then | ||||
* adjusting upwards a couple of steps if necessary. | * adjusting upwards a couple of steps if necessary. | ||||
* | * | ||||
* FAT timestamps have 7 bits for the year and starts at 1980, so | * FAT timestamps have 7 bits for the year and starts at 1980, so | ||||
* they can represent up to 2107 which means that the non-leap-year | * they can represent up to 2107 which means that the non-leap-year | ||||
* 2100 must be handled. | * 2100 must be handled. | ||||
* | |||||
* XXX: As long as time_t is 32 bits this is not relevant or easily | |||||
* XXX: testable. Revisit when time_t grows bigger. | |||||
* XXX: grepfodder: 64 bit time_t, y2100, y2.1k, 2100, leap year | |||||
* | |||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <sys/clock.h> | #include <sys/clock.h> | ||||
#ifdef TEST_DRIVER | #ifdef TEST_DRIVER | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | timespec2fattime(const struct timespec *tsp, int utc, uint16_t *ddp, | ||||
if (ddp != NULL) { | if (ddp != NULL) { | ||||
t2 = t1 / DAY; | t2 = t1 / DAY; | ||||
if (t2 < T1980) { | if (t2 < T1980) { | ||||
/* Impossible date, truncate to 1980-01-01 */ | /* Impossible date, truncate to 1980-01-01 */ | ||||
*ddp = 0x0021; | *ddp = 0x0021; | ||||
} else { | } else { | ||||
t2 -= T1980; | t2 -= T1980; | ||||
/* | /* 2100 is not a leap year */ | ||||
* 2100 is not a leap year. | |||||
* XXX: a 32 bit time_t can not get us here. | |||||
*/ | |||||
if (t2 >= ((2100 - 1980) / 4 * LYC + FEB)) | if (t2 >= ((2100 - 1980) / 4 * LYC + FEB)) | ||||
t2++; | t2++; | ||||
/* Account for full leapyear cycles */ | /* Account for full leapyear cycles */ | ||||
l = t2 / LYC; | l = t2 / LYC; | ||||
*ddp = (l * 4) << 9; | *ddp = (l * 4) << 9; | ||||
t2 -= l * LYC; | t2 -= l * LYC; | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | fattime2timespec(unsigned dd, unsigned dt, unsigned dh, int utc, | ||||
day = (dd & 0x1f) - 1; | day = (dd & 0x1f) - 1; | ||||
/* Full leap-year cycles */ | /* Full leap-year cycles */ | ||||
day += LYC * ((dd >> 11) & 0x1f); | day += LYC * ((dd >> 11) & 0x1f); | ||||
/* Month offset from leap-year cycle */ | /* Month offset from leap-year cycle */ | ||||
day += daytab[(dd >> 5) & 0x3f]; | day += daytab[(dd >> 5) & 0x3f]; | ||||
/* | /* 2100 is not a leap year */ | ||||
* 2100 is not a leap year. | |||||
* XXX: a 32 bit time_t can not get us here. | |||||
*/ | |||||
if (day >= ((2100 - 1980) / 4 * LYC + FEB)) | if (day >= ((2100 - 1980) / 4 * LYC + FEB)) | ||||
day--; | day--; | ||||
/* Align with time_t epoch */ | /* Align with time_t epoch */ | ||||
day += T1980; | day += T1980; | ||||
tsp->tv_sec += DAY * day; | tsp->tv_sec += (time_t) DAY * day; | ||||
if (!utc) | if (!utc) | ||||
tsp->tv_sec += utc_offset(); | tsp->tv_sec += utc_offset(); | ||||
} | } | ||||
#ifdef TEST_DRIVER | #ifdef TEST_DRIVER | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |