Loading src/common/util.c +28 −11 Original line number Diff line number Diff line Loading @@ -112,19 +112,36 @@ void tv_addms(struct timeval *a, long ms) { a->tv_usec %= 1000000; } #define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400))) static int n_leapdays(int y1, int y2) { --y1; --y2; return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400); } static const int days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; time_t tor_timegm (struct tm *tm) { /* This is a pretty ironclad timegm implementation, snarfed from Python2.2. * It's way more brute-force than fiddling with tzset(). */ time_t ret; char *tz; tz = getenv("TZ"); setenv("TZ", "", 1); tzset(); ret = mktime(tm); if (tz) setenv("TZ", tz, 1); else unsetenv("TZ"); tzset(); unsigned long year, days, hours, minutes; int i; year = tm->tm_year + 1900; assert(year >= 1970); assert(tm->tm_mon >= 0 && tm->tm_mon <= 11); days = 365 * (year-1970) + n_leapdays(1970,year); for (i = 0; i < tm->tm_mon; ++i) days += days_per_month[i]; if (tm->tm_mon > 1 && IS_LEAPYEAR(year)) ++days; days += tm->tm_mday - 1; hours = days*24 + tm->tm_hour; minutes = hours*60 + tm->tm_min; ret = minutes*60 + tm->tm_sec; return ret; } Loading src/or/test.c +15 −0 Original line number Diff line number Diff line Loading @@ -422,6 +422,7 @@ test_crypto() void test_util() { struct timeval start, end; struct tm a_time; start.tv_sec = 5; start.tv_usec = 5000; Loading @@ -447,6 +448,20 @@ test_util() { test_eq(0L, tv_udiff(&start, &end)); /* The test values here are confirmed to be correct on a platform * with a working timgm. */ a_time.tm_year = 2003-1900; a_time.tm_mon = 7; a_time.tm_mday = 30; a_time.tm_hour = 6; a_time.tm_min = 14; a_time.tm_sec = 55; test_eq((time_t) 1062224095UL, tor_timegm(&a_time)); a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */ test_eq((time_t) 1093846495UL, tor_timegm(&a_time)); a_time.tm_mon = 1; /* Try a leap year, in feb. */ a_time.tm_mday = 10; test_eq((time_t) 1076393695UL, tor_timegm(&a_time)); } void Loading Loading
src/common/util.c +28 −11 Original line number Diff line number Diff line Loading @@ -112,19 +112,36 @@ void tv_addms(struct timeval *a, long ms) { a->tv_usec %= 1000000; } #define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400))) static int n_leapdays(int y1, int y2) { --y1; --y2; return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400); } static const int days_per_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; time_t tor_timegm (struct tm *tm) { /* This is a pretty ironclad timegm implementation, snarfed from Python2.2. * It's way more brute-force than fiddling with tzset(). */ time_t ret; char *tz; tz = getenv("TZ"); setenv("TZ", "", 1); tzset(); ret = mktime(tm); if (tz) setenv("TZ", tz, 1); else unsetenv("TZ"); tzset(); unsigned long year, days, hours, minutes; int i; year = tm->tm_year + 1900; assert(year >= 1970); assert(tm->tm_mon >= 0 && tm->tm_mon <= 11); days = 365 * (year-1970) + n_leapdays(1970,year); for (i = 0; i < tm->tm_mon; ++i) days += days_per_month[i]; if (tm->tm_mon > 1 && IS_LEAPYEAR(year)) ++days; days += tm->tm_mday - 1; hours = days*24 + tm->tm_hour; minutes = hours*60 + tm->tm_min; ret = minutes*60 + tm->tm_sec; return ret; } Loading
src/or/test.c +15 −0 Original line number Diff line number Diff line Loading @@ -422,6 +422,7 @@ test_crypto() void test_util() { struct timeval start, end; struct tm a_time; start.tv_sec = 5; start.tv_usec = 5000; Loading @@ -447,6 +448,20 @@ test_util() { test_eq(0L, tv_udiff(&start, &end)); /* The test values here are confirmed to be correct on a platform * with a working timgm. */ a_time.tm_year = 2003-1900; a_time.tm_mon = 7; a_time.tm_mday = 30; a_time.tm_hour = 6; a_time.tm_min = 14; a_time.tm_sec = 55; test_eq((time_t) 1062224095UL, tor_timegm(&a_time)); a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */ test_eq((time_t) 1093846495UL, tor_timegm(&a_time)); a_time.tm_mon = 1; /* Try a leap year, in feb. */ a_time.tm_mday = 10; test_eq((time_t) 1076393695UL, tor_timegm(&a_time)); } void Loading