// Module: Log4CPLUS // File: timehelper.cxx // Created: 4/2003 // Author: Tad E. Smith // // // Copyright (C) Tad E. Smith All rights reserved. // // This software is published under the terms of the Apache Software // License version 1.1, a copy of which has been included with this // distribution in the LICENSE.APL file. // // $Log: timehelper.cxx,v $ // Revision 1.7 2004/01/29 07:27:54 tcsmith // Fixed Bug #805203 - The getFormattedTime() method now pads the time string with // leading zeros where needed. // // Revision 1.6 2003/08/05 09:20:08 tcsmith // Modified the getFormattedTime() method to increase performance. // // Revision 1.5 2003/06/29 16:36:10 tcsmith // Removed the setTime(long) method. // // Revision 1.4 2003/06/27 15:45:51 tcsmith // Removed getMillis() method. // // Revision 1.3 2003/06/23 20:54:33 tcsmith // Added mutliplication and division operator implementations for the Time // class. // // Revision 1.2 2003/06/12 23:10:54 tcsmith // Added the Time class implementation. // // Revision 1.1 2003/06/04 18:54:31 tcsmith // Renamed strftime.cxx to timehelper.cxx // // Revision 1.2 2003/04/19 23:51:17 tcsmith // Now call the strftime() function in the global namespace. // // Revision 1.1 2003/04/19 22:55:27 tcsmith // Initial version. // #include #include #include #include #if defined(HAVE_FTIME) #include #endif #if defined(HAVE_GETTIMEOFDAY) #include #endif #if defined(HAVE_GMTIME_R) && !defined(LOG4CPLUS_SINGLE_THREADED) #define LOG4CPLUS_NEED_GMTIME_R #endif #if defined(HAVE_LOCALTIME_R) && !defined(LOG4CPLUS_SINGLE_THREADED) #define LOG4CPLUS_NEED_LOCALTIME_R #endif #define BUFFER_SIZE 40 #define ONE_SEC_IN_USEC 1000000 using namespace std; using namespace log4cplus; using namespace log4cplus::helpers; ////////////////////////////////////////////////////////////////////////////// // Time ctors ////////////////////////////////////////////////////////////////////////////// Time::Time() : tv_sec(0), tv_usec(0) { } Time::Time(long tv_sec, long tv_usec) : tv_sec(tv_sec), tv_usec(tv_usec) { } Time::Time(time_t time) : tv_sec(time), tv_usec(0) { } Time Time::gettimeofday() { #if defined(HAVE_GETTIMEOFDAY) timeval tp; ::gettimeofday(&tp, 0); return Time(tp.tv_sec, tp.tv_usec); #elif defined(HAVE_FTIME) struct timeb tp; ::ftime(&tp); return Time(tp.time, tp.millitm * 1000); #else #warning "Time::gettimeofday()- low resolution timer: gettimeofday and ftime unavailable" return Time(::time(0), 0); #endif } ////////////////////////////////////////////////////////////////////////////// // Time methods ////////////////////////////////////////////////////////////////////////////// int Time::setTime(struct tm* t) { time_t time = ::mktime(t); if(time != -1) { tv_sec = time; } return time; } time_t Time::getTime() const { return tv_sec; } void Time::gmtime(struct tm* t) const { time_t clock = tv_sec; #ifdef LOG4CPLUS_NEED_GMTIME_R ::gmtime_r(&clock, t); #else struct tm* tmp = ::gmtime(&clock); *t = *tmp; #endif } void Time::localtime(struct tm* t) const { time_t clock = tv_sec; #ifdef LOG4CPLUS_NEED_LOCALTIME_R ::localtime_r(&clock, t); #else struct tm* tmp = ::localtime(&clock); *t = *tmp; #endif } log4cplus::tstring Time::getFormattedTime(const log4cplus::tstring& fmt, bool use_gmtime) const { tchar buffer[BUFFER_SIZE]; struct tm time; if(use_gmtime) { gmtime(&time); } else { localtime(&time); } #ifdef UNICODE size_t len = ::wcsftime(buffer, BUFFER_SIZE, fmt.c_str(), &time); #else size_t len = ::strftime(buffer, BUFFER_SIZE, fmt.c_str(), &time); #endif buffer[len] = '\0'; tstring ret(buffer); size_t pos = ret.find( LOG4CPLUS_TEXT("%q") ); if(pos != tstring::npos) { tstring tmp(ret.substr(0, pos)); tstring seconds( convertIntegerToString((tv_usec / 1000)) ); switch(seconds.length()) { case 1: tmp += LOG4CPLUS_TEXT("00"); break; case 2: tmp += LOG4CPLUS_TEXT("0"); break; } tmp += seconds; tmp += ret.substr(pos + 2); ret = tmp; } pos = ret.find( LOG4CPLUS_TEXT("%Q") ); if(pos != tstring::npos) { tstring tmp(ret.substr(0, pos)); tstring seconds( convertIntegerToString((tv_usec / 1000)) ); switch(seconds.length()) { case 1: tmp += LOG4CPLUS_TEXT("00"); break; case 2: tmp += LOG4CPLUS_TEXT("0"); break; } tmp += seconds; #if defined(HAVE_GETTIMEOFDAY) tstring usecs( convertIntegerToString((tv_usec % 1000)) ); switch(usecs.length()) { case 1: tmp += LOG4CPLUS_TEXT(".00"); break; case 2: tmp += LOG4CPLUS_TEXT(".0"); break; case 3: tmp += LOG4CPLUS_TEXT("."); break; } tmp += usecs; #endif tmp += ret.substr(pos + 2); ret = tmp; } return ret; } Time& Time::operator+=(const Time& rhs) { tv_sec += rhs.tv_sec; tv_usec += rhs.tv_usec; if(tv_usec > ONE_SEC_IN_USEC) { ++tv_sec; tv_usec -= ONE_SEC_IN_USEC; } return *this; } Time& Time::operator-=(const Time& rhs) { tv_sec -= rhs.tv_sec; tv_usec -= rhs.tv_usec; if(tv_usec < 0) { --tv_sec; tv_usec += ONE_SEC_IN_USEC; } return *this; } Time& Time::operator/=(long rhs) { long rem_secs = tv_sec % rhs; tv_sec /= rhs; tv_usec /= rhs; tv_usec += ((rem_secs * ONE_SEC_IN_USEC) / rhs); return *this; } Time& Time::operator*=(long rhs) { long new_usec = tv_usec * rhs; long overflow_sec = new_usec / ONE_SEC_IN_USEC; tv_usec = new_usec % ONE_SEC_IN_USEC; tv_sec *= rhs; tv_sec += overflow_sec; return *this; } ////////////////////////////////////////////////////////////////////////////// // Time globals ////////////////////////////////////////////////////////////////////////////// const Time operator+(const Time& lhs, const Time& rhs) { return Time(lhs) += rhs; } const Time operator-(const Time& lhs, const Time& rhs) { return Time(lhs) -= rhs; } const Time operator/(const Time& lhs, long rhs) { return Time(lhs) /= rhs; } const Time operator*(const Time& lhs, long rhs) { return Time(lhs) *= rhs; } bool operator<(const Time& lhs, const Time& rhs) { return ( (lhs.sec() < rhs.sec()) || ( (lhs.sec() == rhs.sec()) && (lhs.usec() < rhs.usec())) ); } bool operator<=(const Time& lhs, const Time& rhs) { return ((lhs < rhs) || (lhs == rhs)); } bool operator>(const Time& lhs, const Time& rhs) { return ( (lhs.sec() > rhs.sec()) || ( (lhs.sec() == rhs.sec()) && (lhs.usec() > rhs.usec())) ); } bool operator>=(const Time& lhs, const Time& rhs) { return ((lhs > rhs) || (lhs == rhs)); } bool operator==(const Time& lhs, const Time& rhs) { return ( lhs.sec() == rhs.sec() && lhs.usec() == rhs.usec()); } bool operator!=(const Time& lhs, const Time& rhs) { return !(lhs == rhs); }