Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -459,10 +459,24 @@ AC_DEFINE(HAVE_GMTIME_R, 1, [Whether we have gmtime_r]) ]) AC_CHECK_FUNC(localtime_r, [ AC_DEFINE(HAVE_LOCALTIME_R, 1, [Whether we have localtime_r]) ]) + +AC_MSG_CHECKING(for tm_gmtoff in struct tm) +AC_TRY_COMPILE([ + #define _GNU_SOURCE + #include +], [ + struct tm tm; + tm.tm_gmtoff = 0; +], [ + AC_DEFINE(STRUCT_TM_HAS_TM_GMTOFF, 1, [Whether struct tm has tm_gmtoff]) + AC_MSG_RESULT(yes) +], [ + AC_MSG_RESULT(no) +]) AC_CHECK_FUNC(kqueue, [ AC_DEFINE(HAVE_KQUEUE, 1, [Whether we have kqueue]) AC_SUBST(OFSTREAMOBSERVER_KQUEUE_M, "OFStreamObserver_kqueue.m") ]) Index: src/OFDate.m ================================================================== --- src/OFDate.m +++ src/OFDate.m @@ -131,10 +131,25 @@ @throw [OFOutOfRangeException exceptionWithClass: isa]; \ \ return tm->field; # endif #endif + +static int month_to_day_of_year[12] = { + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 +}; @implementation OFDate #if (!defined(HAVE_GMTIME_R) || !defined(HAVE_LOCALTIME_R)) && \ defined(OF_THREADS) + (void)initialize @@ -232,19 +247,33 @@ if (strptime([string UTF8String], [format UTF8String], &tm) == NULL) @throw [OFInvalidFormatException exceptionWithClass: isa]; - if (tm.tm_gmtoff) +#ifdef STRUCT_TM_HAS_TM_GMTOFF + if (tm.tm_gmtoff != 0) @throw [OFInvalidFormatException exceptionWithClass: isa]; +#endif - if ((seconds = mktime(&tm)) == -1) + /* Years */ + seconds = (tm.tm_year - 70) * 31536000; + /* Leap years */ + seconds += ((tm.tm_year / 4) - 17) * 86400; + /* Months */ + if (tm.tm_mon < 0 || tm.tm_mon > 12) @throw [OFInvalidFormatException exceptionWithClass: isa]; - - seconds += tm.tm_gmtoff; + seconds += month_to_day_of_year[tm.tm_mon - 1] * 86400; + /* Days */ + seconds += (tm.tm_mday - 1) * 86400; + /* Hours */ + seconds += tm.tm_hour * 3600; + /* Minutes */ + seconds += tm.tm_min * 60; + /* Seconds */ + seconds += tm.tm_sec; } @catch (id e) { [self release]; @throw e; }