00001 #ifndef PSTIME_TIME_H 00002 #define PSTIME_TIME_H 00003 00004 //-------------------------------------------------------------------------- 00005 // File and Version Information: 00006 // $Id: Time.h 5859 2013-03-22 22:35:24Z salnikov@SLAC.STANFORD.EDU $ 00007 // 00008 // Description: 00009 // Class Time. 00010 // 00011 // The transformation to/from human-readable time format, required by I/O, 00012 // is based on the standard ISO8601 time presentation. 00013 // 00014 // This is essentially a wrap-up for clock_gettime() [UNIX/POSIX time] 00015 // access to high-resolution time method, 00016 // utilizing "struct timespec" and "struct tm" from <time.h> 00017 // Some arithmetics between PSTime and PSDuration objects is also available. 00018 // 00019 //------------------------------------------------------------------------ 00020 00021 //----------------- 00022 // C/C++ Headers -- 00023 //----------------- 00024 #include <time.h> 00025 #include <iosfwd> 00026 #include <string> 00027 #include <stdint.h> 00028 00029 #include "PSTime/Duration.h" 00030 00031 // --------------------- 00032 // -- Class Interface -- 00033 // --------------------- 00034 00035 /** 00036 * @defgroup PSTime PSTime package 00037 * 00038 * @brief Package defining time-related classes for psana framework. 00039 * 00040 * This package include several classes and functions which define 00041 * time representation and operations with time. It is based on on 00042 * standard ISO8601 external representation (http://en.wikipedia.org/wiki/ISO_8601) 00043 * but it does not provide complete support and in samoe cases it is 00044 * made more human-oriented. 00045 * 00046 * Core of the package are two classes: Time and Duration. Other classes define 00047 * formatting functions and various utility functions. 00048 */ 00049 00050 00051 namespace PSTime { 00052 00053 /** 00054 * @ingroup PSTime 00055 * 00056 * @brief Standard time class for use in LCLS software. 00057 * 00058 * The transformation to/from human-readable time format, required by I/O, 00059 * is based on the standard ISO8601 time presentation. 00060 * 00061 * This is essentially a wrap-up for clock_gettime() [UNIX/POSIX time] 00062 * access to high-resolution time method, 00063 * utilizing "struct timespec" and "struct tm" from <time.h> 00064 * Some arithmetics between PSTime and PSDuration objects is also available. 00065 * 00066 * This software was developed for the LCLS project. If you use all or 00067 * part of it, please give an appropriate acknowledgment. 00068 * 00069 * @version \$Id: Time.h 5859 2013-03-22 22:35:24Z salnikov@SLAC.STANFORD.EDU $ 00070 * 00071 * @author Mikhail S. Dubrovin 00072 */ 00073 00074 class Time { 00075 public: 00076 00077 /** 00078 * @brief Type for time zone designation. 00079 * 00080 * There are several methods in Time class which can produce time 00081 * representation in either local or UTC time zones. By default 00082 * all these methods assume local time zone, use UTC enum value as 00083 * the parameter to those methods to produce UTC representation. 00084 */ 00085 enum Zone { UTC, Local }; 00086 00087 /** 00088 * @brief Default constructor makes zero (epoch) time. 00089 * 00090 * Use now() method if you need current time. 00091 */ 00092 Time (); 00093 00094 /** 00095 * @brief Construct from UNIX time. 00096 * 00097 * Constructs a time from an unsigned number of seconds since the 00098 * the Unix epoch of 1970-01-01; nanoseconds are optional, if needed. 00099 */ 00100 explicit Time (time_t sec_since_1970_01_01, uint32_t nsec = 0); 00101 00102 /** 00103 * @brief Construct from broken-down representation. 00104 * 00105 * @param[in] year Calendar year C.E. (e.g., 2010). 00106 * @param[in] month Month in the range [1,12]. 00107 * @param[in] day Day of the month in the range [1,31]. 00108 * @param[in] hour Hours in the range [0,23]. 00109 * @param[in] min Minutes after the hour in the range [0,59]. 00110 * @param[in] sec Seconds in the range [0,59*] (*) might be up to 61 for leap seconds. 00111 * @param[in] nsec Nanoseconds after the second in the range [0,999999999]. 00112 * @param[in] zone Time zone, default is local time zone. 00113 */ 00114 Time (int year, 00115 int month, 00116 int day, 00117 int hour, 00118 int min, 00119 int sec, 00120 uint32_t nsec = 0, 00121 Zone zone = Local); 00122 00123 /** 00124 * @brief Constructs a time from the timespec struct (for high resolution time). 00125 */ 00126 explicit Time (struct timespec& ts); 00127 00128 /** 00129 * @brief Constructs a time from the tm struct (broken-down time) and zone. 00130 */ 00131 explicit Time (struct tm& tms, Zone zone = Local); 00132 00133 /** 00134 * @brief Constructs a time from the string representation. 00135 * 00136 * Accepts the time stamp in format: 00137 * @li <date>, or 00138 * @li <date> <time>[.<fraction-of-sec>][<zone>], or 00139 * @li <date>T<time>[.<fraction-of-sec>][<zone>] 00140 * 00141 * where 00142 * 00143 * @li <date> should be in format @c YYYY-MM-DD, @c YYYYMMDD, @c YYYY-MM, @c YYYYMM, 00144 * or @c YYYY, if month or day is missing they are assumed to be 1; 00145 * @li <time> should be in format @c HH:MM:SS, @c HHMMSS, @c HH:MM, @c HHMM, @c HH, 00146 * if minutes or seconds are missing they are assumed to be 0; 00147 * @li <fraction-of-sec> may have up to 9 digits; if this field is missing, 00148 * it is assumed equal to 0, fraction require seconds to be specified; 00149 * @li <zone> should be @c Z for UTC or in format @c {sign}HH[:MM] or {sign}HHMM, 00150 * if this field is missing time is assumed to be in local time zone. 00151 * 00152 * Examples of valid input are: 00153 * @li "2000-01-01 00:00:00" - beginning of year 2000 in local time zone 00154 * @li "2000-01-01 00:00:00Z" - beginning of year 2000 in UTC 00155 * @li "2000-01-01 00:00:00-08" - beginning of year 2000 in PST 00156 * @li "2000-01-01 00:00:00.000000001" - one nanosecond after the beginning of year 2000 00157 * in local time zone 00158 * @li "20000101T000000.001" - one millisecond after the beginning of year 2000 in 00159 * local time zone in compact form 00160 * @li "20000101" - beginning of year 2000 in local time zone 00161 * @li "2000" - same as above 00162 * 00163 * @throw TimeParseException 00164 */ 00165 explicit Time (const std::string& str); 00166 00167 /** 00168 * @brief Subtract two times and return duration. 00169 * 00170 * Duration cannot be negative, so t1-t2 is always equal to t2-t1. 00171 */ 00172 Duration operator-( const Time& t ) const; 00173 00174 /// Add duration to time. 00175 Time& operator+=( const Duration& d ); 00176 00177 /// Subtract duration from time. 00178 Time& operator-=( const Duration& d ); 00179 00180 /// Compare two times 00181 bool operator!=( const Time& t ) const { 00182 return ( m_utcSec != t.m_utcSec || m_utcNsec != t.m_utcNsec ); 00183 } 00184 00185 /// Compare two times 00186 bool operator==( const Time& t ) const { return !( *this != t ); } 00187 00188 /// Compare two times 00189 bool operator<( const Time& t ) const { 00190 return ( m_utcSec < t.m_utcSec ) || 00191 ( m_utcSec == t.m_utcSec && m_utcNsec < t.m_utcNsec ); 00192 } 00193 00194 /// Compare two times 00195 bool operator>( const Time& t ) const { 00196 return ( m_utcSec > t.m_utcSec ) || 00197 ( m_utcSec == t.m_utcSec && m_utcNsec > t.m_utcNsec ); 00198 } 00199 00200 /// Compare two times 00201 bool operator>=( const Time& t ) const { return !( *this < t ); } 00202 00203 /// Compare two times 00204 bool operator<=( const Time& t ) const { return !( *this > t ); } 00205 00206 /// POSIX sec. since 00:00:00 Jan. 1, 1970 UTC 00207 time_t sec() const {return m_utcSec;} 00208 00209 /// returns nanoseconds value 00210 uint32_t nsec() const {return m_utcNsec;} 00211 00212 /// Returns the Time object content via high-resolution time timespec structure. 00213 struct timespec getTimeSpec() const; 00214 00215 /// Returns the Time object content via broken-down time tm structure for indicated zone. 00216 struct tm gettm( Zone zone = Local ) const; 00217 00218 /** 00219 * @brief Return time representation in extended ISO8601 format. 00220 * 00221 * Output will look like "2011-01-30 17:52:50.123456789-08". This format 00222 * is acceptable for human-readable output. 00223 * 00224 * @param[in] zone Time zone to use for string representation 00225 * @param[in] nsecPrecision Precision of nanoseconds field, if 0 then nanoseconds 00226 * will not be shown. 00227 */ 00228 std::string asString( Zone zone = Local, int nsecPrecision = 9 ) const; // YYYY-MM-DD HH:MM:SS.NNNNNNNNN+HH:MM 00229 00230 /** 00231 * @brief Return time representation in basic ISO8601 format. 00232 * 00233 * Output will look like "20110130T175250-08". This format is intended 00234 * for machine-readable output, such as timestamps in file names, etc. 00235 * 00236 * @param[in] zone Time zone to use for string representation 00237 * @param[in] nsecPrecision Precision of nanoseconds field, if 0 then nanoseconds 00238 * will not be shown. 00239 */ 00240 std::string asStringCompact( Zone zone = Local, int nsecPrecision = 0 ) const; // HHMMSSTHHMMSS+HHMM 00241 00242 00243 /** 00244 * @brief Format time according the supplied format string. 00245 * 00246 * For full description of the acceptable format codes see TimeFormat::format() method. 00247 * 00248 * @param[in] fmt Format string 00249 * @param[in] zone Time zone to use for string representation 00250 */ 00251 std::string asStringFormat( const std::string& fmt="%Y-%m-%d %H:%M:%S%f%z", Zone zone = Local ) const; 00252 00253 protected: 00254 00255 private: 00256 00257 // Data members 00258 time_t m_utcSec; ///< Number of seconds since UNIX epoch time 00259 uint32_t m_utcNsec; ///< Number of nanoseconds within second (range 0..999999999) 00260 00261 //------------------ 00262 // Static Members -- 00263 //------------------ 00264 00265 public: 00266 00267 /** 00268 * @brief Returns current time. 00269 */ 00270 static Time now() ; 00271 00272 }; // class Time 00273 00274 00275 /// Addition of duration and time objects 00276 inline 00277 Time 00278 operator+(const Duration& d, const Time& t) 00279 { 00280 Time tmp = t; 00281 tmp += d; 00282 return tmp; 00283 } 00284 00285 /// Addition of time and duration objects 00286 inline 00287 Time 00288 operator+(const Time& t, const Duration& d) 00289 { 00290 Time tmp = t; 00291 tmp += d; 00292 return tmp; 00293 } 00294 00295 /// Subtract duration from time 00296 inline 00297 Time 00298 operator-(const Time& t, const Duration& d ) 00299 { 00300 Time tmp = t; 00301 tmp -= d; 00302 return tmp; 00303 } 00304 00305 /// Stream insertion operator, prints result of Time::asString() method. 00306 std::ostream& 00307 operator<<( std::ostream& os, const Time& t ); 00308 00309 } // namespace PSTime 00310 00311 #endif // PSTIME_TIME_H