libCom/osi: add full epicsTime conversion from/to UTC struct tm (without timezone mechanism)

This commit is contained in:
Ralph Lange
2016-10-04 16:16:42 +02:00
parent c2b17feaf1
commit 3702401171
2 changed files with 96 additions and 6 deletions
+85 -4
View File
@@ -287,11 +287,80 @@ epicsTime::epicsTime (const local_tm_nano_sec &tm)
throwWithLocation ( formatProblemWithStructTM () );
}
// Do the epoch conversion
*this = epicsTime (ansiTimeTicks);
// Add the nSec part
*this = epicsTime (this->secPastEpoch, tm.nSec);
}
unsigned long nSecAdj = tm.nSec % nSecPerSec;
unsigned long secAdj = tm.nSec / nSecPerSec;
*this = epicsTime ( this->secPastEpoch+secAdj, this->nSec+nSecAdj );
//
// epicsTime (const gm_tm_nano_sec &tm)
//
// do conversion avoiding the timezone mechanism
static inline epicsInt32 is_leap(epicsInt32 year)
{
if (year % 400 == 0)
return 1;
if (year % 100 == 0)
return 0;
if (year % 4 == 0)
return 1;
return 0;
}
static inline epicsInt32 days_from_0(epicsInt32 year)
{
year--;
return 365 * year + (year / 400) - (year / 100) + (year / 4);
}
static inline epicsInt32 days_from_1970(epicsInt32 year)
{
static const int days_from_0_to_1970 = days_from_0(1970);
return days_from_0(year) - days_from_0_to_1970;
}
static inline epicsInt32 days_from_1jan(epicsInt32 year,
epicsInt32 month,
epicsInt32 day)
{
static const epicsInt32 days[2][12] =
{
{ 0,31,59,90,120,151,181,212,243,273,304,334},
{ 0,31,60,91,121,152,182,213,244,274,305,335}
};
return days[is_leap(year)][month-1] + day - 1;
}
epicsTime::epicsTime (const gm_tm_nano_sec &tm)
{
time_t_wrapper ansiTimeTicks;
int year = tm.ansi_tm.tm_year + 1900;
int month = tm.ansi_tm.tm_mon;
if (month > 11) {
year += month / 12;
month %= 12;
} else if (month < 0) {
int years_diff = (-month + 11) / 12;
year -= years_diff;
month += 12 * years_diff;
}
month++;
int day = tm.ansi_tm.tm_mday;
int day_of_year = days_from_1jan(year, month, day);
int days_since_epoch = days_from_1970(year) + day_of_year;
const time_t seconds_in_day = 3600 * 24;
ansiTimeTicks.ts = seconds_in_day * days_since_epoch
+ 3600 * tm.ansi_tm.tm_hour
+ 60 * tm.ansi_tm.tm_min
+ tm.ansi_tm.tm_sec;
// Do the epoch conversion
*this = epicsTime (ansiTimeTicks);
// Add the nSec part
*this = epicsTime (this->secPastEpoch, tm.nSec);
}
//
@@ -905,6 +974,19 @@ extern "C" {
}
return epicsTimeOK;
}
epicsShareFunc int epicsShareAPI epicsTimeFromGMTM (epicsTimeStamp *pDest, const struct tm *pSrc, unsigned long nSecSrc)
{
try {
gm_tm_nano_sec tmns;
tmns.ansi_tm = *pSrc;
tmns.nSec = nSecSrc;
*pDest = epicsTime (tmns);
}
catch (...) {
return epicsTimeERROR;
}
return epicsTimeOK;
}
epicsShareFunc int epicsShareAPI epicsTimeToTimespec (struct timespec *pDest, const epicsTimeStamp *pSrc)
{
try {
@@ -1036,4 +1118,3 @@ extern "C" {
}
}
}
+11 -2
View File
@@ -105,10 +105,12 @@ public:
epicsTime & operator = ( const local_tm_nano_sec & );
/*
* convert to ANSI Cs "struct tm" (with nano seconds)
* convert to and from ANSI Cs "struct tm" (with nano seconds)
* adjusted for GM time (UTC)
*/
operator gm_tm_nano_sec () const;
epicsTime ( const gm_tm_nano_sec & );
epicsTime & operator = ( const gm_tm_nano_sec & );
/* convert to and from POSIX RTs "struct timespec" */
operator struct timespec () const;
@@ -194,13 +196,15 @@ epicsShareFunc int epicsShareAPI epicsTimeToTime_t (
epicsShareFunc int epicsShareAPI epicsTimeFromTime_t (
epicsTimeStamp * pDest, time_t src );
/*convert to and from ANSI C's "struct tm" with nano seconds */
/* 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 );
epicsShareFunc int epicsShareAPI epicsTimeFromGMTM (
epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc );
/* convert to and from POSIX RT's "struct timespec" */
epicsShareFunc int epicsShareAPI epicsTimeToTimespec (
@@ -312,6 +316,11 @@ inline epicsTime & epicsTime::operator = ( const local_tm_nano_sec & rhs )
return *this = epicsTime ( rhs );
}
inline epicsTime & epicsTime::operator = ( const gm_tm_nano_sec & rhs )
{
return *this = epicsTime ( rhs );
}
inline epicsTime & epicsTime::operator = ( const struct timespec & rhs )
{
*this = epicsTime ( rhs );