diff options
author | Oliver Braun <obr@openoffice.org> | 2001-05-02 11:35:45 +0000 |
---|---|---|
committer | Oliver Braun <obr@openoffice.org> | 2001-05-02 11:35:45 +0000 |
commit | a07021f7f1076d7205f19a443c4f022146e4179a (patch) | |
tree | 4eba2f34769afa01c4b55c8f99f3e2d96373600a /sal/osl/unx/time.c | |
parent | 78a6e9db47f2cb08fe9d3c23655a85773f68515d (diff) |
fix daylight saving time detection and adjusted output of getGlobalTimer back to milliseconds
Diffstat (limited to 'sal/osl/unx/time.c')
-rw-r--r-- | sal/osl/unx/time.c | 177 |
1 files changed, 116 insertions, 61 deletions
diff --git a/sal/osl/unx/time.c b/sal/osl/unx/time.c index d5dfbba29f9b..f35dbe5f0a0b 100644 --- a/sal/osl/unx/time.c +++ b/sal/osl/unx/time.c @@ -2,9 +2,9 @@ * * $RCSfile: time.c,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: pluby $ $Date: 2001-03-11 02:13:08 $ + * last change: $Author: obr $ $Date: 2001-05-02 12:35:45 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -65,11 +65,48 @@ #include <osl/diagnose.h> #include <osl/time.h> +/* FIXME: detection should be done in configure script */ +#if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) +#define STRUCT_TM_HAS_GMTOFF 1 + +#elif defined(SOLARIS) +#define HAS_ALTZONE 1 +#define HAS_GMTIME_R 1 +#define HAS_LOCALTIME_R 1 + +#elif defined(LINUX) +#define STRUCT_TM_HAS_GMTOFF 1 +#define HAS_GMTIME_R 1 +#define HAS_LOCALTIME_R 1 +#endif + + +#if !defined(HAS_LOCALTIME_R) +struct tm *localtime_r(const time_t *clock, struct tm *res) +{ + // FIXME: copy buffer and make thread safe! + return localtime( clock ); +} +#endif + +#if !defined(HAS_GMTIME_R) +struct tm *gmtime_r(const time_t *clock, struct tm *res) +{ + // FIXME: copy buffer and make thread safe! + return gmtime( clock ); +} +#endif + + +/*-------------------------------------------------- + * osl_getSystemTime + *-------------------------------------------------*/ sal_Bool SAL_CALL osl_getSystemTime(TimeValue* TimeValue) { struct timeval tp; + /* FIXME: use higher resolution */ gettimeofday(&tp, NULL); TimeValue->Seconds = tp.tv_sec; @@ -85,13 +122,14 @@ sal_Bool SAL_CALL osl_getSystemTime(TimeValue* TimeValue) sal_Bool SAL_CALL osl_getDateTimeFromTimeValue( TimeValue* pTimeVal, oslDateTime* pDateTime ) { - struct tm *pSystemTime; - time_t atime; + struct tm *pSystemTime; + struct tm tmBuf; + time_t atime; atime = (time_t)pTimeVal->Seconds; /* Convert time from type time_t to struct tm */ - pSystemTime = gmtime( &atime ); + pSystemTime = gmtime_r( &atime, &tmBuf ); /* Convert struct tm to struct oslDateTime */ @@ -118,51 +156,63 @@ sal_Bool SAL_CALL osl_getDateTimeFromTimeValue( TimeValue* pTimeVal, oslDateTime sal_Bool SAL_CALL osl_getTimeValueFromDateTime( oslDateTime* pDateTime, TimeValue* pTimeVal ) { - struct tm aSystemTime; - time_t aSeconds; + struct tm aTime; + time_t nSeconds; /* Convert struct oslDateTime to struct tm */ - aSystemTime.tm_sec = pDateTime->Seconds; - aSystemTime.tm_min = pDateTime->Minutes; - aSystemTime.tm_hour = pDateTime->Hours; - aSystemTime.tm_mday = pDateTime->Day; - aSystemTime.tm_wday = pDateTime->DayOfWeek; - - if ( pDateTime->Month > 1) - aSystemTime.tm_mon = pDateTime->Month - 1; + aTime.tm_sec = pDateTime->Seconds; + aTime.tm_min = pDateTime->Minutes; + aTime.tm_hour = pDateTime->Hours; + aTime.tm_mday = pDateTime->Day; + aTime.tm_wday = pDateTime->DayOfWeek; + + if ( pDateTime->Month > 0 ) + aTime.tm_mon = pDateTime->Month - 1; else return sal_False; - if ( pDateTime->Year >= 1900) - aSystemTime.tm_year = pDateTime->Year - 1900; + if ( pDateTime->Year >= 1900 ) + aTime.tm_year = pDateTime->Year - 1900; else return sal_False; - aSystemTime.tm_isdst = 0; - aSystemTime.tm_wday = 0; - aSystemTime.tm_yday = 0; + aTime.tm_isdst = -1; + aTime.tm_wday = 0; + aTime.tm_yday = 0; /* Convert time to calendar value */ - aSeconds = mktime( &aSystemTime ); + nSeconds = mktime( &aTime ); - if (aSeconds != (time_t) -1) + /* + * mktime expects the struct tm to be in local timezone, so we have to adjust + * the returned value to be timezone neutral. + */ + + if ( nSeconds != (time_t) -1 ) { - tzset(); + time_t bias; /* timezone corrections */ -#if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) - if ( (sal_Int64) aSeconds > (aSystemTime.tm_gmtoff * -1) ) - aSeconds += aSystemTime.tm_gmtoff; + tzset(); + +#if defined(STRUCT_TM_HAS_GMTOFF) + /* members of struct tm are corrected by mktime */ + bias = 0 - aTime.tm_gmtoff; + +#elif defined(HAS_ALTZONE) + /* check if daylight saving time is in effect */ + bias = aTime.tm_isdst > 0 ? altzone : timezone; #else - if ( (sal_Int64) aSeconds > timezone ) - aSeconds -= timezone; + /* exspect daylight saving time to be one hour */ + bias = aTime.tm_isdst > 0 ? timezone - 3600 : timezone; #endif - else - return sal_False; - pTimeVal->Seconds = aSeconds; + pTimeVal->Seconds = nSeconds; pTimeVal->Nanosec = pDateTime->NanoSeconds; + if ( nSeconds > bias ) + pTimeVal->Seconds -= bias; + return sal_True; } @@ -176,23 +226,24 @@ sal_Bool SAL_CALL osl_getTimeValueFromDateTime( oslDateTime* pDateTime, TimeValu sal_Bool SAL_CALL osl_getLocalTimeFromSystemTime( TimeValue* pSystemTimeVal, TimeValue* pLocalTimeVal ) { - sal_Int64 bias; - struct tm *pLocalTime; - time_t atime; + struct tm *pLocalTime; + struct tm tmBuf; + time_t bias; + time_t atime; - atime = (time_t)pSystemTimeVal->Seconds; + atime = (time_t) pSystemTimeVal->Seconds; + pLocalTime = localtime_r( &atime, &tmBuf ); - tzset(); +#if defined(STRUCT_TM_HAS_GMTOFF) + /* members of struct tm are corrected by mktime */ + bias = 0 - pLocalTime->tm_gmtoff; - /* timezone an daylight saving time */ -#if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) - pLocalTime = localtime( &atime ); - bias = pLocalTime->tm_gmtoff * -1; +#elif defined(HAS_ALTZONE) + /* check if daylight saving time is in effect */ + bias = pLocalTime->tm_isdst > 0 ? altzone : timezone; #else - if ( daylight != 0) - bias = timezone - 3600; - else - bias = timezone; + /* exspect daylight saving time to be one hour */ + bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone; #endif if ( (sal_Int64) pSystemTimeVal->Seconds > bias ) @@ -212,33 +263,36 @@ sal_Bool SAL_CALL osl_getLocalTimeFromSystemTime( TimeValue* pSystemTimeVal, Tim sal_Bool SAL_CALL osl_getSystemTimeFromLocalTime( TimeValue* pLocalTimeVal, TimeValue* pSystemTimeVal ) { - sal_Int64 bias; - struct tm *pLocalTime; - time_t atime; + struct tm *pLocalTime; + struct tm tmBuf; + time_t bias; + time_t atime; - atime = (time_t)pLocalTimeVal->Seconds; + atime = (time_t) pLocalTimeVal->Seconds; - tzset(); - - /* timezone an daylight saving time */ -#if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) /* Convert atime, which is a local time, to it's GMT equivalent. Then, get * the timezone offset for the local time for the GMT equivalent time. Note * that we cannot directly use local time to determine the timezone offset * because GMT is the only reliable time that we can determine timezone * offset from. */ - atime = mktime( gmtime( &atime ) ); - pLocalTime = localtime( &atime ); - bias = pLocalTime->tm_gmtoff * -1; + + atime = mktime( gmtime_r( &atime, &tmBuf ) ); + pLocalTime = localtime_r( &atime, &tmBuf ); + +#if defined(STRUCT_TM_HAS_GMTOFF) + /* members of struct tm are corrected by mktime */ + bias = 0 - pLocalTime->tm_gmtoff; + +#elif defined(HAS_ALTZONE) + /* check if daylight saving time is in effect */ + bias = pLocalTime->tm_isdst > 0 ? altzone : timezone; #else - if ( daylight != 0) - bias = timezone - 3600; - else - bias = timezone; + /* exspect daylight saving time to be one hour */ + bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone; #endif - if ( (sal_Int64) pSystemTimeVal->Seconds + bias > 0) + if ( (sal_Int64) pSystemTimeVal->Seconds + bias > 0 ) { pSystemTimeVal->Seconds = pLocalTimeVal->Seconds + bias; pSystemTimeVal->Nanosec = pLocalTimeVal->Nanosec; @@ -259,6 +313,7 @@ sal_uInt32 SAL_CALL osl_getGlobalTimer() struct timeval currentTime; sal_uInt32 nSeconds; + // FIXME: not thread safe !! if ( bGlobalTimer == sal_False ) { gettimeofday( &startTime, NULL ); @@ -269,5 +324,5 @@ sal_uInt32 SAL_CALL osl_getGlobalTimer() nSeconds = (sal_uInt32)( currentTime.tv_sec - startTime.tv_sec ); - return ( nSeconds * 1000 ) + (long)( currentTime.tv_usec - startTime.tv_usec); + return ( nSeconds * 1000 ) + (long) (( currentTime.tv_usec - startTime.tv_usec) / 1000 ); } |