#ifndef __Time_H__ #define __Time_H__ #include class Time_Span; /** * This class is to provide a consistant interface and storage to clock time * .. Epoch based time to the second * * jan-2000 .. rhh changing all time to use sub second timing... */ class Time_Clock { friend class Time_Span; public: // Constructors static Time_Clock GetCurrentTime(); void ToCurrentTime(); inline Time_Clock(const timeval &in_mytime) { _my_time = in_mytime; } Time_Clock(); Time_Clock(time_t time); Time_Clock(long secs, long usecs); Time_Clock(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds = 0, int nDST = -1); Time_Clock(const Time_Clock& timeSrc); inline const Time_Clock &operator=(const Time_Clock& timeSrc); inline const Time_Clock &operator=(time_t t); // Attributes struct tm *GetGmtTm(struct tm *ptm) const; struct tm *GetLocalTm(struct tm *ptm) const; time_t GetTime() const; int GetYear() const; int GetMonth() const; // month of year (1 = Jan) int GetDay() const; // day of month int GetHour() const; int GetMinute() const; int GetSecond() const; int GetDayOfWeek() const; // 1=Sun, 2=Mon, ..., 7=Sat void Set(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds = 0, int nDST = -1); // Operations time math const Time_Clock& operator+=(const Time_Span &Time_Span); const Time_Clock& operator-=(const Time_Span &Time_Span); bool operator==(const Time_Clock &time) const; bool operator!=(const Time_Clock &time) const; bool operator<(const Time_Clock &time) const; bool operator>(const Time_Clock &time) const; bool operator<=(const Time_Clock &time) const; bool operator>=(const Time_Clock &time) const; inline time_t GetTime_t() { return _my_time.tv_sec; } inline long GetUsecPart() { return _my_time.tv_usec; } // formatting using "C" strftime std::string Format(const char *pFormat) const; std::string FormatGmt(const char *pFormat) const; const timeval &GetTval() { return _my_time; } const timeval &GetTval() const { return _my_time; } private: struct timeval _my_time; }; /** * Construction from parts */ inline Time_Clock:: Time_Clock(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds, int nDST) { struct tm atm; atm.tm_sec = nSec; atm.tm_min = nMin; atm.tm_hour = nHour; assert(nDay >= 1 && nDay <= 31); atm.tm_mday = nDay; assert(nMonth >= 1 && nMonth <= 12); atm.tm_mon = nMonth - 1; // tm_mon is 0 based assert(nYear >= 1900); atm.tm_year = nYear - 1900; // tm_year is 1900 based atm.tm_isdst = nDST; _my_time.tv_sec = (long)mktime(&atm); assert(_my_time.tv_sec != -1); // indicates an illegal input time _my_time.tv_usec = microseconds; assert(_my_time.tv_usec < 1000000); } /** * */ inline void Time_Clock:: Set(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, long microseconds , int nDST) { struct tm atm; atm.tm_sec = nSec; atm.tm_min = nMin; atm.tm_hour = nHour; assert(nDay >= 1 && nDay <= 31); atm.tm_mday = nDay; assert(nMonth >= 1 && nMonth <= 12); atm.tm_mon = nMonth - 1; // tm_mon is 0 based assert(nYear >= 1900); atm.tm_year = nYear - 1900; // tm_year is 1900 based atm.tm_isdst = nDST; _my_time.tv_sec = (long)mktime(&atm); assert(_my_time.tv_sec != -1); // indicates an illegal input time _my_time.tv_usec = microseconds; assert(_my_time.tv_usec < 1000000); } /** * The Default no param constructor.. Will set time to current system time */ inline Time_Clock Time_Clock:: GetCurrentTime() { return Time_Clock(); } /** * */ inline Time_Clock:: Time_Clock() { gettimeofday(&_my_time, nullptr); } /** * Load this object with the current OS time */ inline void Time_Clock:: ToCurrentTime() { gettimeofday(&_my_time, nullptr); } /** * Access the stored time and converts to a struct tm format If storage * location is specified then it will stor information in the provided buffer * else it will use the library's internal buffer space */ inline struct tm *Time_Clock:: GetGmtTm(struct tm *ptm) const { nassertr(ptm != nullptr, nullptr); #ifdef _WIN32 return (gmtime_s(ptm, (const time_t *)&_my_time.tv_sec) == 0) ? ptm : nullptr; #else return gmtime_r((const time_t *)&_my_time.tv_sec, ptm); #endif } /** * Gets The local time in a tm structre from the internal time value */ inline struct tm *Time_Clock:: GetLocalTm(struct tm *ptm) const { nassertr(ptm != nullptr, nullptr); #ifdef _WIN32 return (localtime_s(ptm, (const time_t *)&_my_time.tv_sec) == 0) ? ptm : nullptr; #else return localtime_r((const time_t *)&_my_time.tv_sec, ptm); #endif } // String formatting Verifies will fail if the needed buffer size is too large #define maxTimeBufferSize 4096 /** * Used to allow access to the "C" library strftime functions.. */ inline std::string Time_Clock:: Format(const char *pFormat) const { char szBuffer[maxTimeBufferSize]; char ch, ch1; char *pch = szBuffer; while ((ch = *pFormat++) != '\0') { assert(pch < &szBuffer[maxTimeBufferSize]); if (ch == '%') { switch (ch1 = *pFormat++) { default: *pch++ = ch; *pch++ = ch1; break; case 'N': #ifdef _WIN32 pch += sprintf_s(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000)); #else pch += snprintf(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000)); #endif break; } } else { *pch++ = ch; } } *pch = '\0'; char szBuffer1[maxTimeBufferSize]; struct tm tmTemp; if (GetLocalTm(&tmTemp) == nullptr || !strftime(szBuffer1, sizeof(szBuffer1), szBuffer, &tmTemp)) { szBuffer1[0] = '\0'; } return std::string(szBuffer1); } /** * A Wraper to size_t strftime( char *strDest, size_t maxsize, const char * *format, const struct tm *timeptr ); * */ inline std::string Time_Clock:: FormatGmt(const char *pFormat) const { char szBuffer[maxTimeBufferSize]; char ch, ch1; char *pch = szBuffer; while ((ch = *pFormat++) != '\0') { assert(pch < &szBuffer[maxTimeBufferSize]); if (ch == '%') { switch (ch1 = *pFormat++) { default: *pch++ = ch; *pch++ = ch1; break; case 'N': #ifdef _WIN32 pch += sprintf_s(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000)); #else pch += snprintf(pch, maxTimeBufferSize, "%03ld", (long)(_my_time.tv_usec / 1000)); #endif break; } } else { *pch++ = ch; } } *pch = '\0'; char szBuffer1[maxTimeBufferSize]; struct tm tmTemp; if (GetGmtTm(&tmTemp) == nullptr || !strftime(szBuffer1, sizeof(szBuffer1), szBuffer, &tmTemp)) { szBuffer1[0] = '\0'; } return std::string(szBuffer1); } /** * The Constructor that take a time_t objext */ inline Time_Clock:: Time_Clock(time_t time) { _my_time.tv_sec = (long)time; _my_time.tv_usec = 0; } /** * Constructor that takes in sec and usecs.. */ inline Time_Clock:: Time_Clock(long secs, long usecs) { _my_time.tv_sec = secs; _my_time.tv_usec = usecs; NormalizeTime(_my_time); } /** * yet another constructor */ inline Time_Clock:: Time_Clock(const Time_Clock& timeSrc) { _my_time.tv_sec = timeSrc._my_time.tv_sec; _my_time.tv_usec = timeSrc._my_time.tv_usec; } /** * .. is time equal */ inline bool Time_Clock:: operator==(const Time_Clock &time) const { return ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec == time._my_time.tv_usec)); } /** * .is time != */ inline bool Time_Clock:: operator!=(const Time_Clock &time) const { return ((_my_time.tv_sec != time._my_time.tv_sec) || (_my_time.tv_usec != time._my_time.tv_usec)); } /** * */ inline bool Time_Clock:: operator<(const Time_Clock &time) const { return ((_my_time.tv_sec < time._my_time.tv_sec) || ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec < time._my_time.tv_usec))); } /** * */ inline bool Time_Clock:: operator>(const Time_Clock &time) const { return ((_my_time.tv_sec > time._my_time.tv_sec) || ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec > time._my_time.tv_usec))); } /** * */ inline bool Time_Clock:: operator<=(const Time_Clock &time) const { return ((_my_time.tv_sec < time._my_time.tv_sec) || ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec <= time._my_time.tv_usec))); } /** * */ inline bool Time_Clock:: operator>=(const Time_Clock &time) const { return ((_my_time.tv_sec > time._my_time.tv_sec) || ((_my_time.tv_sec == time._my_time.tv_sec) && (_my_time.tv_usec >= time._my_time.tv_usec))); } /** * */ inline const Time_Clock& Time_Clock:: operator=(const Time_Clock& timeSrc) { if (&timeSrc == this) { return *this; } _my_time = timeSrc._my_time; return *this; } /** * */ inline const Time_Clock& Time_Clock:: operator=(time_t t) { _my_time.tv_sec = (long)t; _my_time.tv_usec = 0; return *this; } /** * */ inline time_t Time_Clock:: GetTime() const { return _my_time.tv_sec; } /** * */ inline int Time_Clock:: GetYear() const { struct tm atm; return (GetLocalTm(&atm)->tm_year) + 1900; } /** * */ inline int Time_Clock:: GetMonth() const { struct tm atm; return GetLocalTm(&atm)->tm_mon + 1; } /** * */ inline int Time_Clock:: GetDay() const { struct tm atm; return GetLocalTm(&atm)->tm_mday; } /** * */ inline int Time_Clock:: GetHour() const { struct tm atm; return GetLocalTm(&atm)->tm_hour; } /** * */ inline int Time_Clock:: GetMinute() const { struct tm atm; return GetLocalTm(&atm)->tm_min; } /** * */ inline int Time_Clock:: GetSecond() const { struct tm atm; return GetLocalTm(&atm)->tm_sec; } /** * */ inline int Time_Clock:: GetDayOfWeek() const { struct tm atm; return GetLocalTm(&atm)->tm_wday + 1; } #endif //__Time_H__