TDatime.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TDatime.cxx 35923 2010-09-30 14:43:53Z brun $
00002 // Author: Rene Brun   05/01/95
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TDatime                                                              //
00015 //                                                                      //
00016 // This class stores the date and time with a precision of one second   //
00017 // in an unsigned 32 bit word (e.g. 950130 124559). The date is stored  //
00018 // with the origin being the 1st january 1995.                          //
00019 //                                                                      //
00020 // This class has no support for time zones. The time is assumed        //
00021 // to be in the local time of the machine where the object was created. //
00022 // As a result, TDatime objects are not portable between machines       //
00023 // operating in different time zones and unsuitable for storing the     //
00024 // date/time of data taking events and the like. If absolute time is    //
00025 // required, use TTimeStamp.                                            //
00026 //                                                                      //
00027 //////////////////////////////////////////////////////////////////////////
00028 
00029 #include "RConfig.h"
00030 
00031 #include <time.h>
00032 
00033 #ifdef WIN32
00034 #include "Windows4Root.h"
00035 #include <string.h>
00036 #endif
00037 
00038 #include "TBuffer.h"
00039 #include "Strlen.h"
00040 #include "TDatime.h"
00041 #include "TError.h"
00042 #include "Bytes.h"
00043 #include "TString.h"
00044 
00045 
00046 ClassImp(TDatime)
00047 
00048 //______________________________________________________________________________
00049 TDatime::TDatime()
00050 {
00051    // Create a TDatime and set it to the current time.
00052 
00053    Set();
00054 }
00055 
00056 //______________________________________________________________________________
00057 TDatime::TDatime(Int_t date, Int_t time)
00058 {
00059    // Create a TDatime and set it to the specified date and time.
00060    // See Set(Int_t, Int_t) about the date, time format.
00061 
00062    Set(date, time);
00063 }
00064 
00065 //______________________________________________________________________________
00066 TDatime::TDatime(Int_t year, Int_t month, Int_t day,
00067                  Int_t hour, Int_t min, Int_t sec)
00068 {
00069    // Create a TDatime and set it to the specified year, month,
00070    // day, time, hour, minute and second. See Set() about the format.
00071 
00072    Set(year, month, day, hour, min, sec);
00073 }
00074 
00075 //______________________________________________________________________________
00076 TDatime::TDatime(const char *sqlDateTime)
00077 {
00078    // Expects as input a string in SQL date/time compatible format, like:
00079    // yyyy-mm-dd hh:mm:ss.
00080 
00081    Set(sqlDateTime);
00082 }
00083 
00084 //______________________________________________________________________________
00085 Int_t TDatime::GetDayOfWeek() const
00086 {
00087    // Returns day of week, with Monday being day 1 and Sunday day 7.
00088 
00089    static TString weekDays[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
00090    TString wd = AsString();
00091    int  day;
00092    for (day = 0; day < 7; day++) {
00093       if (wd(0, 3) == weekDays[day])
00094          break;
00095    }
00096    return (day < 7) ? day+1: -1;
00097 }
00098 
00099 //______________________________________________________________________________
00100 const char *TDatime::AsString() const
00101 {
00102    // Return the date & time as a string (ctime() format).
00103    // Copy result because it points to a statically allocated string.
00104 
00105    time_t t = Convert();
00106    char *retStr = ctime(&t);
00107    if (retStr) {
00108       *(retStr + 24) = 0;
00109       return retStr;
00110    } else {
00111       static const char *defaulttime = "15/06/96";
00112       Error("TDatime::AsString", "could not get time string");
00113       return defaulttime;
00114    }
00115 }
00116 
00117 //______________________________________________________________________________
00118 const char *TDatime::AsString(char *out) const
00119 {
00120    // Return the date & time as a string (ctime() format).
00121    // Result is copied into out (and out is returned). Make sure
00122    // out can at least contain 26 characters. Thread safe.
00123 
00124    time_t t = Convert();
00125 #ifdef _REENTRANT
00126 #if defined(R__SOLARIS) && (_POSIX_C_SOURCE - 0 < 199506L)
00127    char *retStr = ctime_r(&t, out, 26);
00128 #else
00129    char *retStr = ctime_r(&t, out);
00130 #endif
00131 #else
00132    char *retStr = ctime(&t);
00133 #endif
00134    if (retStr) {
00135       *(retStr + 24) = 0;
00136 #ifndef _REENTRANT
00137       strcpy(out, retStr);
00138 #endif
00139       return retStr;
00140    } else {
00141       static const char *defaulttime = "15/06/96";
00142       strcpy(out, defaulttime);
00143       Error("TDatime::AsString", "could not get time string");
00144       return defaulttime;
00145    }
00146 }
00147 
00148 //______________________________________________________________________________
00149 const char *TDatime::AsSQLString() const
00150 {
00151    // Return the date & time in SQL compatible string format, like:
00152    // 1997-01-15 20:16:28. The returned string buffer is static and
00153    // will be reused.
00154 
00155    static char sqldate[20];
00156 
00157    UInt_t year  = fDatime>>26;
00158    UInt_t month = (fDatime<<6)>>28;
00159    UInt_t day   = (fDatime<<10)>>27;
00160    UInt_t hour  = (fDatime<<15)>>27;
00161    UInt_t min   = (fDatime<<20)>>26;
00162    UInt_t sec   = (fDatime<<26)>>26;
00163 
00164    snprintf(sqldate,20, "%04d-%02d-%02d %02d:%02d:%02d", (year+1995), month, day,
00165            hour, min, sec);
00166 
00167    return sqldate;
00168 }
00169 
00170 //______________________________________________________________________________
00171 UInt_t TDatime::Convert(Bool_t toGMT) const
00172 {
00173    // Convert fDatime from TDatime format to the standard time_t format.
00174    // If toGMT is true, the time offset of the current local time zone is
00175    // subtracted from the returned time_t. One use of such a non-standard time_t
00176    // value is to convert a TDatime object that contains local time to GMT,
00177    // as in this example:
00178    //
00179    // TDatime now;
00180    // now.Set(now.Convert(kTRUE));
00181    //
00182    // Caution: the time_t returned from Convert(kTRUE) is incompatible with
00183    // regular Unix time - it contains an artificial, locale-dependent offset.
00184 
00185    UInt_t year  = fDatime>>26;
00186    UInt_t month = (fDatime<<6)>>28;
00187    UInt_t day   = (fDatime<<10)>>27;
00188    UInt_t hour  = (fDatime<<15)>>27;
00189    UInt_t min   = (fDatime<<20)>>26;
00190    UInt_t sec   = (fDatime<<26)>>26;
00191 
00192    struct tm tp;
00193    tp.tm_year  = year+95;
00194    tp.tm_mon   = month-1;
00195    tp.tm_mday  = day;
00196    tp.tm_hour  = hour;
00197    tp.tm_min   = min;
00198    tp.tm_sec   = sec;
00199    tp.tm_isdst = -1;
00200 
00201    time_t t = mktime(&tp);
00202    if ((int)t == -1) {
00203       Error("TDatime::Convert", "error converting fDatime to time_t");
00204       return 0;
00205    }
00206    if (toGMT) {
00207 #ifdef _REENTRANT
00208       struct tm tg;
00209       struct tm *tgp = gmtime_r(&t, &tg);
00210 #else
00211       struct tm *tgp = gmtime(&t);
00212 #endif
00213       tgp->tm_isdst = -1;
00214       t  = mktime(tgp);
00215    }
00216    return (UInt_t)t;
00217 }
00218 
00219 //______________________________________________________________________________
00220 void TDatime::Copy(TDatime &datime) const
00221 {
00222    // Copy this to datime.
00223 
00224    datime.fDatime = fDatime;
00225 }
00226 
00227 //______________________________________________________________________________
00228 void TDatime::FillBuffer(char *&buffer)
00229 {
00230    // Encode Date/Time into buffer, used by I/O system.
00231 
00232    tobuf(buffer, fDatime);
00233 }
00234 
00235 //______________________________________________________________________________
00236 UInt_t TDatime::Get() const
00237 {
00238    // Return raw date/time as encoded by TDatime. Note, this value cannot
00239    // be used to e.g. calculate time differences, as it is an encoded value.
00240    // To calculate time differences use the Convert() method to get a time
00241    // in seconds and then subtract the values.
00242 
00243    return fDatime;
00244 }
00245 
00246 //______________________________________________________________________________
00247 Int_t TDatime::GetDate() const
00248 {
00249    // Return date in form of 19971224 (i.e. 24/12/1997)
00250 
00251    UInt_t year  = fDatime>>26;
00252    UInt_t month = (fDatime<<6)>>28;
00253    UInt_t day   = (fDatime<<10)>>27;
00254    return 10000*(year+1995) + 100*month + day;
00255 }
00256 
00257 //______________________________________________________________________________
00258 Int_t TDatime::GetTime() const
00259 {
00260    // Return time in form of 123623 (i.e. 12:36:23)
00261 
00262    UInt_t hour  = (fDatime<<15)>>27;
00263    UInt_t min   = (fDatime<<20)>>26;
00264    UInt_t sec   = (fDatime<<26)>>26;
00265    return 10000*hour + 100*min + sec;
00266 }
00267 
00268 //______________________________________________________________________________
00269 void TDatime::Print(Option_t *) const
00270 {
00271    // Print date and time.
00272 
00273    printf("Date/Time = %s\n", AsString());
00274 }
00275 
00276 //______________________________________________________________________________
00277 void TDatime::ReadBuffer(char *&buffer)
00278 {
00279    // Decode Date/Time from output buffer, used by I/O system.
00280 
00281    frombuf(buffer, &fDatime);
00282 }
00283 
00284 //______________________________________________________________________________
00285 void TDatime::Set()
00286 {
00287    // Set Date/Time to current time as reported by the system.
00288    // Date and Time are encoded into one single unsigned 32 bit word.
00289    // Date is stored with the origin being the 1st january 1995.
00290    // Time has 1 second precision.
00291 
00292 #ifndef WIN32
00293    time_t tloc   = time(0);
00294 #ifdef _REENTRANT
00295    struct tm tpa;
00296    struct tm *tp = localtime_r(&tloc, &tpa);
00297 #else
00298    struct tm *tp = localtime(&tloc);
00299 #endif
00300    UInt_t year   = tp->tm_year;
00301    UInt_t month  = tp->tm_mon + 1;
00302    UInt_t day    = tp->tm_mday;
00303    UInt_t hour   = tp->tm_hour;
00304    UInt_t min    = tp->tm_min;
00305    UInt_t sec    = tp->tm_sec;
00306 #else
00307    SYSTEMTIME tp;
00308    GetLocalTime(&tp);
00309    UInt_t year   = tp.wYear-1900;
00310    UInt_t month  = tp.wMonth;
00311    UInt_t day    = tp.wDay;
00312    UInt_t hour   = tp.wHour;
00313    UInt_t min    = tp.wMinute;
00314    UInt_t sec    = tp.wSecond;
00315 #endif
00316 
00317    fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
00318 }
00319 
00320 //______________________________________________________________________________
00321 void TDatime::Set(UInt_t tloc, Bool_t dosDate)
00322 {
00323    // The input arg is a time_t value returned by time() or a value
00324    // returned by Convert(). This value is the number of seconds since
00325    // the EPOCH (i.e. 00:00:00 on Jan 1m 1970). If dosDate is true then
00326    // the input is a dosDate value.
00327 
00328    UInt_t year, month, day, hour, min, sec;
00329 
00330    if (dosDate) {
00331       year  = ((tloc >> 25) & 0x7f) + 80;
00332       month = ((tloc >> 21) & 0xf);
00333       day   = (tloc >> 16) & 0x1f;
00334       hour  = (tloc >> 11) & 0x1f;
00335       min   = (tloc >> 5) & 0x3f;
00336       sec   = (tloc & 0x1f) * 2;
00337    } else {
00338       time_t t = (time_t) tloc;
00339 #ifdef _REENTRANT
00340       struct tm tpa;
00341       struct tm *tp = localtime_r(&t, &tpa);
00342 #else
00343       struct tm *tp = localtime(&t);
00344 #endif
00345       year   = tp->tm_year;
00346       month  = tp->tm_mon + 1;
00347       day    = tp->tm_mday;
00348       hour   = tp->tm_hour;
00349       min    = tp->tm_min;
00350       sec    = tp->tm_sec;
00351    }
00352 
00353    fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
00354 }
00355 
00356 //______________________________________________________________________________
00357 void TDatime::Set(Int_t date, Int_t time)
00358 {
00359    // Set date and time. Data must be in format 980418 or 19980418 and time in
00360    // 224512 (second precision). The date must
00361    // be >= 950101.
00362    // For years >= 2000, date can be given in the form 20001127 or 1001127
00363    // internally the date will be converted to 1001127
00364 
00365    if (date > 19000000) date -= 19000000;
00366    if (date < 950101) {
00367       Error("TDatime::Set", "year smaller than 1995");
00368       return;
00369    }
00370 
00371    Int_t year  = date/10000;
00372    Int_t month = (date-year*10000)/100;
00373    Int_t day   = date%100;
00374 
00375    Int_t hour, min, sec;
00376 
00377    hour = time/10000;
00378    min  = (time-hour*10000)/100;
00379    sec  = time%100;
00380 
00381    fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
00382 }
00383 
00384 //______________________________________________________________________________
00385 void TDatime::Set(Int_t year, Int_t month, Int_t day,
00386                   Int_t hour, Int_t min, Int_t sec)
00387 {
00388    // Set date and time. Year may be xx where 95 <= xx <= 158 (158 being 2058).
00389    // The year must be >= 1995.
00390 
00391    if (year < 159) year += 1900;
00392    if (year < 1995) {
00393       Error("TDatime::Set", "year must be >= 1995");
00394       return;
00395    }
00396 
00397    fDatime = (year-1995)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
00398 }
00399 
00400 //______________________________________________________________________________
00401 void TDatime::Set(const char* sqlDateTime)
00402 {
00403    // Expects as input a string in SQL date/time compatible format, like:
00404    // yyyy-mm-dd hh:mm:ss.
00405 
00406    Int_t yy, mm, dd, hh, mi, ss;
00407 
00408    if (sscanf(sqlDateTime, "%d-%d-%d %d:%d:%d", &yy, &mm, &dd, &hh, &mi, &ss) == 6)
00409       Set(yy, mm, dd, hh, mi, ss);
00410    else {
00411       Error("TDatime(sqlDatTime)", "input string not in right format, set"
00412             " to current date/time");
00413       Set();
00414    }
00415 }
00416 
00417 //______________________________________________________________________________
00418 void TDatime::Streamer(TBuffer &b)
00419 {
00420    // Stream a object of type TDatime.
00421 
00422    if (b.IsReading()) {
00423       b >> fDatime;
00424    } else {
00425       b << fDatime;
00426    }
00427 }
00428 
00429 //______________________________________________________________________________
00430 void TDatime::GetDateTime(UInt_t datetime, Int_t &date, Int_t &time)
00431 {
00432    // Static function that returns the date and time. The input is
00433    // in TDatime format (as obtained via TDatime::Get()).
00434    // Date is returned in the format 950223  February 23 1995.
00435    // Time is returned in the format 102459 10h 24m 59s.
00436 
00437    UInt_t year  = datetime>>26;
00438    UInt_t month = (datetime<<6)>>28;
00439    UInt_t day   = (datetime<<10)>>27;
00440    UInt_t hour  = (datetime<<15)>>27;
00441    UInt_t min   = (datetime<<20)>>26;
00442    UInt_t sec   = (datetime<<26)>>26;
00443    date         =  10000*(year+1995) + 100*month + day;
00444    time         =  10000*hour + 100*min + sec;
00445 }

Generated on Tue Jul 5 14:11:19 2011 for ROOT_528-00b_version by  doxygen 1.5.1