![]() |
|
|
Bdb packages | Design docs | Source docs | Guidelines | Recent releases |
|
Main Page Modules Namespace List Class Hierarchy Alphabetical List Compound List File List Compound Members File Members /BdbTime/BdbTime.hh
Go to the documentation of this file.00001 #ifndef BDBTIME_HH 00002 #define BDBTIME_HH 00003 00004 //----------------------------------------------------------------------------- 00005 // 00006 // File and Version Information: 00007 // $Id: BdbTime.hh,v 1.15 2002/05/08 00:19:57 gpdf Exp $ 00008 // 00009 // Description: 00010 // Class BdbTime. 00011 // This is a persistent time class. 00012 // 00013 // Environment: 00014 // Software developed for the BaBar Detector at the SLAC B-Factory. 00015 // 00016 // Author List: 00017 // J. Ohnemus Original Author 00018 // Gregory Dubois-Felsmann RW migration, 2002 00019 // 00020 // Copyright Information: 00021 // Copyright (C) 1994, 1995 Lawrence Berkeley Laboratory 00022 // Copyright (c) 2002 California Institute of Technology 00023 // 00024 //----------------------------------------------------------------------------- 00025 00026 //----------------- 00027 // BaBar Headers -- 00028 //----------------- 00029 #include "BaBar/BaBarODMGTypes.h" 00030 00031 //----------------- 00032 // C/C++ Headers -- 00033 //----------------- 00034 #include <time.h> 00035 #include <iostream.h> 00036 #include <string> 00037 00038 //---------------------- 00039 // Rogue Wave Headers -- 00040 //---------------------- 00041 #include <rw/rwtime.h> 00042 #include <rw/zone.h> 00043 #include <rw/rwdate.h> 00044 #include <rw/rstream.h> 00045 00046 //---------------------- 00047 // Base Class Headers -- 00048 //---------------------- 00049 00050 //------------------------------- 00051 // Collaborating Class Headers -- 00052 //------------------------------- 00053 #include "BdbTime/BdbDuration.hh" 00054 #include "BdbTime/BdbTimeConst.hh" 00055 00056 //------------------------------------ 00057 // Collaborating Class Declarations -- 00058 //------------------------------------ 00059 00060 class RWCString; 00061 00062 // --------------------- 00063 // -- Class Interface -- 00064 // --------------------- 00065 00066 class BdbTime { 00067 00068 public: 00069 00070 enum Zone { Local, UTC }; 00071 00072 // Constructors 00073 00074 /** 00075 * Constructs with the current time, to the nearest second. This 00076 * constructor is deprecated and may be removed in a future release. 00077 * The static function BdbTime::now() should be used in preference 00078 * to this in all new code, if the current time is really required. 00079 * 00080 * For some reason, the original implementation did not set the _gmtNsec 00081 * member, perhaps because it was not easy to get it synchronized with 00082 * the Rogue Wave "now()" function's return value. Now that we use 00083 * clock_gettime() directly, this could be fixed. 00084 * 00085 * However, we have decided not to do this at this time, in order not 00086 * to change the behavior of existing programs. 00087 * 00088 * BdbTime::now() preserves the full significance available from 00089 * clock_gettime(). 00090 * 00091 * Please note that this constructor involves a system call and is 00092 * expensive! Do not default-construct BdbTimes unless you really need 00093 * the current time value. If you are just declaring a time variable 00094 * to fill in later, BdbTime(0) is a more performant choice. 00095 */ 00096 BdbTime( ); 00097 00098 /** Copy constructor. */ 00099 BdbTime( const BdbTime& t ); 00100 00101 /** 00102 * Constructs a time from an unsigned number of seconds since the 00103 * BdbTime epoch of 1901. NB: this is not the Unix epoch of 1970! 00104 */ 00105 explicit BdbTime( d_ULong sec_since_1901, d_ULong nsec = 0 ); 00106 00107 /** 00108 * Constructs a time from a broken-down list of components of a date 00109 * and time. 00110 */ 00111 BdbTime( d_ULong year, 00112 d_ULong month, 00113 d_ULong day, 00114 d_ULong hour, 00115 d_ULong minute, 00116 d_ULong second, 00117 d_ULong nanosecond = 0, 00118 Zone zone = UTC ); 00119 00120 /** 00121 * Constructs a time from a broken-down list of components of a date 00122 * and time. Deprecated Rogue Wave version. 00123 */ 00124 BdbTime( d_ULong year, 00125 d_ULong month, 00126 d_ULong day, 00127 d_ULong hour, 00128 d_ULong minute, 00129 d_ULong second, 00130 d_ULong nanosecond, 00131 const RWZone& zone ); 00132 00133 // This constructor will not be migrated from RW. It has never been used 00134 // in BaBar, has no readily apparent safe use, and will be withdrawn. -gpdf 00135 BdbTime( d_ULong hour, 00136 d_ULong minute, 00137 d_ULong second, 00138 d_ULong nanosecond = 0, 00139 const RWZone& zone = RWZone::utc() ); 00140 00141 /** Deprecated constructor from a Rogue Wave time. */ 00142 BdbTime( const RWTime& t ); // RWTime constructor 00143 00144 // date/time textstring constructor. This accepts all forms of date 00145 // specification accepted by RWDate. By default times are interpreted as UTC 00146 // (a logical alternative might be RWZone::local()). 00147 // If an invalid date or time string is present, the BdbTime time will 00148 // be set to -infinity. If the string is set to +Infinity or 00149 // -Infinity, the BdbTime will be set to that as well. 00150 BdbTime( const RWCString& date, const RWCString& time, 00151 const RWZone& zone = RWZone::utc()); 00152 00153 // Interim version of this for std::string. Initially implemented using 00154 // the RW behavior underneath. Will be reimplemented RW-free and may take 00155 // a restricted set of string formats at that point. 00156 BdbTime( const std::string& date, const std::string& time, Zone zone = UTC ); 00157 00158 // same as above, but with the date and time in a single string 00159 // (separated by whitespace) 00160 BdbTime( const RWCString& datetime, 00161 const RWZone& zone = RWZone::utc()); 00162 00163 // Interim version of this for std::string. Initially implemented using 00164 // the RW behavior underneath. Will be reimplemented RW-free and may take 00165 // a restricted set of string formats at that point. 00166 BdbTime( const std::string&, Zone zone = UTC ); 00167 00168 /** 00169 * Constructs from POSIX high-resolution time, as might be 00170 * obtained from clock_gettime. 00171 */ 00172 BdbTime( const struct timespec& ts ); 00173 00174 /** 00175 * Constructs from POSIX "broken-down time". 00176 * @param stm Cannot be const because it is internally provided to 00177 * POSIX mktime(), which normalizes it -- see man mktime. 00178 */ 00179 BdbTime( struct tm& stm, Zone zone = UTC ); 00180 00181 /** 00182 * The destructor is non-virtual in order to keep this representational 00183 * class small and suitable for processing with value semantics. 00184 * Class with non-empty destructors should not be constructed with 00185 * non-private inheritance from BdbTime. 00186 */ 00187 ~BdbTime( ) { } 00188 00189 00190 // Assignment operator 00191 BdbTime& operator=( const BdbTime& t ); 00192 00193 // Calculational operators 00194 00195 /** 00196 * Calculates the absolute value of the difference between two times. 00197 * NB: BdbDuration is an inherently unsigned quantity! This is 00198 * in essence because reasonably foreseeable time differences are 00199 * larger in seconds than 2^31 and so can't be represented as a 00200 * signed 32 bit integer. 00201 */ 00202 BdbDuration operator-( const BdbTime& t ) const; 00203 00204 BdbTime& operator+=( const BdbDuration& d ); 00205 BdbTime operator+( const BdbDuration& d ) const; 00206 00207 BdbTime& operator-=( const BdbDuration& d ); 00208 BdbTime operator-( const BdbDuration& d ) const; 00209 00210 // Comparison operators 00211 bool operator==( const BdbTime& t ) const 00212 { 00213 return ( _gmtSec == t._gmtSec && _gmtNsec == t._gmtNsec ); 00214 } 00215 00216 bool operator!=( const BdbTime& t ) const 00217 { 00218 return !( *this == t ); 00219 } 00220 00221 bool operator<( const BdbTime& t ) const 00222 { 00223 return ( _gmtSec < t._gmtSec ) || 00224 ( _gmtSec == t._gmtSec && _gmtNsec < t._gmtNsec ); 00225 } 00226 00227 bool operator<=( const BdbTime& t ) const 00228 { 00229 return ( _gmtSec < t._gmtSec ) || 00230 ( _gmtSec == t._gmtSec && _gmtNsec <= t._gmtNsec ); 00231 } 00232 00233 bool operator>( const BdbTime& t ) const 00234 { 00235 return !( *this <= t ); 00236 } 00237 00238 bool operator>=( const BdbTime& t ) const 00239 { 00240 return !( *this < t ); 00241 } 00242 00243 // Selectors 00244 d_ULong getGmtSec( ) const { return _gmtSec; } 00245 d_ULong getGmtNsec( ) const { return _gmtNsec; } 00246 00247 /** 00248 * Extracts the value of the BdbTime as a POSIX.1b "struct timespec". 00249 * Returns 0 on success in analogy with POSIX.1b clock_gettime(). 00250 * WARNING: Must and will fail for valid BdbTime values that are more 00251 * than 2^31-1 seconds before the beginning of the POSIX 1970 epoch, 00252 * i.e., before around 1901.12.13 20:45:53 UTC. 00253 * 00254 * There are such times in the conditions database from early 00255 * SP production, before all times were renormalized into 1997+ space. 00256 */ 00257 int timeSpec( struct timespec* ts ) const; 00258 00259 /** 00260 * Extracts the value of the BdbTime as a POSIX "struct tm" broken-down 00261 * time. This requires the use of a time zone. In analogy with the 00262 * POSIX.1b gmtime_r() function, a pointer to a "struct tm" to receive 00263 * the data must be supplied -- so this function is thread-safe(*). 00264 * Following this analogy, the function returns the supplied pointer 00265 * on success, and 0 on failure. 00266 * 00267 * This function should work for all times in the BdbTime range. 00268 */ 00269 struct tm* tm( struct tm* stm, Zone zone ) const; 00270 00271 /** 00272 * Creates a string from the value of the BdbTime, based on a 00273 * specified format specification, as for POSIX strftime(), and on 00274 * a time zone. Note that this function does not provide a way 00275 * to embed the "nanoseconds" part of the BdbTime, since this is 00276 * not possible to express in a form recognized by strftime. 00277 * 00278 * The "%N" format specified does not appear to be used in the POSIX 00279 * definition of strftime. It's possible it could be hijacked in a 00280 * future upgrade. FIXME 00281 * 00282 * This function should work for all times in the BdbTime range. 00283 */ 00284 std::string asString( const char* fmt, Zone zone ) const; 00285 00286 // Deprecated: 00287 RWTime getRWTime( ) const { return RWTime( _gmtSec ); } 00288 00289 // Friends 00290 friend BdbTime operator+( const BdbDuration& d, const BdbTime& t ); 00291 friend ostream& operator<<( ostream& os, const BdbTime& t ); 00292 00293 private: 00294 00295 void renormalizeNanoseconds( ); 00296 00297 // Data members 00298 d_ULong _gmtSec; // number of seconds since 00:00:00 Jan. 1, 1901 UTC 00299 d_ULong _gmtNsec; // number of nanoseconds 00300 00301 public: 00302 // static interfaces: 00303 00304 /** 00305 * Constructs and returns a BdbTime representing the current time. 00306 * This interface, unlike the deprecated default constructor, returns 00307 * a BdbTime set to the full resolution available from clock_gettime(). 00308 * Note that this may vary between platforms and even operating 00309 * system versions. 00310 */ 00311 static BdbTime now(); 00312 00313 /** 00314 * Determines whether a string representing a date and a string 00315 * representing a time can be converted successfully to a date/time 00316 * in BdbTime format, i.e., in the unsigned 1901 epoch. 00317 * 00318 * Note that the strings "-Infinity" and "+Infinity" are not recognized 00319 * by this interface. Note also that 1901.01.01 00:00:00 UTC is not a 00320 * valid time; 00:00:01 is the first valid time. 00321 * 00322 * @param time Returned time value; modified only if parsing is successful. 00323 * @return Flag indicating whether parsing was successful. 00324 */ 00325 static bool parseTime( const std::string& sdate, const std::string& stime, 00326 Zone zone, 00327 BdbTime& time ); 00328 00329 /** 00330 * Determines whether a string representing a date and time can be 00331 * converted successfully to a date/time in BdbTime format, i.e., in 00332 * the unsigned 1901 epoch. 00333 * 00334 * Note that the strings "-Infinity" and "+Infinity" are recognized 00335 * by this interface, and produce BdbTime::minusInfinity and 00336 * BdbTime::plusInfinity values, respectively. 00337 * 00338 * Note also that 1901.01.01 00:00:00 UTC is not a treated as a 00339 * valid time; 00:00:01 is the first valid time. 00340 * 00341 * @param time Returned time value; modified only if parsing is successful. 00342 * @return Flag indicating whether parsing was successful. 00343 */ 00344 static bool parseTime( const std::string& sdatetime, 00345 Zone zone, 00346 BdbTime& time ); 00347 00348 // Static members 00349 static const BdbTime minusInfinity; 00350 static const BdbTime plusInfinity; 00351 // 00352 // Helper function to get time zones from strings 00353 // 00354 static const RWZone& getZone(const RWCString& zonename); 00355 00356 }; 00357 00358 00359 inline void 00360 BdbTime::renormalizeNanoseconds( ) 00361 { 00362 if ( _gmtNsec >= BdbTimeConst::nsecInASec ) { 00363 // carry nanoseconds over into seconds 00364 d_ULong extraSec = _gmtNsec / BdbTimeConst::nsecInASec; 00365 d_ULong remainNsec = _gmtNsec % BdbTimeConst::nsecInASec; 00366 _gmtSec += extraSec; 00367 _gmtNsec = remainNsec; 00368 } 00369 } 00370 00371 #endif 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382 00383 00384 00385 00386 00387
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002