TVldTimeStamp.hxx

Go to the documentation of this file.
00001 /**
00002  * \class TVldTimeStamp
00003  *
00004  * \ingroup Validity
00005  *
00006  * \brief Encapsulate the seconds and ns since EPOCH
00007  *
00008  * This extends (and isolates) struct timespec
00009  *
00010  *    struct timespec
00011  *       {
00012  *          time_t   tv_sec;   // seconds
00013  *          long     tv_nsec;  // nanoseconds
00014  *       }
00015  *    time_t seconds is relative to Jan 1, 1970 00:00:00 UTC
00016  *
00017  * Due to ROOT/CINT limitations TVldTimeStamp does not explicitly
00018  * hold a timespec struct; attempting to do so means the Streamer
00019  * must be hand written.  Instead we have chosen to simply contain
00020  * similar fields within the private area of this class.
00021  *
00022  * \note
00023  *       the use of time_t (and its default implementation as a 32 int)
00024  *       implies overflow conditions occurs somewhere around
00025  *       Jan 18, 19:14:07, 2038.
00026  *       If this experiment is still going when it becomes significant
00027  *       someone will have to deal with it.
00028  *
00029 
00030  *
00031  * \author (last to touch it) $Author: finch $
00032  *
00033  * \version $Revision: 1.2 $
00034  *
00035  * \date $Date: 2011/06/09 14:44:29 $
00036  *
00037  * Contact: R. Hatcher
00038  *
00039  * Created on: Wed Apr 13 17:53:23 2005
00040  *
00041  * Author:  R. Hatcher 2000.04.19
00042  *          R. Hatcher 2000.12.20 -- convert from TDatime to struct timespec
00043  *
00044  * $Id: TVldTimeStamp.hxx,v 1.2 2011/06/09 14:44:29 finch Exp $
00045  *
00046  */
00047 
00048 
00049 #ifndef VLDTIMESTAMP_H
00050 #define VLDTIMESTAMP_H
00051 
00052 // TTimeStamp is the ROOT adopted version of this class
00053 // so it has all the necessary includes
00054 #include "TTimeStamp.h"
00055 
00056 // make the TVldTimeStamp cout'able
00057 #include <iosfwd>
00058 
00059 
00060 class TVldTimeStamp;
00061 
00062 class TVldTimeStamp {
00063 
00064    friend Bool_t operator==(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs);
00065    friend Bool_t operator!=(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs);
00066    friend Bool_t operator< (const TVldTimeStamp &lhs, const TVldTimeStamp &rhs);
00067    friend Bool_t operator<=(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs);
00068    friend Bool_t operator> (const TVldTimeStamp &lhs, const TVldTimeStamp &rhs);
00069    friend Bool_t operator>=(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs);
00070 
00071    friend TVldTimeStamp operator- (const TVldTimeStamp &lhs, const TVldTimeStamp &rhs);
00072 
00073  public:
00074 
00075    /// Static method to return the "beginning of time" (start of Unix EPOCH)
00076    static TVldTimeStamp GetBOT();
00077 
00078    /// Static method to return the "end of time" which is sometime in
00079    /// the future and near or at the limit of TVldTimeStamp's ability
00080    /// to hold large times.
00081    static TVldTimeStamp GetEOT();
00082 
00083    /// Static method to return the "negative beginning of time", i.e. the
00084    /// earliest time prior to start of Unix EPOCH which is negative seconds.
00085    static TVldTimeStamp GetNBOT();
00086 
00087    /// Empty ctor (builds current time with nsec field filled as best possible)
00088    TVldTimeStamp();
00089 
00090    /// Copy
00091    TVldTimeStamp(const TVldTimeStamp &source)
00092      : fSec(source.fSec), 
00093      fNanoSec(source.fNanoSec) { }
00094 
00095    /// Assignment
00096    TVldTimeStamp& operator=(const TVldTimeStamp &source)
00097       { if (this != &source) {fSec = source.fSec; fNanoSec = source.fNanoSec;}
00098       return *this; }
00099 
00100    /// Construction from timespec struct
00101    TVldTimeStamp(const timespec_t &ts)
00102      : fSec(ts.tv_sec), fNanoSec(ts.tv_nsec)
00103       { NormalizeNanoSec(); }
00104 
00105    /// Construction from time_t and separate nsec
00106    TVldTimeStamp(const time_t &t, const Int_t nsec)
00107      : fSec(t), fNanoSec(nsec)
00108       { NormalizeNanoSec(); }
00109 
00110    /// Create a TVldTimeStamp and set it to the specified year, month,
00111    /// day, time, hour, minute, second and nanosec.
00112    /// If !isUTC then it is assumed to be the standard local time zone.
00113    ///
00114    /// If local time is PST then one can use
00115    ///
00116    ///    TVldTimeStamp(year,month,day,hour,min,sec,nsec,kFALSE,0);
00117    ///
00118    /// or
00119    ///
00120    ///    Int_t secOffset = 8*60*60;
00121    ///    TVldTimeStamp(year,month,day,hour,min,sec,nsec,kTRUE,8*60*60);
00122    TVldTimeStamp(UInt_t year, UInt_t month,
00123                 UInt_t day,  UInt_t hour,
00124                 UInt_t min,  UInt_t sec,
00125                 UInt_t nsec=0, 
00126                 Bool_t isUTC=kTRUE, Int_t secOffset=0);
00127 
00128    /// Create a TVldTimeStamp and set it to the specified date, time, nanosec.
00129    /// If !isUTC then it is assumed to be the standard local time zone.
00130    TVldTimeStamp(UInt_t date, UInt_t time, UInt_t nsec, 
00131                 Bool_t isUTC=kTRUE, Int_t secOffset=0);
00132 
00133    /** Create a TVldTimeStamp using double precision floating point
00134     * seconds from the EPOCH.
00135     *
00136     * \warning This will truncate precision to no better than about 1
00137     * microsecond.  Do not use this constructor for timestamps that
00138     * are expected to be more precise!
00139     */
00140    TVldTimeStamp(Double_t seconds)
00141      : fSec((Int_t)seconds), fNanoSec((Int_t)((seconds-fSec)*1.0e9))
00142      { NormalizeNanoSec(); }
00143 
00144 
00145    virtual ~TVldTimeStamp();
00146 
00147    /** Implicitly convert a TVldTimeStamp to a double.
00148     *
00149     * \warning This will truncate precision to no better than about 1
00150     * microsecond.  Do not compare/subtract TVldTimeStamps that have
00151     * been converted to doubles if you require the full nanosecond
00152     * precision!
00153     */
00154    operator double() const { return fSec + 1.0e-9 * fNanoSec; }
00155 
00156 
00157    /// Get timestamp as a timespec_t
00158    timespec_t     GetTimeSpec() const
00159       { timespec_t value = {fSec,fNanoSec}; return value; }
00160 
00161    /// Get (integral) seconds after the EPOCH
00162    time_t         GetSec(void) const { return fSec;}
00163    /// Get nanoseconds after the second
00164    Int_t          GetNanoSec(void) const { return fNanoSec; }
00165    
00166    /// Get time from the epoch in seconds
00167    Double_t GetSeconds(void) const { return fSec+(fNanoSec/1.0e9); }
00168     
00169   /** Return the date & time as a string.
00170    *
00171    * Result is pointer to a statically allocated string.
00172    * User should copy this into their own buffer before calling
00173    * this method again.  This is somewhat mitigated
00174    * by use of a circular buffer of strings.
00175    *
00176    * Option "l" returns it in local zone format
00177    * (can be applied to default or compact format).
00178    *
00179    * Default format is RFC822 compliant:
00180    *   "Mon, 02 Jan 2001 18:11:12 +0000 (GMT) +999999999 nsec"
00181    *   "Mon, 02 Jan 2001 10:11:12 -0800 (PST) +999999999 nsec"
00182    *
00183    * Option "c" compact is (almost) ISO 8601 compliant:
00184    *   "2001-01-02 18:11:12.9999999999Z"
00185    *   "2001-01-02 10:11:12.9999999999-0800"  if PST
00186    *      * uses "-" as date separator as specified in ISO 8601
00187    *      * uses "." rather than preferred "," for decimal separator
00188    *      * -HHMM is the difference between local and UTC (if behind, + if ahead).
00189    *   The "-HHMM" is replaced with "Z" if given as UTC.
00190    *   To be strictly conforming it should use "T" instead of the
00191    *   blank separating the date and time.
00192    *
00193    * Option "2" returns as {sec,nsec} integers.
00194    *
00195    * Option "s" returns "2001-01-02 18:11:12" with an implied UTC,
00196    * overrides "l" option.
00197    *
00198    * Internally uses a circular list of buffers to avoid problems
00199    * using AsString multiple times in a single statement.
00200    */
00201    const char    *AsString(Option_t *option="") const;
00202    void           Copy(TVldTimeStamp &vldts) const;
00203 
00204    /// Return date in form of 19971224 (i.e. 24/12/1997),
00205    /// if non-zero pointers supplied for year, month, day fill those as well
00206    Int_t          GetDate(Bool_t inUTC=kTRUE, Int_t secOffset=0,
00207                           UInt_t *year=0, UInt_t *month=0,
00208                           UInt_t *day=0) const;
00209 
00210    /// Return time in form of 123623 (i.e. 12:36:23),
00211    /// if non-zero pointers supplied for hour, min, sec fill those as well
00212    Int_t          GetTime(Bool_t inUTC=kTRUE, Int_t secOffset=0,
00213                           UInt_t* hour=0, UInt_t* min=0, 
00214                           UInt_t* sec=0) const;
00215 
00216    void           Add(const TVldTimeStamp& offset);
00217    void           Add(Double_t seconds);
00218 
00219    void           Print(Option_t *option="") const;
00220 
00221    // Utility functions
00222 
00223    /// Static method returning local (current) time zone offset from UTC.
00224    /// This is the difference in seconds between UTC and local standard time.
00225    static Int_t   GetZoneOffset();
00226   /**
00227    * Equivalent of standard routine "mktime" but
00228    * using the assumption that tm struct is filled with UTC, not local, time.
00229    *
00230    * This version *ISN'T* configured to handle every possible
00231    * weirdness of out-of-range values in the case of normalizing
00232    * the tm struct.
00233    *
00234    * This version *DOESN'T* correctly handle values that can't be
00235    * fit into a time_t (i.e. beyond year 2038-01-18 19:14:07, or
00236    * before the start of Epoch). */
00237    static time_t  MktimeFromUTC(tm_t* tmstruct);
00238    /// Is the given year a leap year.
00239    static Bool_t  IsLeapYear(Int_t year);
00240    /// Print out the "tm" structure:
00241    static void    DumpTMStruct(const tm_t& tmstruct);
00242 
00243  private:
00244 
00245    void           Set();
00246    void           Set(Int_t year, Int_t month, Int_t day,
00247                       Int_t hour, Int_t min, Int_t sec, 
00248                       Int_t nsec, Bool_t isUTC, Int_t secOffset);
00249    void           Set(Int_t date, Int_t time, Int_t nsec,
00250                       Bool_t isUTC, Int_t secOffset);
00251    void           NormalizeNanoSec();
00252 
00253    // Data members:
00254    // similar fields to struct timespec
00255    // use ROOT versions to "know" that they are platform consistent
00256    // 32-bit integers to avoid IO confusion.
00257    Int_t  fSec;
00258    Int_t  fNanoSec;
00259 
00260    ClassDef(TVldTimeStamp,2)
00261 };
00262 std::ostream& operator<<(std::ostream& os, const TVldTimeStamp& vldts);
00263 
00264 #ifndef __CINT__
00265 //=============================================================================
00266 // Implementation details -- inlines need to be hidden from CINT
00267 //=============================================================================
00268 
00269 
00270 
00271 inline Bool_t operator==(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs)
00272    { return lhs.fSec  == rhs.fSec && 
00273             lhs.fNanoSec == rhs.fNanoSec; }
00274 
00275 inline Bool_t operator!=(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs)
00276    { return lhs.fSec  != rhs.fSec ||
00277             lhs.fNanoSec != rhs.fNanoSec; }
00278 
00279 inline Bool_t operator<(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs)
00280    { return lhs.fSec  < rhs.fSec ||
00281              ( lhs.fSec  == rhs.fSec &&
00282                lhs.fNanoSec <  rhs.fNanoSec   ); }
00283 
00284 inline Bool_t operator<=(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs)
00285    { return lhs.fSec  < rhs.fSec ||
00286              ( lhs.fSec  == rhs.fSec &&
00287                lhs.fNanoSec <= rhs.fNanoSec   ); }
00288 
00289 inline Bool_t operator>(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs)
00290    { return lhs.fSec  > rhs.fSec ||
00291              ( lhs.fSec  == rhs.fSec &&
00292                lhs.fNanoSec >  rhs.fNanoSec   ); }
00293 
00294 inline Bool_t operator>=(const TVldTimeStamp &lhs, const TVldTimeStamp &rhs)
00295    { return lhs.fSec  > rhs.fSec ||
00296              ( lhs.fSec  == rhs.fSec &&
00297                lhs.fNanoSec >= rhs.fNanoSec   ); }
00298 
00299 inline TVldTimeStamp operator-(const TVldTimeStamp& lhs, const TVldTimeStamp& rhs)
00300 {
00301     return TVldTimeStamp(lhs.GetSec()     - rhs.GetSec(),
00302                         lhs.GetNanoSec() - rhs.GetNanoSec());
00303 }
00304 
00305 
00306 #endif /* __CINT__ */
00307 #endif // VLDTIMESTAMP_H

Generated on 11 Aug 2013 for SKDatabase by  doxygen 1.6.1