From 2496284e20526fe06808829aa61888f17fe585cb Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Fri, 14 Dec 2001 00:54:28 +0000 Subject: [PATCH] 1) distinguish between struct tm in local timezone and a struct tm in UTC 2) added new osd routines to replace gmtime_t and localtime_t because the vxWorks interface does not follow posix RT --- src/libCom/osi/epicsTime.cpp | 90 +++++++++++++++++++++++------------- src/libCom/osi/epicsTime.h | 33 ++++++++++--- 2 files changed, 85 insertions(+), 38 deletions(-) diff --git a/src/libCom/osi/epicsTime.cpp b/src/libCom/osi/epicsTime.cpp index 3f321514f..924ba6dce 100644 --- a/src/libCom/osi/epicsTime.cpp +++ b/src/libCom/osi/epicsTime.cpp @@ -81,14 +81,15 @@ epicsTimeLoadTimeInit::epicsTimeLoadTimeInit () double secWest; { - time_t current = time (NULL); + time_t current = time ( NULL ); time_t error; tm date; - gmtime_r (¤t, &date); - error = mktime (&date); - assert (error!=(time_t)-1); - secWest = difftime (error, current); + int status = epicsTime_gmtime ( ¤t, &date ); + assert ( status == epicsTimeOK ); + error = mktime ( &date ); + assert ( error != (time_t) - 1 ); + secWest = difftime ( error, current ); } { @@ -197,22 +198,18 @@ epicsTime::operator time_t_wrapper () const } // -// convert to and from ANSI C struct tm (with nano seconds) +// convert to ANSI C struct tm (with nano seconds) adjusted for the local time zone // -epicsTime::operator tm_nano_sec () const +epicsTime::operator local_tm_nano_sec () const { - tm_nano_sec tm; - time_t_wrapper ansiTimeTicks; + time_t_wrapper ansiTimeTicks = *this; - ansiTimeTicks = *this; + local_tm_nano_sec tm; - // - // reentrant version of localtime() - from POSIX RT - // - // WRS returns int and others return &tm.ansi_tm on - // succes? - // - localtime_r (&ansiTimeTicks.ts, &tm.ansi_tm); + int status = epicsTime_localtime ( &ansiTimeTicks.ts, &tm.ansi_tm ); + if ( status != epicsTimeOK ) { + throw -1; + } tm.nSec = this->nSec; @@ -220,9 +217,28 @@ epicsTime::operator tm_nano_sec () const } // -// epicsTime (const tm_nano_sec &tm) +// convert to ANSI C struct tm (with nano seconds) adjusted for UTC // -epicsTime::epicsTime (const tm_nano_sec &tm) +epicsTime::operator gm_tm_nano_sec () const +{ + time_t_wrapper ansiTimeTicks = *this; + + gm_tm_nano_sec tm; + + int status = epicsTime_gmtime ( &ansiTimeTicks.ts, &tm.ansi_tm ); + if ( status != epicsTimeOK ) { + throw -1; + } + + tm.nSec = this->nSec; + + return tm; +} + +// +// epicsTime (const local_tm_nano_sec &tm) +// +epicsTime::epicsTime (const local_tm_nano_sec &tm) { static const time_t mktimeFailure = static_cast (-1); time_t_wrapper ansiTimeTicks; @@ -237,7 +253,7 @@ epicsTime::epicsTime (const tm_nano_sec &tm) unsigned long nSecAdj = tm.nSec % nSecPerSec; unsigned long secAdj = tm.nSec / nSecPerSec; - *this = epicsTime (this->secPastEpoch+secAdj, this->nSec+nSecAdj); + *this = epicsTime ( this->secPastEpoch+secAdj, this->nSec+nSecAdj ); } // @@ -433,7 +449,7 @@ size_t epicsTime::strftime ( char *pBuff, size_t bufLength, const char *pFormat if (fracPtr != NULL) *fracPtr = '\0'; // format all but fractional seconds - tm_nano_sec tmns = *this; + local_tm_nano_sec tmns = *this; size_t numChar = ::strftime (pBuff, bufLength, format, &tmns.ansi_tm); if (numChar == 0 || fracPtr == NULL) return numChar; @@ -704,10 +720,10 @@ extern "C" { } epicsShareFunc int epicsShareAPI epicsTimeFromTime_t (epicsTimeStamp *pDest, time_t src) { - time_t_wrapper dst; - dst.ts = src; try { - *pDest = epicsTime (dst); + time_t_wrapper dst; + dst.ts = src; + *pDest = epicsTime ( dst ); } catch (...) { return epicsTimeERROR; @@ -716,24 +732,34 @@ extern "C" { } epicsShareFunc int epicsShareAPI epicsTimeToTM (struct tm *pDest, unsigned long *pNSecDest, const epicsTimeStamp *pSrc) { - tm_nano_sec tmns; try { - tmns = epicsTime (*pSrc); + local_tm_nano_sec tmns = epicsTime (*pSrc); + *pDest = tmns.ansi_tm; + *pNSecDest = tmns.nSec; + } + catch (...) { + return epicsTimeERROR; + } + return epicsTimeOK; + } + epicsShareFunc int epicsShareAPI epicsTimeToGMTM (struct tm *pDest, unsigned long *pNSecDest, const epicsTimeStamp *pSrc) + { + try { + gm_tm_nano_sec gmtmns = epicsTime (*pSrc); + *pDest = gmtmns.ansi_tm; + *pNSecDest = gmtmns.nSec; } catch (...) { return epicsTimeERROR; } - *pDest = tmns.ansi_tm; - *pNSecDest = tmns.nSec; return epicsTimeOK; } epicsShareFunc int epicsShareAPI epicsTimeFromTM (epicsTimeStamp *pDest, const struct tm *pSrc, unsigned long nSecSrc) { - tm_nano_sec tmns; - tmns.ansi_tm = *pSrc; - tmns.nSec = nSecSrc; - try { + local_tm_nano_sec tmns; + tmns.ansi_tm = *pSrc; + tmns.nSec = nSecSrc; *pDest = epicsTime (tmns); } catch (...) { diff --git a/src/libCom/osi/epicsTime.h b/src/libCom/osi/epicsTime.h index 9dcb04306..c74db41c1 100644 --- a/src/libCom/osi/epicsTime.h +++ b/src/libCom/osi/epicsTime.h @@ -40,8 +40,17 @@ struct ntpTimeStamp { #ifdef __cplusplus class aitTimeStamp; /* GDD*/ -// extended ANSI C RTL "struct tm" which includes nano seconds within a second. -struct tm_nano_sec { + +// extend ANSI C RTL "struct tm" to include nano seconds within a second +// and a struct tm that is adjusted for the local timezone +struct local_tm_nano_sec { + struct tm ansi_tm; /* ANSI C time details */ + unsigned long nSec; /* nano seconds extension */ +}; + +// extend ANSI C RTL "struct tm" to includes nano seconds within a second +// and a struct tm that is adjusted for GMT (UTC) +struct gm_tm_nano_sec { struct tm ansi_tm; /* ANSI C time details */ unsigned long nSec; /* nano seconds extension */ }; @@ -88,9 +97,14 @@ public: epicsTime operator = (const time_t_wrapper &rhs); // convert to and from ANSI Cs "struct tm" (with nano seconds) - operator tm_nano_sec () const; - epicsTime (const tm_nano_sec &ts); - epicsTime operator = (const tm_nano_sec &rhs); + // adjusted for the local time zone + operator local_tm_nano_sec () const; + epicsTime (const local_tm_nano_sec &ts); + epicsTime operator = (const local_tm_nano_sec &rhs); + + // convert to ANSI Cs "struct tm" (with nano seconds) + // adjusted for GM time (UTC) + operator gm_tm_nano_sec () const; // convert to and from POSIX RTs "struct timespec" operator struct timespec () const; @@ -180,6 +194,8 @@ epicsShareFunc int epicsShareAPI epicsTimeFromTime_t ( /*convert to and from ANSI C's "struct tm" with nano seconds */ epicsShareFunc int epicsShareAPI epicsTimeToTM ( struct tm *pDest, unsigned long *pNSecDest, const epicsTimeStamp *pSrc); +epicsShareFunc int epicsShareAPI epicsTimeToGMTM ( + struct tm *pDest, unsigned long *pNSecDest, const epicsTimeStamp *pSrc); epicsShareFunc int epicsShareAPI epicsTimeFromTM ( epicsTimeStamp *pDest, const struct tm *pSrc, unsigned long nSecSrc); @@ -223,6 +239,11 @@ epicsShareFunc size_t epicsShareAPI epicsTimeToStrftime ( epicsShareFunc void epicsShareAPI epicsTimeShow ( const epicsTimeStamp *, unsigned interestLevel); +/* OS dependent reentrant versions of the ANSI C interface because */ +/* vxWorks gmtime_r interface does not match POSIX standards */ +int epicsTime_localtime ( const time_t *clock, struct tm *result ); +int epicsTime_gmtime ( const time_t *clock, struct tm *result ); + #ifdef __cplusplus } #endif /* __cplusplus */ @@ -309,7 +330,7 @@ inline bool epicsTime::operator > (const epicsTime &rhs) const return ! ( *this <= rhs ); } -inline epicsTime epicsTime::operator = (const tm_nano_sec &rhs) +inline epicsTime epicsTime::operator = (const local_tm_nano_sec &rhs) { return *this = epicsTime (rhs); }