diff --git a/src/acconfig.h b/src/acconfig.h index 3e460635859a40f03e212eed599b29ce149e3c82..8a6820083d74c030ba510e19d6ac7faf08603341 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -407,6 +407,9 @@ /* define this if #include <time.h> provides an external int timezone */ #undef HAVE_EXTERNAL_TIMEZONE +/* define this if #include <time.h> provides an external int altzone */ +#undef HAVE_EXTERNAL_ALTZONE + /* define this if your struct tm has a tm_gmtoff */ #undef STRUCT_TM_HAS_GMTOFF diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 407148ccf8dd8fda072080a827ba2f2e0a11ff2f..36dee6100abc7d30d938428dd96d81931dafe0d2 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5855,12 +5855,29 @@ time_t mktime_zone(struct tm *date, int other_timezone, int tz) normalised_time += 24*60*60; else if (normalised_time > 12*60*60) normalised_time -= 24*60*60; + #ifdef STRUCT_TM_HAS___TM_GMTOFF retval += date->__tm_gmtoff; #elif defined(STRUCT_TM_HAS_GMTOFF) retval += date->tm_gmtoff; +#elif defined(HAVE_EXTERNAL_TIMEZONE) && defined(HAVE_EXTERNAL_ALTZONE) + if (date->tm_isdst) { + retval -= altzone; + } else { + retval -= timezone; + } #else - normalised_time = retval - mktime(gmtime(&retval)); + { + /* NB: The tm from gmtime(3F) will always have tm_isdst == 0, + * but mktime() is always in the local time zone, and will + * adjust it and tm_hour if the local time zone is in dst. + * This causes an error of typically one hour in dst when + * used without preadjustment. + */ + struct tm gmt_tm = *gmtime(&retval); + gmt_tm.tm_isdst = date->tm_isdst; + normalised_time += retval - mktime(&gmt_tm); + } #endif retval += normalised_time + tz; } diff --git a/src/configure.in b/src/configure.in index cbf3371317bcd115b274ff900256a2d4fe9b720a..fff642f389069e9eed2f00cad16f1733706cbd2d 100644 --- a/src/configure.in +++ b/src/configure.in @@ -5017,6 +5017,24 @@ fi AC_MSG_RESULT($pike_cv_has_external_timezone) +AC_MSG_CHECKING(extern int altzone) + +AC_CACHE_VAL(pike_cv_has_external_altzone,[ +AC_TRY_LINK([ +#include <time.h> +],[ + int _tz; + _tz=altzone; + altzone=_tz; +],pike_cv_has_external_altzone=yes,pike_cv_has_external_altzone=no) +]) + +if test "$pike_cv_has_external_altzone" = "yes"; then + AC_DEFINE(HAVE_EXTERNAL_ALTZONE) +fi + +AC_MSG_RESULT($pike_cv_has_external_altzone) + ############################################################################# # No test for this yet...