Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

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