back out to previous version
This commit is contained in:
+121
-9
@@ -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 (¤t, &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)
|
||||
//
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user