back out to previous version

This commit is contained in:
Marty Kraimer
2000-06-20 21:12:45 +00:00
parent 7834744bb2
commit 7323486b9e
2 changed files with 162 additions and 9 deletions
+121 -9
View File
@@ -50,9 +50,10 @@ const unsigned osiTime::nSecPerSec = 1000u*osiTime::uSecPerSec;
const unsigned osiTime::nSecPerUSec = 1000u;
const unsigned osiTime::secPerMin = 60u;
//Following is (SEC_IN_YEAR*20)+(5*SEC_IN_DAY)
// 5 is leap years from 1970 to 1990
static const double posixEpochToEpicsEpoch = 631152000.0;
static const unsigned ntpEpochYear = 1900;
static const unsigned ntpEpocMonth = 0; // January
static const unsigned ntpEpocDayOfTheMonth = 1; // the 1st day of the month
static const double ULONG_MAX_PLUS_ONE = (static_cast<double>(ULONG_MAX) + 1.0);
//
// force this module to include code that can convert
@@ -67,6 +68,10 @@ public:
static const unsigned tmStructEpochYear = 1900;
static const unsigned epicsEpochYear = 1990;
static const unsigned epicsEpocMonth = 0; // January
static const unsigned epicsEpocDayOfTheMonth = 1; // the 1st day of the month
//
// forward declarations for utility routines
//
@@ -87,7 +92,12 @@ inline osiTime::osiTime (const unsigned long secIn, const unsigned long nSecIn)
class osiTimeLoadTimeInit {
public:
osiTimeLoadTimeInit ();
double time_tSecPerTick; // seconds ( EPICS uses int sec)
double epicsEpochOffset; // seconds
#ifdef NTP_SUPPORT
double ntpEpochOffset; // seconds
#endif
double time_tSecPerTick; // seconds (both NTP and EPICS use int sec)
};
static const osiTimeLoadTimeInit lti;
@@ -97,9 +107,63 @@ static const osiTimeLoadTimeInit lti;
//
osiTimeLoadTimeInit::osiTimeLoadTimeInit ()
{
time_t first = static_cast<time_t> (0);
time_t last = static_cast<time_t> (1);
this->time_tSecPerTick = difftime (last, first);
static const time_t ansiEpoch = 0;
double secWest;
{
time_t current = time (NULL);
time_t error;
tm date;
gmtime_r (&current, &date);
error = mktime (&date);
assert (error!=(time_t)-1);
secWest = difftime (error, current);
}
{
time_t first = static_cast<time_t> (0);
time_t last = static_cast<time_t> (1);
this->time_tSecPerTick = difftime (last, first);
}
{
struct tm tmEpicsEpoch;
time_t epicsEpoch;
tmEpicsEpoch.tm_sec = 0;
tmEpicsEpoch.tm_min = 0;
tmEpicsEpoch.tm_hour = 0;
tmEpicsEpoch.tm_mday = epicsEpocDayOfTheMonth;
tmEpicsEpoch.tm_mon = epicsEpocMonth;
tmEpicsEpoch.tm_year = epicsEpochYear-tmStructEpochYear;
tmEpicsEpoch.tm_isdst = -1; // dont know if its daylight savings time
epicsEpoch = mktime (&tmEpicsEpoch);
assert (epicsEpoch!=(time_t)-1);
this->epicsEpochOffset = difftime (epicsEpoch, ansiEpoch) - secWest;
}
#ifdef NTP_SUPPORT
/* unfortunately, on NT mktime cant calculate a time_t for a date before 1970 */
{
struct tm tmEpochNTP;
time_t ntpEpoch;
tmEpochNTP.tm_sec = 0;
tmEpochNTP.tm_min = 0;
tmEpochNTP.tm_hour = 0;
tmEpochNTP.tm_mday = ntpEpocDayOfTheMonth;
tmEpochNTP.tm_mon = ntpEpocMonth;
tmEpochNTP.tm_year = ntpEpochYear-tmStructEpochYear;
tmEpochNTP.tm_isdst = -1; // dont know if its daylight savings time
ntpEpoch = mktime (&tmEpochNTP);
assert (ntpEpoch!=(time_t)-1);
this->ntpEpochOffset = static_cast<long> (difftime (ansiEpoch, ntpEpoch) + this->epicsEpochOffset - secWest);
}
#endif
}
//
@@ -124,7 +188,7 @@ osiTime::osiTime (const time_t_wrapper &ansiTimeTicks)
//
// map time_t, which ansi C defines as some arithmetic type, into type double
//
sec = ansiTimeTicks.ts * lti.time_tSecPerTick - posixEpochToEpicsEpoch;
sec = ansiTimeTicks.ts * lti.time_tSecPerTick - lti.epicsEpochOffset;
//
// map into the the EPICS time stamp range (which allows rollover)
@@ -151,7 +215,7 @@ osiTime::operator time_t_wrapper () const
double tmp;
time_t_wrapper wrap;
tmp = (this->secPastEpoch + posixEpochToEpicsEpoch) / lti.time_tSecPerTick;
tmp = (this->secPastEpoch + lti.epicsEpochOffset) / lti.time_tSecPerTick;
tmp += (this->nSec / lti.time_tSecPerTick) / nSecPerSec;
//
@@ -179,6 +243,7 @@ osiTime::operator tm_nano_sec () const
// succes?
//
localtime_r (&ansiTimeTicks.ts, &tm.ansi_tm);
tm.nSec = this->nSec;
return tm;
@@ -286,6 +351,53 @@ osiTime::osiTime (const aitTimeStamp &ts)
*this = osiTime (this->secPastEpoch+secAdj, this->nSec+nSecAdj);
}
//
// osiTime::ntpTimeStamp ()
//
#ifdef NTP_SUPPORT
osiTime::operator ntpTimeStamp () const
{
ntpTimeStamp ts;
if (lti.ntpEpochOffset>=0) {
unsigned long offset = static_cast<unsigned long> (lti.ntpEpochOffset);
// underflow expected
ts.l_ui = this->secPastEpoch - offset;
}
else {
unsigned long offset = static_cast<unsigned long> (-lti.ntpEpochOffset);
// overflow expected
ts.l_ui = this->secPastEpoch + offset;
}
ts.l_uf = static_cast<unsigned long> ( ( this->nSec * ULONG_MAX_PLUS_ONE ) / nSecPerSec );
return ts;
}
#endif
//
// osiTime::osiTime (const ntpTimeStamp &ts)
//
#ifdef NTP_SUPPORT
osiTime::osiTime (const ntpTimeStamp &ts)
{
if (lti.ntpEpochOffset>=0) {
unsigned long offset = static_cast<unsigned long> (lti.ntpEpochOffset);
// overflow expected
this->secPastEpoch = ts.l_ui + this->secPastEpoch + offset;
}
else {
unsigned long offset = static_cast<unsigned long> (-lti.ntpEpochOffset);
// underflow expected
this->secPastEpoch = ts.l_ui + this->secPastEpoch - offset;
}
this->nSec = static_cast<unsigned long> ( ( ts.l_uf / ULONG_MAX_PLUS_ONE ) * nSecPerSec );
}
#endif
//
// size_t osiTime::strftime (char *pBuff, size_t bufLength, const char *pFormat)
//
+41
View File
@@ -65,6 +65,33 @@ struct time_t_wrapper {
time_t ts;
};
//
// This comment is from the NTP header files:
//
// NTP uses two fixed point formats. The first (l_fp) is the "long"
// format and is 64 bits long with the decimal between bits 31 and 32.
// This is used for time stamps in the NTP packet header (in network
// byte order) and for internal computations of offsets (in local host
// byte order). We use the same structure for both signed and unsigned
// values, which is a big hack but saves rewriting all the operators
// twice. Just to confuse this, we also sometimes just carry the
// fractional part in calculations, in both signed and unsigned forms.
// Anyway, an l_fp looks like:
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Integral Part |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Fractional Part |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//
struct ntpTimeStamp {
epicsUInt32 l_ui; /* sec past NTP epoch */
epicsUInt32 l_uf; /* fractional seconds */
};
class osiTime;
//
@@ -146,6 +173,13 @@ public:
osiTime (const struct timeval &ts);
osiTime operator = (const struct timeval &rhs);
//
// convert to and from NTP timestamp format
//
operator ntpTimeStamp () const;
osiTime (const ntpTimeStamp &ts);
osiTime operator = (const ntpTimeStamp &rhs);
//
// convert to and from GDD's aitTimeStamp format
//
@@ -329,6 +363,13 @@ inline osiTime::operator TS_STAMP () const
return ts;
}
#ifdef NTP_SUPPORT
inline osiTime osiTime::operator = (const ntpTimeStamp &rhs)
{
*this = osiTime (rhs);
return *this;
}
#endif
inline osiTime osiTime::operator = (const time_t_wrapper &rhs)
{