diff options
author | Nick Mathewson <nickm@torproject.org> | 2003-11-10 06:28:53 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2003-11-10 06:28:53 +0000 |
commit | 3c4b4c8cac706ba17d33929ddcc0b0a306adc6b8 (patch) | |
tree | c6b1e2b400b464ffa5199bb2f3621d894442739e /src/common/util.c | |
parent | 3dddcf4306df2ecd364f9c45b576d709181bff7b (diff) | |
download | tor-3c4b4c8cac706ba17d33929ddcc0b0a306adc6b8.tar.gz tor-3c4b4c8cac706ba17d33929ddcc0b0a306adc6b8.zip |
Check in a working cross-platform timegm
svn:r779
Diffstat (limited to 'src/common/util.c')
-rw-r--r-- | src/common/util.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/src/common/util.c b/src/common/util.c index 525f27b88e..c81d0fe876 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -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; } |