diff options
author | jerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68> | 2001-08-31 06:07:34 +0000 |
---|---|---|
committer | jerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68> | 2001-08-31 06:07:34 +0000 |
commit | 9b6e91a32b620d4bd876108c2b9b62cd665208d1 (patch) | |
tree | c330704a4276360187a314d552d7014ed9b103b8 /time/unix | |
parent | 38cc7a50e68f1b587f2ad0bb19578eeaf420c507 (diff) | |
download | libapr-9b6e91a32b620d4bd876108c2b9b62cd665208d1.tar.gz |
On platforms where neither HAVE_GMTOFF nor HAVE___OFFSET is defined,
like Solaris, the function "get_offset" in apr/time/unix/time.c is a
bottleneck in time formatting.
On these platforms, get_offset ignores its argument; it really computes
the server's offset from GMT, normalized so that it's independent of
daylight savings.
Here's a new version of the get_offset patch that initializes
the TZ offset from apr_initialize. I've attached the new include
file that it uses, apr/include/arch/unix/internal_time.h
--
Justin added the missing call to apr_initialize in testtime.c so that
testtime works on Solaris and produces the "right" output.
Submitted by: Brian Pane <bpane@pacbell.net>
Reviewed by: Justin Erenkrantz, Roy Fielding
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@62262 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'time/unix')
-rw-r--r-- | time/unix/time.c | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/time/unix/time.c b/time/unix/time.c index 5f46b5ff1..edaa1f893 100644 --- a/time/unix/time.c +++ b/time/unix/time.c @@ -70,6 +70,10 @@ #endif /* End System Headers */ +#if !defined(HAVE_GMTOFF) && !defined(HAVE___OFFSET) +static apr_int32_t server_gmt_offset; +#endif /* if !defined(HAVE_GMTOFF) && !defined(HAVE___OFFSET) */ + static apr_int32_t get_offset(struct tm *tm) { #ifdef HAVE_GMTOFF @@ -77,29 +81,7 @@ static apr_int32_t get_offset(struct tm *tm) #elif defined(HAVE___OFFSET) return tm->__tm_gmtoff; #else - /* We don't have an offset field to use, so calculate it. - mktime() is the inverse of localtime(); so, presumably, - passing in a struct tm made by gmtime() let's us calculate - the true GMT offset. However, there's a catch: if daylight - savings is in effect, gmtime()will set the tm_isdst field - and confuse mktime() into returning a time that's offset - by one hour. In that case, we must adjust the calculated GMT - offset. */ - { - time_t t1 = time(0), t2 = 0; - struct tm t; - int was_dst; - -#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) - gmtime_r(&t1, &t); -#else - t = *gmtime(&t1); -#endif - was_dst = (t.tm_isdst > 0); - t.tm_isdst = -1; - t2 = mktime(&t); - return (apr_int32_t) difftime(t1, t2) + (was_dst ? 3600 : 0); - } + return server_gmt_offset; #endif } @@ -308,3 +290,50 @@ APR_DECLARE(apr_status_t) apr_os2_time_to_apr_time(apr_time_t *result, FDATE os2 return APR_SUCCESS; } #endif + +APR_DECLARE(void) apr_unix_setup_time(void) +{ +#if !defined(HAVE_GMTOFF) && !defined(HAVE___OFFSET) + /* Precompute the offset from GMT on systems where it's not + in struct tm. + + Note: This offset is normalized to be independent of daylight + savings time; if the calculation happens to be done in a + time/place where a daylight savings adjustment is in effect, + the returned offset has the same value that it would have + in the same location if daylight savings were not in effect. + The reason for this is that the returned offset can be + applied to a past or future timestamp in explode_time(), + so the DST adjustment obtained from the current time won't + necessarily be applicable. + + mktime() is the inverse of localtime(); so, presumably, + passing in a struct tm made by gmtime() let's us calculate + the true GMT offset. However, there's a catch: if daylight + savings is in effect, gmtime()will set the tm_isdst field + and confuse mktime() into returning a time that's offset + by one hour. In that case, we must adjust the calculated GMT + offset. + + */ + + struct timeval now; + time_t t1, t2; + struct tm t; + int was_dst; + + gettimeofday(&now, NULL); + t1 = now.tv_sec; + t2 = 0; + +#if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + gmtime_r(&t1, &t); +#else + t = *gmtime(&t1); +#endif + was_dst = (t.tm_isdst > 0); + t.tm_isdst = -1; + t2 = mktime(&t); + server_gmt_offset = (apr_int32_t) difftime(t1, t2) + (was_dst ? 3600 : 0); +#endif +} |