LCOV - code coverage report
Current view: top level - INDI/libcommon - TimeStamp.cpp (source / functions) Coverage Total Hit
Test: MagAOX Lines: 9.9 % 332 33
Test Date: 2026-01-03 21:03:39 Functions: 21.3 % 47 10

            Line data    Source code
       1              : /// $Id: TimeStamp.cpp,v 1.5 2007/09/20 18:06:48 pgrenz Exp $
       2              : ///
       3              : /// @author Paul Grenz
       4              : ///
       5              : ////////////////////////////////////////////////////////////////////////////////
       6              : 
       7              : #include <sstream>
       8              : #include <iomanip>
       9              : #include <algorithm>
      10              : #include <limits>
      11              : #include <stdio.h>
      12              : #include <iostream>
      13              : 
      14              : #include "TimeStamp.hpp"
      15              : 
      16              : using std::string;
      17              : using std::ostream;
      18              : using std::stringstream;
      19              : using std::transform;
      20              : using std::setfill;
      21              : using std::setw;
      22              : using std::setprecision;
      23              : using pcf::TimeStamp;
      24              : 
      25              : ////////////////////////////////////////////////////////////////////////////////
      26              : /// Standard constructor - initialize the internal timeval struct.
      27              : 
      28         7551 : TimeStamp::TimeStamp()
      29              : {
      30         7551 :   m_tvCurr = TimeStamp::now().getTimeVal();
      31         7551 : }
      32              : 
      33              : ////////////////////////////////////////////////////////////////////////////////
      34              : /// Standard constructor from a timeval structure.
      35              : /// @param tvCurr A timeval struct which contains a valid time.
      36              : 
      37         7897 : TimeStamp::TimeStamp( const timeval &tvCurr )
      38              : {
      39         7897 :   m_tvCurr.tv_sec = tvCurr.tv_sec;
      40         7897 :   m_tvCurr.tv_usec = tvCurr.tv_usec;
      41         7897 : }
      42              : 
      43              : ////////////////////////////////////////////////////////////////////////////////
      44              : /// Standard constructor from a number of milliseconds. The amount is
      45              : /// considered to be an absolute value.
      46              : /// @param nMillis The number of milliseconds since the epoch UTC.
      47              : 
      48            0 : TimeStamp::TimeStamp( const int &nMillis )
      49              : {
      50            0 :   m_tvCurr.tv_sec = nMillis / 1000;
      51            0 :   m_tvCurr.tv_usec = ( nMillis % 1000 ) * 1000;
      52            0 : }
      53              : 
      54              : ////////////////////////////////////////////////////////////////////////////////
      55              : /// standard constructor from a year, month, day, hour (24), min, sec. The
      56              : /// time is considered to be in UTC, and no adjustment is done.
      57              : /// @param nYear The 4 digit year.
      58              : /// @param nMonth The month (between 1 and 12 inclusive).
      59              : /// @param nDay The day (between 1 and 31 inclusive).
      60              : /// @param nHour The hour (between 0 and 23 inclusive).
      61              : /// @param nMinute The minute (between 0 and 59 inclusive)
      62              : /// @param nSecond The second (between 0 and 60 inclusive).
      63              : 
      64            0 : TimeStamp::TimeStamp( const int &nYear, const int &nMonth, const int &nDay,
      65            0 :                       const int &nHour, const int &nMinute, const int &nSecond )
      66              : {
      67              :   // First get the current UTC. This will be modified to hold the
      68              :   // specified timestamp.
      69            0 :   ::time_t now = ::time( 0 );
      70            0 :   ::tm *gmtm = ::gmtime( &now );
      71              : 
      72              :   // Now fill in the rest of the struct with our desired values.
      73            0 :   gmtm->tm_sec = nSecond;
      74            0 :   gmtm->tm_min = nMinute;
      75            0 :   gmtm->tm_hour = nHour;
      76            0 :   gmtm->tm_mday = nDay;
      77            0 :   gmtm->tm_mon = nMonth - 1; // month is zero-based in tm struct.
      78            0 :   gmtm->tm_year = nYear - 1900; // 1900 is stored as 0 in tm struct.
      79              :   //gmtm->tm_wday;  /* day of week (Sunday = 0) */
      80              :   //gmtm->tm_yday;  /* day of year (0 - 365) */
      81              :   //gmtm->tm_isdst; /* is summer time in effect? */
      82              :   //gmtm->tm_zone;  /* abbreviation of timezone name */
      83              :   //gmtm->tm_gmtoff;  /* offset from UTC in seconds */
      84              : 
      85              :   // The object pointed by gmtm is modified, setting the tm_wday and tm_yday
      86              :   // to their appropiate values, and modifying the other members as necessary
      87              :   // to values within the normal range representing the specified time.
      88            0 :   m_tvCurr.tv_sec = local_timegm( gmtm );
      89            0 :   m_tvCurr.tv_usec = 0;
      90            0 : }
      91              : 
      92              : ////////////////////////////////////////////////////////////////////////////////
      93              : /// Standard destructor.
      94              : 
      95        15541 : TimeStamp::~TimeStamp()
      96              : {
      97              :   //  nothing to do.
      98        15541 : }
      99              : 
     100              : ////////////////////////////////////////////////////////////////////////////////
     101              : /// Returns the underlying timeval struct. This is the number of seconds since
     102              : /// January 1, 1970, UTC.
     103              : 
     104         7551 : const timeval &TimeStamp::getTimeVal() const
     105              : {
     106         7551 :   return m_tvCurr;
     107              : }
     108              : 
     109              : ////////////////////////////////////////////////////////////////////////////////
     110              : /// Returns the microsecond part of the time val struct.
     111              : 
     112              : /*int TimeStamp::getTimeValMicros() const
     113              : {
     114              :   return m_tvCurr.tv_usec;
     115              : }*/
     116              : 
     117              : ////////////////////////////////////////////////////////////////////////////////
     118              : /// Returns the seconds part of the time val struct.
     119              : 
     120              : /*int TimeStamp::getTimeValSecs() const
     121              : {
     122              :   return m_tvCurr.tv_sec;
     123              : }*/
     124              : 
     125              : ////////////////////////////////////////////////////////////////////////////////
     126              : /// Assignment operator. Assigns this object from another TimeStamp object.
     127              : /// @param tsRhs The TimeStamp object to use to reset this one.
     128              : 
     129          392 : const TimeStamp &TimeStamp::operator= ( const TimeStamp &tsRhs )
     130              : {
     131          392 :   if ( &tsRhs != this )
     132              :   {
     133          392 :     m_tvCurr = tsRhs.m_tvCurr;
     134              :   }
     135          392 :   return *this;
     136              : }
     137              : 
     138              : ////////////////////////////////////////////////////////////////////////////////
     139              : /// Assignment operator from a timeval. Sets the internal data from a timeval
     140              : /// struct
     141              : /// @param tv The timeval struct to use.
     142              : 
     143            0 : const TimeStamp &TimeStamp::operator= ( const timeval &tv  )
     144              : {
     145            0 :   m_tvCurr.tv_sec = tv.tv_sec;
     146            0 :   m_tvCurr.tv_usec = tv.tv_usec;
     147              : 
     148            0 :   return *this;
     149              : }
     150              : 
     151              : ////////////////////////////////////////////////////////////////////////////////
     152              : /// Assignment operator from a number of milliseconds. This is considered to be
     153              : /// an absolute value counted from the epoch, UTC.
     154              : /// @param nMillis The number of milliseconds that has elapsed since epoch, UTC.
     155              : 
     156            0 : const TimeStamp &TimeStamp::operator= ( const int &nMillis  )
     157              : {
     158            0 :   m_tvCurr.tv_sec = nMillis / 1000;
     159            0 :   m_tvCurr.tv_usec = ( nMillis % 1000 ) * 1000;
     160              : 
     161            0 :   return *this;
     162              : }
     163              : 
     164              : ////////////////////////////////////////////////////////////////////////////////
     165              : /// Subtraction operator. Subtracts two TimeStamps and returns the difference
     166              : /// as another TimeStamp. One must exercise caution, as the result is not an
     167              : /// absolute time, but rather a relative one.
     168              : /// @param tsRhs Another TimeStamp object.
     169              : /// @return The result: an absolute TimeStamp object.
     170              : 
     171           12 : TimeStamp TimeStamp::operator- ( const TimeStamp &tsRhs ) const
     172              : {
     173              :   //  subtracting two timeval structs is a little non-obvious.
     174              : 
     175              :   timeval tvDiff;
     176              : 
     177           12 :   tvDiff.tv_sec = m_tvCurr.tv_sec - tsRhs.m_tvCurr.tv_sec;
     178           12 :   tvDiff.tv_usec = m_tvCurr.tv_usec - tsRhs.m_tvCurr.tv_usec;
     179           12 :   if ( tvDiff.tv_usec < 0 )
     180              :   {
     181            0 :     tvDiff.tv_sec--;
     182            0 :     tvDiff.tv_usec += 1000000;
     183              :   }
     184              : 
     185           24 :   return TimeStamp( tvDiff );
     186              : }
     187              : 
     188              : ////////////////////////////////////////////////////////////////////////////////
     189              : /// Addition operator. Adds two TimeStamps and returns the sum
     190              : /// as another TimeStamp. One must exercise caution, as the second may not
     191              : /// be a meaningful value.
     192              : /// @param tsRhs Another TimeStamp object.
     193              : /// @return The result: an absolute TimeStamp object.
     194              : 
     195            0 : TimeStamp TimeStamp::operator+ ( const TimeStamp &tsRhs ) const
     196              : {
     197              :   //  adding two timeval structs is a little non-obvious.
     198              : 
     199              :   timeval tvSum;
     200            0 :   tvSum.tv_sec = m_tvCurr.tv_sec + tsRhs.m_tvCurr.tv_sec;
     201            0 :   int nnSum = m_tvCurr.tv_usec + tsRhs.m_tvCurr.tv_usec;
     202              : 
     203            0 :   if ( nnSum < 1000000 )
     204              :   {
     205            0 :     tvSum.tv_usec = nnSum;
     206              :   }
     207              :   else
     208              :   {
     209            0 :     tvSum.tv_sec++;
     210            0 :     tvSum.tv_usec = nnSum - 1000000;
     211              :   }
     212              : 
     213            0 :   return TimeStamp( tvSum );
     214              : }
     215              : 
     216              : ////////////////////////////////////////////////////////////////////////////////
     217              : /// Less than operator. Subtracts two TimeStamps and returns true if this
     218              : /// object is less than (further in the past) than tsRhs.
     219              : /// @param tsRhs Another TimeStamp object.
     220              : /// @return true or false.
     221              : 
     222            0 : bool TimeStamp::operator<( const TimeStamp &tsRhs ) const
     223              : {
     224            0 :   return ( ( getMicros() - tsRhs.getMicros() ) < 0 );
     225              : }
     226              : 
     227              : ////////////////////////////////////////////////////////////////////////////////
     228              : /// Less than or equal to operator. Subtracts two TimeStamps and returns
     229              : /// true if this object is less than (further in the past) or equal to than tsRhs.
     230              : /// @param tsRhs Another TimeStamp object.
     231              : /// @return true or false.
     232              : 
     233            0 : bool TimeStamp::operator<=( const TimeStamp &tsRhs ) const
     234              : {
     235            0 :   return ( ( getMicros() - tsRhs.getMicros() ) <= 0 );
     236              : }
     237              : 
     238              : ////////////////////////////////////////////////////////////////////////////////
     239              : /// Greater than operator. Subtracts two TimeStamps and returns true if this
     240              : /// object is greater than (more recent in the past) than tsRhs.
     241              : /// @param tsRhs Another TimeStamp object.
     242              : /// @return true or false.
     243              : 
     244            0 : bool TimeStamp::operator>( const TimeStamp &tsRhs ) const
     245              : {
     246            0 :   return ( ( getMicros() - tsRhs.getMicros() ) > 0 );
     247              : }
     248              : 
     249              : ////////////////////////////////////////////////////////////////////////////////
     250              : /// Greater than or equal to operator. Subtracts two TimeStamps and returns
     251              : /// true if this object is greater than (more recent in the past) or equal to
     252              : /// the tsRhs.
     253              : /// @param tsRhs Another TimeStamp object.
     254              : /// @return true or false.
     255              : 
     256            0 : bool TimeStamp::operator>=( const TimeStamp &tsRhs ) const
     257              : {
     258            0 :   return ( ( getMicros() - tsRhs.getMicros() ) >= 0 );
     259              : }
     260              : 
     261              : ////////////////////////////////////////////////////////////////////////////////
     262              : /// Copy constructor. Initialize this TimeStamp from another one.
     263              : /// @param ts Another TimeStamp to use to initialize this one.
     264              : 
     265           93 : TimeStamp::TimeStamp( const TimeStamp &ts )
     266              : {
     267           93 :   m_tvCurr = ts.m_tvCurr;
     268           93 : }
     269              : 
     270              : ////////////////////////////////////////////////////////////////////////////////
     271              : /// Equals operator. Returns true if the two TimeStamp objects are the same.
     272              : /// @param tsRhs Another TimeStamp object.
     273              : /// @return True if the two TimeStamps are the same, false otherwise.
     274              : 
     275            0 : bool TimeStamp::operator== ( const TimeStamp &tsRhs ) const
     276              : {
     277            0 :   return bool( m_tvCurr.tv_sec == tsRhs.m_tvCurr.tv_sec &&
     278            0 :                m_tvCurr.tv_usec == tsRhs.m_tvCurr.tv_usec );
     279              : }
     280              : 
     281              : ////////////////////////////////////////////////////////////////////////////////
     282              : /// returns the month number (1 to 12) given the 3-letter name.
     283              : /// The name should be one of: jan feb mar apr may jun jul aug sep oct nov dec.
     284              : /// Capitalization will be corrected. It defaults to -1 if it is unknown.
     285              : 
     286            0 : int TimeStamp::getMonthNumber( const std::string &szMonth )
     287              : {
     288            0 :   string szMonthLC = szMonth.substr( 0, 3 );
     289            0 :   transform( szMonthLC.begin(), szMonthLC.end(), szMonthLC.begin(),
     290              :              ( int( * )( int ) )tolower );
     291              : 
     292            0 :   if ( szMonthLC == "jan" )
     293            0 :     return 1;
     294            0 :   if ( szMonthLC == "feb" )
     295            0 :     return 2;
     296            0 :   if ( szMonthLC == "mar" )
     297            0 :     return 3;
     298            0 :   if ( szMonthLC == "apr" )
     299            0 :     return 4;
     300            0 :   if ( szMonthLC == "may" )
     301            0 :     return 5;
     302            0 :   if ( szMonthLC == "jun" )
     303            0 :     return 6;
     304            0 :   if ( szMonthLC == "jul" )
     305            0 :     return 7;
     306            0 :   if ( szMonthLC == "aug" )
     307            0 :     return 8;
     308            0 :   if ( szMonthLC == "sep" )
     309            0 :     return 9;
     310            0 :   if ( szMonthLC == "oct" )
     311            0 :     return 10;
     312            0 :   if ( szMonthLC == "nov" )
     313            0 :     return 11;
     314            0 :   if ( szMonthLC == "dec" )
     315            0 :     return 12;
     316              :   // default is unknown.
     317            0 :   return -1;
     318            0 : }
     319              : 
     320              : ////////////////////////////////////////////////////////////////////////////////
     321              : /// Returns the 3-letter weekday name given the number (1 to 7) of the weekday.
     322              : /// The name will be one of: Sun Mon Tue Wed Thu Fri Sat.
     323              : /// Capitalization will be corrected. It defaults to "???" if it is unknown.
     324              : 
     325            0 : string TimeStamp::getWeekdayName( const int &nWeekdayNum )
     326              : {
     327            0 :   switch ( nWeekdayNum )
     328              :   {
     329            0 :     case 1:
     330            0 :       return "Sun";
     331              :       break;
     332            0 :     case 2:
     333            0 :       return "Mon";
     334              :       break;
     335            0 :     case 3:
     336            0 :       return "Tue";
     337              :       break;
     338            0 :     case 4:
     339            0 :       return "Wed";
     340              :       break;
     341            0 :     case 5:
     342            0 :       return "Thu";
     343              :       break;
     344            0 :     case 6:
     345            0 :       return "Fri";
     346              :       break;
     347            0 :     case 7:
     348            0 :       return "Sat";
     349              :       break;
     350            0 :     default:
     351            0 :       return "???";
     352              :       break;
     353              :   }
     354              : }
     355              : 
     356              : ////////////////////////////////////////////////////////////////////////////////
     357              : /// Returns the 3-letter month name given the number (1 to 12) of the month.
     358              : /// The name will be one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec.
     359              : /// Capitalization will be corrected. It defaults to "???" if it is unknown.
     360              : 
     361            0 : string TimeStamp::getMonthName( const int &nMonthNum )
     362              : {
     363            0 :   switch ( nMonthNum )
     364              :   {
     365            0 :     case 1:
     366            0 :       return "Jan";
     367              :       break;
     368            0 :     case 2:
     369            0 :       return "Feb";
     370              :       break;
     371            0 :     case 3:
     372            0 :       return "Mar";
     373              :       break;
     374            0 :     case 4:
     375            0 :       return "Apr";
     376              :       break;
     377            0 :     case 5:
     378            0 :       return "May";
     379              :       break;
     380            0 :     case 6:
     381            0 :       return "Jun";
     382              :       break;
     383            0 :     case 7:
     384            0 :       return "Jul";
     385              :       break;
     386            0 :     case 8:
     387            0 :       return "Aug";
     388              :       break;
     389            0 :     case 9:
     390            0 :       return "Sep";
     391              :       break;
     392            0 :     case 10:
     393            0 :       return "Oct";
     394              :       break;
     395            0 :     case 11:
     396            0 :       return "Nov";
     397              :       break;
     398            0 :     case 12:
     399            0 :       return "Dec";
     400              :       break;
     401            0 :     default:
     402            0 :       return "???";
     403              :       break;
     404              :   }
     405              : }
     406              : 
     407              : ////////////////////////////////////////////////////////////////////////////////
     408              : /// Fetches the current time from the system. This can be used to initialize
     409              : /// an instance of this object: TimeStamp ts = TimeStamp::now();. It can
     410              : /// also be used when just the current itme is needed. UTC is assumed.
     411              : /// @return A TimeStamp object containing the current system time.
     412              : 
     413         7859 : TimeStamp TimeStamp::now()
     414              : {
     415              :   timeval tvCurr;
     416              : 
     417              : #ifdef WIN32
     418              :   FILETIME  ftNow;
     419              :   GetSystemTimeAsFileTime ( &ftNow );
     420              :   long long nnTime = ( long long ) ftNow.dwHighDateTime << 32;
     421              :   nnTime |= ftNow.dwLowDateTime;
     422              :   ///  convert from 100 nanosec to 1 usec.
     423              :   nnTime /= 10;
     424              :   ///  Number of microsec between the beginning of the Windows epoch
     425              :   ///  (1 Jan 1601) and the Unix epoch (1 Jan 1970).
     426              :   nnTime -= 11644473600000000ULL;
     427              :   tvCurr.tv_sec  = ( nnTime / 1000000ULL );
     428              :   tvCurr.tv_usec = ( nnTime % 1000000ULL );
     429              : #else
     430              :   /**
     431              :   The  gettimeofday()  function shall obtain the current time, expressed
     432              :   as seconds and microseconds since the  Epoch, UTC, and  store  it  in  the
     433              :   timeval structure pointed to by tp. The resolution of the system clock
     434              :   is unspecified. The gettimeofday() function shall return  0  and  no
     435              :   value  shall  be reserved to indicate an error.
     436              :   If tzp is not a null pointer, the behavior is unspecified.
     437              :   **/
     438         7859 :   ::gettimeofday( &tvCurr, NULL );
     439              : #endif
     440              : 
     441        15718 :   return TimeStamp( tvCurr );
     442              : }
     443              : 
     444              : ////////////////////////////////////////////////////////////////////////////////
     445              : /// Creates an iso-formatted time similar to: 193812 based on the currently
     446              : /// stored time.
     447              : /// @return the iso-formatted number.
     448              : 
     449            0 : string TimeStamp::getFormattedIsoTimeStr() const
     450              : {
     451            0 :   string szFormatted = "000000";
     452              : 
     453            0 :   time_t tNumSecs = getTimeValSecs();
     454            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     455              : 
     456              :   // transform date and time to broken-down time.
     457            0 :   if ( tmCurr != NULL )
     458              :   {
     459            0 :     stringstream ssFormatted;
     460              :     ssFormatted
     461            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_hour
     462            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_min
     463            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_sec;
     464            0 :     szFormatted = ssFormatted.str();
     465            0 :   }
     466              : 
     467            0 :   return szFormatted;
     468            0 : }
     469              : 
     470              : ////////////////////////////////////////////////////////////////////////////////
     471              : /// Generates the date and time formatted as "Sun Jun 24 19:38:12.234 2007".
     472              : /// @return A string formatted with the date and time information.
     473              : 
     474            0 : string TimeStamp::getFormattedStr() const
     475              : {
     476            0 :   string szFormatted = "??? ??? 00 00:00:00.000 0000";
     477              : 
     478            0 :   time_t tNumSecs = getTimeValSecs();
     479            0 :   int nNumMillis = getTimeValMicros() / 1000;
     480            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     481              : 
     482              :   // transform date and time to broken-down time.
     483            0 :   if ( tmCurr != NULL )
     484              :   {
     485            0 :     stringstream ssFormatted;
     486              :     ssFormatted
     487            0 :         << getWeekdayName( tmCurr->tm_wday + 1 )
     488              :         << " "
     489            0 :         << getMonthName( tmCurr->tm_mon + 1 )
     490              :         << " "
     491            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_mday
     492              :         << " "
     493            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_hour
     494              :         << ":"
     495            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_min
     496              :         << ":"
     497            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_sec
     498              :         << "."
     499            0 :         << setfill( '0' ) << setw( 3 ) << nNumMillis
     500              :         << " "
     501            0 :         << setfill( '0' ) << setw( 4 ) << 1900 + tmCurr->tm_year;
     502            0 :     szFormatted = ssFormatted.str();
     503            0 :   }
     504              : 
     505            0 :   return szFormatted;
     506            0 : }
     507              : 
     508              : ////////////////////////////////////////////////////////////////////////////////
     509              : /// Creates an iso-formatted date similar to:
     510              : /// YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.451Z)
     511              : /// Based on the current time.
     512              : /// @return the iso-formatted string.
     513              : 
     514            0 : string TimeStamp::getFormattedIso8601Str() const
     515              : {
     516            0 :   string szFormatted = "0000-00-00T00:00:00.000000Z";
     517              : 
     518              :   // It is a bit roundabout, but this is the simpliest way I have found
     519              :   // to convert a timeval to a tm.
     520            0 :   time_t tNumSecs = getTimeValSecs();
     521            0 :   int nNumMicros = getTimeValMicros();
     522            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     523              : 
     524              :   // transform date and time to broken-down time.
     525            0 :   if ( tmCurr != NULL )
     526              :   {
     527            0 :     stringstream ssFormatted;
     528              :     ssFormatted
     529            0 :         << setfill( '0' ) << setw( 4 ) << 1900 + tmCurr->tm_year
     530              :         << "-"
     531            0 :         << setfill( '0' ) << setw( 2 ) << 1 + tmCurr->tm_mon
     532              :         << "-"
     533            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_mday
     534              :         << "T"
     535            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_hour
     536              :         << ":"
     537            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_min
     538              :         << ":"
     539            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_sec
     540              :         << "."
     541            0 :         << setfill( '0' ) << setw( 6 ) << nNumMicros
     542            0 :         << "Z";
     543            0 :     szFormatted = ssFormatted.str();
     544            0 :   }
     545              : 
     546            0 :   return szFormatted;
     547            0 : }
     548              : 
     549              : ////////////////////////////////////////////////////////////////////////////////
     550              : /// Creates an iso-formatted date similar to: 20091230 based on the currently
     551              : /// stored time.
     552              : /// @return the iso-formatted number.
     553              : 
     554            0 : string TimeStamp::getFormattedIsoDateStr() const
     555              : {
     556            0 :   string szFormatted = "00000000";
     557              : 
     558            0 :   time_t tNumSecs = getTimeValSecs();
     559            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     560              : 
     561              :   // transform date and time to broken-down time.
     562            0 :   if ( tmCurr != NULL )
     563              :   {
     564            0 :     stringstream ssFormatted;
     565              :     ssFormatted
     566            0 :         << setfill( '0' ) << setw( 4 ) << 1900 + tmCurr->tm_year
     567            0 :         << setfill( '0' ) << setw( 2 ) << 1 + tmCurr->tm_mon
     568            0 :         << setfill( '0' ) << setw( 2 ) << tmCurr->tm_mday;
     569            0 :     szFormatted = ssFormatted.str();
     570            0 :   }
     571              : 
     572            0 :   return szFormatted;
     573            0 : }
     574              : 
     575              : ////////////////////////////////////////////////////////////////////////////////
     576              : /// Calculates the number of milliseconds that have elapsed since this object's
     577              : /// internal data was set and the time stamp ts.
     578              : /// @return The number of milliseconds that have elapsed since the object
     579              : /// was created or updated (see 'update').
     580              : 
     581           12 : double TimeStamp::elapsedMillis( const TimeStamp &ts ) const
     582              : {
     583           12 :   TimeStamp tsDiff = ts - *this;
     584           24 :   return tsDiff.getMillis();
     585           12 : }
     586              : 
     587              : ////////////////////////////////////////////////////////////////////////////////
     588              : /// Calculates the number of milliseconds that have elapsed since this object's
     589              : /// internal data was set and the time stamp ts. Resets the timestamp to
     590              : /// the current time if the interval has passsed.
     591              : /// @return The number of milliseconds that have elapsed since the object
     592              : /// was created or updated (see 'update').
     593              : 
     594            0 : bool TimeStamp::intervalElapsedMillis( const int iInterval )
     595              : {
     596            0 :   TimeStamp tsCurrent = TimeStamp::now();
     597            0 :   TimeStamp tsDiff = tsCurrent - *this;
     598            0 :   bool oIntervalElapsed = ( tsDiff.getMillis() >= iInterval );
     599            0 :   if ( oIntervalElapsed )
     600            0 :     *this = tsCurrent;
     601            0 :   return oIntervalElapsed;
     602            0 : }
     603              : 
     604              : ////////////////////////////////////////////////////////////////////////////////
     605              : /// Calculates the number of days that have elapsed since this object's
     606              : /// internal data was set and the time stamp ts.
     607              : /// @return The number of milliseconds that have elapsed since the object
     608              : /// was created or updated (see 'update').
     609              : 
     610            0 : double TimeStamp::elapsedDays( const TimeStamp &ts ) const
     611              : {
     612            0 :   TimeStamp tsDiff = ts - *this;
     613            0 :   return tsDiff.getDays();
     614            0 : }
     615              : 
     616              : ////////////////////////////////////////////////////////////////////////////////
     617              : /// Calculates the number of microseconds since epoch (1970 Jan 1), UTC.
     618              : /// @return The number of microseconds since the unix epoch.
     619              : 
     620            0 : double TimeStamp::getMicros() const
     621              : {
     622            0 :   return ( static_cast<double>( m_tvCurr.tv_sec ) * 1000000.0 )
     623            0 :          + ( static_cast<double>(  m_tvCurr.tv_usec ) );
     624              : }
     625              : 
     626              : ////////////////////////////////////////////////////////////////////////////////
     627              : /// Calculates the number of milliseconds since epoch (1970 Jan 1), UTC.
     628              : /// @return The number of milliseconds since the unix epoch.
     629              : 
     630           12 : double TimeStamp::getMillis() const
     631              : {
     632           12 :   return ( static_cast<double>( m_tvCurr.tv_sec ) * 1000.0 )
     633           12 :          + ( static_cast<double>(  m_tvCurr.tv_usec ) / 1000.0 );
     634              : }
     635              : 
     636              : ////////////////////////////////////////////////////////////////////////////////
     637              : /// Calculates the number of days since epoch (1970 Jan 1), UTC.
     638              : /// @return The number of days since the unix epoch.
     639              : 
     640            0 : double TimeStamp::getDays() const
     641              : {
     642              :   // There are 86400 seconds in one day.
     643            0 :   return ( static_cast<double>( m_tvCurr.tv_sec )
     644            0 :            + static_cast<double>(  m_tvCurr.tv_usec ) / 1000000.0 ) / 86400.0;
     645              : }
     646              : 
     647              : ////////////////////////////////////////////////////////////////////////////////
     648              : /// Generates the year (1900+) from the current time. If there is
     649              : /// an error, numeric_limits<unsigned int>::max() is returned.
     650              : 
     651            0 : unsigned int TimeStamp::getYear() const
     652              : {
     653            0 :   unsigned int uiYear = std::numeric_limits<unsigned int>::max();
     654              : 
     655            0 :   time_t tNumSecs = getTimeValSecs();
     656            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     657              : 
     658            0 :   if ( tmCurr != NULL )
     659              :   {
     660            0 :     uiYear = static_cast<unsigned int>( 1900 + tmCurr->tm_year );
     661              :   }
     662              : 
     663            0 :   return uiYear;
     664              : }
     665              : 
     666              : ////////////////////////////////////////////////////////////////////////////////
     667              : /// Generates the year's month number (1-12) from the current time. If there is
     668              : /// an error, std::numeric_limits<unsigned int>::max() is returned.
     669              : 
     670            0 : unsigned int TimeStamp::getYearMonth() const
     671              : {
     672            0 :   unsigned int uiMonth = std::numeric_limits<unsigned int>::max();
     673              : 
     674            0 :   time_t tNumSecs = getTimeValSecs();
     675            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     676              : 
     677            0 :   if ( tmCurr != NULL )
     678              :   {
     679            0 :     uiMonth = static_cast<unsigned int>( tmCurr->tm_mon + 1 );
     680              :   }
     681              : 
     682            0 :   return uiMonth;
     683              : }
     684              : 
     685              : ////////////////////////////////////////////////////////////////////////////////
     686              : /// Generates the day of the month (1-31) from the current time. If there is
     687              : /// an error, numeric_limits<unsigned int>::max() is returned.
     688              : 
     689            0 : unsigned int TimeStamp::getMonthDay() const
     690              : {
     691            0 :   unsigned int uiDay = std::numeric_limits<unsigned int>::max();
     692              : 
     693            0 :   time_t tNumSecs = getTimeValSecs();
     694            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     695              : 
     696            0 :   if ( tmCurr != NULL )
     697              :   {
     698            0 :     uiDay = static_cast<unsigned int>( tmCurr->tm_mday );
     699              :   }
     700              : 
     701            0 :   return uiDay;
     702              : }
     703              : 
     704              : ////////////////////////////////////////////////////////////////////////////////
     705              : /// Generates the hour of the day (0-23) from the current time. If there is
     706              : /// an error, numeric_limits<unsigned int>::max() is returned.
     707              : 
     708            0 : unsigned int TimeStamp::getDayHour() const
     709              : {
     710            0 :   unsigned int uiHour = std::numeric_limits<unsigned int>::max();
     711              : 
     712            0 :   time_t tNumSecs = getTimeValSecs();
     713            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     714              : 
     715            0 :   if ( tmCurr != NULL )
     716              :   {
     717            0 :     uiHour = static_cast<unsigned int>( tmCurr->tm_hour );
     718              :   }
     719              : 
     720            0 :   return uiHour;
     721              : }
     722              : 
     723              : ////////////////////////////////////////////////////////////////////////////////
     724              : /// Generates the minute of the hour (0-59) from the current time. If there is
     725              : /// an error, numeric_limits<unsigned int>::max() is returned.
     726              : 
     727            0 : unsigned int TimeStamp::getHourMinute() const
     728              : {
     729            0 :   unsigned int uiMinute = std::numeric_limits<unsigned int>::max();
     730              : 
     731            0 :   time_t tNumSecs = getTimeValSecs();
     732            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     733              : 
     734            0 :   if ( tmCurr != NULL )
     735              :   {
     736            0 :     uiMinute = static_cast<unsigned int>( tmCurr->tm_min );
     737              :   }
     738              : 
     739            0 :   return uiMinute;
     740              : }
     741              : 
     742              : ////////////////////////////////////////////////////////////////////////////////
     743              : /// Generates the second of the minute (0-60) from the current time. If there is
     744              : /// an error, numeric_limits<unsigned int>::max() is returned.
     745              : 
     746            0 : unsigned int TimeStamp::getMinuteSecond() const
     747              : {
     748            0 :   unsigned int uiSecond = std::numeric_limits<unsigned int>::max();
     749              : 
     750            0 :   time_t tNumSecs = getTimeValSecs();
     751            0 :   tm *tmCurr = ::gmtime( &tNumSecs );
     752              : 
     753            0 :   if ( tmCurr != NULL )
     754              :   {
     755            0 :     uiSecond = static_cast<unsigned int>( tmCurr->tm_sec );
     756              :   }
     757              : 
     758            0 :   return uiSecond;
     759              : }
     760              : 
     761              : ////////////////////////////////////////////////////////////////////////////////
     762              : /// Generates the millisecond of the second (0-999) from the current time.
     763              : 
     764            0 : unsigned int TimeStamp::getSecondMillisecond() const
     765              : {
     766            0 :   unsigned int uiMillisecond = getTimeValMicros() / 1000;
     767              : 
     768            0 :   return uiMillisecond;
     769              : }
     770              : 
     771              : ////////////////////////////////////////////////////////////////////////////////
     772              : /// Decrement the time stamp one day.
     773              : 
     774            0 : void TimeStamp::decrementDay()
     775              : {
     776              :   // There are 86400 seconds in one day.
     777            0 :   m_tvCurr.tv_sec -= 86400;
     778            0 : }
     779              : 
     780              : ////////////////////////////////////////////////////////////////////////////////
     781              : /// Increment the time stamp one day.
     782              : 
     783            0 : void TimeStamp::incrementDay()
     784              : {
     785              :   // There are 86400 seconds in one day.
     786            0 :   m_tvCurr.tv_sec += 86400;
     787            0 : }
     788              : 
     789              : ////////////////////////////////////////////////////////////////////////////////
     790              : /// Creates a string filled with number of microseconds since epoch
     791              : /// (1970 Jan 1), UTC. See 'getMicros' for details about the returned value.
     792              : /// @return The number of microseconds since the unix epoch.
     793              : 
     794            0 : string TimeStamp::getMicrosStr() const
     795              : {
     796            0 :   stringstream ssValue;
     797            0 :   ssValue << getMicros();
     798            0 :   return ssValue.str();
     799            0 : }
     800              : 
     801              : ////////////////////////////////////////////////////////////////////////////////
     802              : /// Creates a string filled with number of milliseconds since epoch
     803              : /// (1970 Jan 1), UTC. See 'getMillis' for details about the returned value.
     804              : /// @return The number of milliseconds since the unix epoch.
     805              : 
     806            0 : string TimeStamp::getMillisStr() const
     807              : {
     808            0 :   stringstream ssValue;
     809            0 :   ssValue << getMillis();
     810            0 :   return ssValue.str();
     811            0 : }
     812              : 
     813              : ////////////////////////////////////////////////////////////////////////////////
     814              : /// Assigns the internal timeval from an MJD number. See 'setMJD" to understand
     815              : /// the format of the MJD. The time is in UTC.
     816              : /// @param xMJD The Modified Julian Day number. The fractional part holds
     817              : /// partial days.
     818              : 
     819            0 : void TimeStamp::fromMJD( const double &xMJD )
     820              : {
     821              :   ///  adjust this day count to start on 1 Jan 1970.
     822            0 :   double xDays = xMJD - 40587.0;
     823              : 
     824              :   ///  convert to a number of seconds.
     825            0 :   long long nnSecs = static_cast<long long>( xDays * 86400.0 );
     826              : 
     827              :   ///  get the number of microsecs.
     828            0 :   m_tvCurr.tv_usec = static_cast<long long>(
     829            0 :                        ( xDays * 86400.0 - static_cast<double>( nnSecs ) ) * 1000000.0 );
     830              : 
     831            0 :   m_tvCurr.tv_sec = nnSecs;
     832            0 : }
     833              : 
     834              : ////////////////////////////////////////////////////////////////////////////////
     835              : /// Sets the internal time from a ISO 8601 formatted string. UTC is assumed.
     836              : /// @param szIso8601 a string like: "2013-09-23T11:41:40.959453Z"
     837              : 
     838            0 : void TimeStamp::fromFormattedIso8601Str( const string &szIso8601 )
     839              : {
     840              :   /*
     841              :     string szIso8601Mod = szIso8601;
     842              : 
     843              :     // We need some speed here, so change this to happen in one loop.
     844              :     for ( unsigned int ii = 0; ii < szIso8601Mod.size(); ii++ )
     845              :     {
     846              :       if ( szIso8601Mod[ii] == '-' || szIso8601Mod[ii] == 'T' ||
     847              :            szIso8601Mod[ii] == ':' || szIso8601Mod[ii] == '.' ||
     848              :            szIso8601Mod[ii] == 'Z' )
     849              :         szIso8601Mod[ii] = ' ';
     850              :     }
     851              :     //std::replace( szIso8601Mod.begin(), szIso8601Mod.end(), '-', ' ' );
     852              :     //std::replace( szIso8601Mod.begin(), szIso8601Mod.end(), 'T', ' ' );
     853              :     //std::replace( szIso8601Mod.begin(), szIso8601Mod.end(), ':', ' ' );
     854              :     //std::replace( szIso8601Mod.begin(), szIso8601Mod.end(), '.', ' ' );
     855              :     //std::replace( szIso8601Mod.begin(), szIso8601Mod.end(), 'Z', ' ' );
     856              : 
     857              :     stringstream ssCurr;
     858              :     ssCurr.str( szIso8601Mod );
     859              : 
     860              :     tm tmCurr;
     861              :     int nYear, nMonth, nDay, nHour, nMinute, nSecond, nMicros;
     862              : 
     863              :     ssCurr >> nYear >> nMonth >> nDay >> nHour >> nMinute >> nSecond >> nMicros;
     864              :   */
     865              :   tm tmCurr;
     866              :   int nYear, nMonth, nDay, nHour, nMinute, nSecond, nMicros;
     867            0 :   ::sscanf( szIso8601.c_str(), "%d-%d-%dT%d:%d:%d.%dZ",
     868              :             &nYear, &nMonth, &nDay, &nHour, &nMinute, &nSecond, &nMicros );
     869              : 
     870            0 :   tmCurr.tm_year = nYear - 1900;
     871            0 :   tmCurr.tm_mon = nMonth - 1;
     872            0 :   tmCurr.tm_mday = nDay;
     873            0 :   tmCurr.tm_hour = nHour;
     874            0 :   tmCurr.tm_min = nMinute;
     875            0 :   tmCurr.tm_sec = nSecond;
     876              : 
     877              :   //JRM changed to timegm from local_timegm
     878            0 :   m_tvCurr.tv_sec = long( timegm( &tmCurr ) );
     879            0 :   m_tvCurr.tv_usec = nMicros;
     880            0 : }
     881              : 
     882              : ////////////////////////////////////////////////////////////////////////////////
     883              : /// Generates a string representing the Modified Julian Day number (MJD).
     884              : /// This day count has been adjusted to start on 17 November 1858. This day
     885              : /// corresponds to MJD 2400000, and is generally accepted as 0, since the
     886              : /// "24" will not change for three centuries to "25".
     887              : /// @return A double which contains the day number and any fraction of a day
     888              : /// which has elapsed.
     889              : 
     890            0 : double TimeStamp::getMJD() const
     891              : {
     892              :   /// first, get the number of days (and fractions of a day) since unix epoch.
     893            0 :   double xDays = ( static_cast<double>( m_tvCurr.tv_sec ) +
     894            0 :                    ( static_cast<double>( m_tvCurr.tv_usec ) / 1000000.0 ) ) / 86400.0;
     895              : 
     896              :   ///  adjust this day count to start on 17 November 1858. This day corresponds
     897              :   ///  to MJD 2400000, and is generally accepted as 0, since the "24" will not
     898              :   ///  change for three centuries to "25".
     899            0 :   return xDays + 40587.0;
     900              : }
     901              : 
     902              : ////////////////////////////////////////////////////////////////////////////////
     903              : /// 'timegm' is nonstandard at this time, so our own version is implemented
     904              : 
     905            0 : ::time_t TimeStamp::local_timegm( ::tm *tmCurr )
     906              : {
     907              :   ::time_t tUtc;
     908              :   char *pcTz;
     909              : 
     910              :   // Get the current time zone. This will be null if it does not exist.
     911            0 :   pcTz = ::getenv( "TZ" );
     912              : 
     913              :   // Set the time zone to be UTC.
     914            0 :   ::setenv( "TZ", "UTC0", 1 );
     915            0 :   ::tzset();
     916              : 
     917              :   // Make a UTC time. (time in the UTC time zone).
     918            0 :   tUtc = ::mktime( tmCurr );
     919              : 
     920              :   // Set the time zone back, or delete it if it did not exist.
     921            0 :   if ( pcTz != NULL )
     922            0 :     ::setenv( "TZ", pcTz, 1 );
     923              :   else
     924            0 :     ::unsetenv( "TZ" );
     925            0 :   :: tzset();
     926              : 
     927            0 :   return tUtc;
     928              : }
     929              : 
     930              : ////////////////////////////////////////////////////
     931              : ////////////////////////////
     932              : /// Handles streaming the TimeStamp formatted string. See 'getFormattedStr'
     933              : /// for details about the format of the string.
     934              : /// @param strmOut The stream to be written to.
     935              : /// @param tsRhs The TimeStamp to be streamed.
     936              : /// @return The modified stream that has been written to.
     937              : 
     938            0 : ostream &operator<< ( ostream &strmOut, const TimeStamp &tsRhs )
     939              : {
     940            0 :   strmOut << tsRhs.getFormattedStr();
     941            0 :   return strmOut;
     942              : }
     943              : 
     944              : ////////////////////////////////////////////////////////////////////////////////
        

Generated by: LCOV version 2.0-1