ROOT  6.06/09
Reference Guide
TDatime.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Rene Brun 05/01/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TDatime
13 This class stores the date and time with a precision of one second
14 in an unsigned 32 bit word (950130 124559).
15 The date is stored with the origin being the 1st January 1995.
16 
17 This class has no support for time zones. The time is assumed
18 to be in the local time of the machine where the object was created.
19 As a result, TDatime objects are not portable between machines
20 operating in different time zones and unsuitable for storing the
21 date/time of data taking events and the like. If absolute time is
22 required, use TTimeStamp.
23 */
24 
25 #include "RConfig.h"
26 
27 #include <time.h>
28 
29 #ifdef WIN32
30 #include "Windows4Root.h"
31 #include <string.h>
32 #endif
33 
34 #include "TBuffer.h"
35 #include "Strlen.h"
36 #include "TDatime.h"
37 #include "TError.h"
38 #include "Bytes.h"
39 #include "TString.h"
40 
41 
43 
44 ////////////////////////////////////////////////////////////////////////////////
45 /// Create a TDatime and set it to the current time.
46 
48 {
49  Set();
50 }
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Create a TDatime and set it to the specified date and time.
54 /// See Set(Int_t, Int_t) about the date, time format.
55 
57 {
58  Set(date, time);
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// Create a TDatime and set it to the specified year, month,
63 /// day, time, hour, minute and second. See Set() about the format.
64 
65 TDatime::TDatime(Int_t year, Int_t month, Int_t day,
66  Int_t hour, Int_t min, Int_t sec)
67 {
68  Set(year, month, day, hour, min, sec);
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Expects as input a string in SQL date/time compatible format, like:
73 /// yyyy-mm-dd hh:mm:ss.
74 
75 TDatime::TDatime(const char *sqlDateTime)
76 {
77  Set(sqlDateTime);
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// Returns day of week, with Monday being day 1 and Sunday day 7.
82 
84 {
85  static TString weekDays[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
86  TString wd = AsString();
87  int day;
88  for (day = 0; day < 7; day++) {
89  if (wd(0, 3) == weekDays[day])
90  break;
91  }
92  return (day < 7) ? day+1: -1;
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Return the date & time as a string (ctime() format).
97 /// Copy result because it points to a statically allocated string.
98 
99 const char *TDatime::AsString() const
100 {
101  time_t t = Convert();
102  char *retStr = ctime(&t);
103  if (retStr) {
104  *(retStr + 24) = 0;
105  return retStr;
106  } else {
107  static const char *defaulttime = "15/06/96";
108  Error("TDatime::AsString", "could not get time string");
109  return defaulttime;
110  }
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Return the date & time as a string (ctime() format).
115 /// Result is copied into out (and out is returned). Make sure
116 /// out can at least contain 26 characters. Thread safe.
117 
118 const char *TDatime::AsString(char *out) const
119 {
120  time_t t = Convert();
121 #ifdef _REENTRANT
122 #if defined(R__SOLARIS) && (_POSIX_C_SOURCE - 0 < 199506L)
123  char *retStr = ctime_r(&t, out, 26);
124 #else
125  char *retStr = ctime_r(&t, out);
126 #endif
127 #else
128  char *retStr = ctime(&t);
129 #endif
130  if (retStr) {
131  *(retStr + 24) = 0;
132 #ifndef _REENTRANT
133  strcpy(out, retStr);
134 #endif
135  return retStr;
136  } else {
137  static const char *defaulttime = "15/06/96";
138  strcpy(out, defaulttime);
139  Error("TDatime::AsString", "could not get time string");
140  return defaulttime;
141  }
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 /// Return the date & time in SQL compatible string format, like:
146 /// 1997-01-15 20:16:28. The returned string buffer is static and
147 /// will be reused.
148 
149 const char *TDatime::AsSQLString() const
150 {
151  static char sqldate[20];
152 
153  UInt_t year = fDatime>>26;
154  UInt_t month = (fDatime<<6)>>28;
155  UInt_t day = (fDatime<<10)>>27;
156  UInt_t hour = (fDatime<<15)>>27;
157  UInt_t min = (fDatime<<20)>>26;
158  UInt_t sec = (fDatime<<26)>>26;
159 
160  snprintf(sqldate,20, "%04d-%02d-%02d %02d:%02d:%02d", (year+1995), month, day,
161  hour, min, sec);
162 
163  return sqldate;
164 }
165 
166 ////////////////////////////////////////////////////////////////////////////////
167 /// Convert fDatime from TDatime format to the standard time_t format.
168 /// If toGMT is true, the time offset of the current local time zone is
169 /// subtracted from the returned time_t. One use of such a non-standard time_t
170 /// value is to convert a TDatime object that contains local time to GMT,
171 /// as in this example:
172 /// ~~~ {.cpp}
173 /// TDatime now;
174 /// now.Set(now.Convert(kTRUE));
175 /// ~~~
176 /// Caution: the time_t returned from Convert(kTRUE) is incompatible with
177 /// regular Unix time - it contains an artificial, locale-dependent offset.
178 
180 {
181  UInt_t year = fDatime>>26;
182  UInt_t month = (fDatime<<6)>>28;
183  UInt_t day = (fDatime<<10)>>27;
184  UInt_t hour = (fDatime<<15)>>27;
185  UInt_t min = (fDatime<<20)>>26;
186  UInt_t sec = (fDatime<<26)>>26;
187 
188  struct tm tp;
189  tp.tm_year = year+95;
190  tp.tm_mon = month-1;
191  tp.tm_mday = day;
192  tp.tm_hour = hour;
193  tp.tm_min = min;
194  tp.tm_sec = sec;
195  tp.tm_isdst = -1;
196 
197  time_t t = mktime(&tp);
198  if ((int)t == -1) {
199  Error("TDatime::Convert", "error converting fDatime to time_t");
200  return 0;
201  }
202  if (toGMT) {
203 #ifdef _REENTRANT
204  struct tm tg;
205  struct tm *tgp = gmtime_r(&t, &tg);
206 #else
207  struct tm *tgp = gmtime(&t);
208 #endif
209  tgp->tm_isdst = -1;
210  t = mktime(tgp);
211  }
212  return (UInt_t)t;
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Copy this to datime.
217 
218 void TDatime::Copy(TDatime &datime) const
219 {
220  datime.fDatime = fDatime;
221 }
222 
223 ////////////////////////////////////////////////////////////////////////////////
224 /// Encode Date/Time into buffer, used by I/O system.
225 
226 void TDatime::FillBuffer(char *&buffer)
227 {
228  tobuf(buffer, fDatime);
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 /// Return raw date/time as encoded by TDatime. Note, this value cannot
233 /// be used to e.g. calculate time differences, as it is an encoded value.
234 /// To calculate time differences use the Convert() method to get a time
235 /// in seconds and then subtract the values.
236 
238 {
239  return fDatime;
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Return date in form of 19971224 (i.e. 24/12/1997)
244 
246 {
247  UInt_t year = fDatime>>26;
248  UInt_t month = (fDatime<<6)>>28;
249  UInt_t day = (fDatime<<10)>>27;
250  return 10000*(year+1995) + 100*month + day;
251 }
252 
253 ////////////////////////////////////////////////////////////////////////////////
254 /// Return time in form of 123623 (i.e. 12:36:23)
255 
257 {
258  UInt_t hour = (fDatime<<15)>>27;
259  UInt_t min = (fDatime<<20)>>26;
260  UInt_t sec = (fDatime<<26)>>26;
261  return 10000*hour + 100*min + sec;
262 }
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// Print date and time.
266 
268 {
269  printf("Date/Time = %s\n", AsString());
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// Decode Date/Time from output buffer, used by I/O system.
274 
275 void TDatime::ReadBuffer(char *&buffer)
276 {
277  frombuf(buffer, &fDatime);
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Set Date/Time to current time as reported by the system.
282 /// Date and Time are encoded into one single unsigned 32 bit word.
283 /// Date is stored with the origin being the 1st January 1995.
284 /// Time has 1 second precision.
285 
287 {
288 #ifndef WIN32
289  time_t tloc = time(0);
290 #ifdef _REENTRANT
291  struct tm tpa;
292  struct tm *tp = localtime_r(&tloc, &tpa);
293 #else
294  struct tm *tp = localtime(&tloc);
295 #endif
296  UInt_t year = tp->tm_year;
297  UInt_t month = tp->tm_mon + 1;
298  UInt_t day = tp->tm_mday;
299  UInt_t hour = tp->tm_hour;
300  UInt_t min = tp->tm_min;
301  UInt_t sec = tp->tm_sec;
302 #else
303  SYSTEMTIME tp;
304  GetLocalTime(&tp);
305  UInt_t year = tp.wYear-1900;
306  UInt_t month = tp.wMonth;
307  UInt_t day = tp.wDay;
308  UInt_t hour = tp.wHour;
309  UInt_t min = tp.wMinute;
310  UInt_t sec = tp.wSecond;
311 #endif
312 
313  fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// The input arg is a time_t value returned by time() or a value
318 /// returned by Convert(). This value is the number of seconds since
319 /// the EPOCH (i.e. 00:00:00 on Jan 1m 1970). If dosDate is true then
320 /// the input is a dosDate value.
321 
322 void TDatime::Set(UInt_t tloc, Bool_t dosDate)
323 {
324  UInt_t year, month, day, hour, min, sec;
325 
326  if (dosDate) {
327  year = ((tloc >> 25) & 0x7f) + 80;
328  month = ((tloc >> 21) & 0xf);
329  day = (tloc >> 16) & 0x1f;
330  hour = (tloc >> 11) & 0x1f;
331  min = (tloc >> 5) & 0x3f;
332  sec = (tloc & 0x1f) * 2;
333  } else {
334  time_t t = (time_t) tloc;
335 #ifdef _REENTRANT
336  struct tm tpa;
337  struct tm *tp = localtime_r(&t, &tpa);
338 #else
339  struct tm *tp = localtime(&t);
340 #endif
341  year = tp->tm_year;
342  month = tp->tm_mon + 1;
343  day = tp->tm_mday;
344  hour = tp->tm_hour;
345  min = tp->tm_min;
346  sec = tp->tm_sec;
347  }
348 
349  fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
350 }
351 
352 ////////////////////////////////////////////////////////////////////////////////
353 /// Set date and time. Data must be in format 980418 or 19980418 and time in
354 /// 224512 (second precision). The date must
355 /// be >= 950101.
356 ///
357 /// For years >= 2000, date can be given in the form 20001127 or 1001127
358 /// internally the date will be converted to 1001127
359 
360 void TDatime::Set(Int_t date, Int_t time)
361 {
362  if (date > 19000000) date -= 19000000;
363  if (date < 950101) {
364  Error("TDatime::Set", "year smaller than 1995");
365  return;
366  }
367 
368  Int_t year = date/10000;
369  Int_t month = (date-year*10000)/100;
370  Int_t day = date%100;
371 
372  Int_t hour, min, sec;
373 
374  hour = time/10000;
375  min = (time-hour*10000)/100;
376  sec = time%100;
377 
378  fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
379 }
380 
381 ////////////////////////////////////////////////////////////////////////////////
382 /// Set date and time. Year may be xx where 95 <= xx <= 158 (158 being 2058).
383 /// The year must be >= 1995.
384 
385 void TDatime::Set(Int_t year, Int_t month, Int_t day,
386  Int_t hour, Int_t min, Int_t sec)
387 {
388  if (year < 159) year += 1900;
389  if (year < 1995) {
390  Error("TDatime::Set", "year must be >= 1995");
391  return;
392  }
393 
394  fDatime = (year-1995)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
395 }
396 
397 ////////////////////////////////////////////////////////////////////////////////
398 /// Expects as input a string in SQL date/time compatible format, like:
399 /// yyyy-mm-dd hh:mm:ss.
400 
401 void TDatime::Set(const char* sqlDateTime)
402 {
403  Int_t yy, mm, dd, hh, mi, ss;
404 
405  if (sscanf(sqlDateTime, "%d-%d-%d %d:%d:%d", &yy, &mm, &dd, &hh, &mi, &ss) == 6)
406  Set(yy, mm, dd, hh, mi, ss);
407  else {
408  Error("TDatime(sqlDatTime)", "input string not in right format, set"
409  " to current date/time");
410  Set();
411  }
412 }
413 
414 ////////////////////////////////////////////////////////////////////////////////
415 /// Stream a object of type TDatime.
416 
417 void TDatime::Streamer(TBuffer &b)
418 {
419  if (b.IsReading()) {
420  b >> fDatime;
421  } else {
422  b << fDatime;
423  }
424 }
425 
426 ////////////////////////////////////////////////////////////////////////////////
427 /// Static function that returns the date and time. The input is
428 /// in TDatime format (as obtained via TDatime::Get()).
429 /// Date is returned in the format 950223 February 23 1995.
430 /// Time is returned in the format 102459 10h 24m 59s.
431 
432 void TDatime::GetDateTime(UInt_t datetime, Int_t &date, Int_t &time)
433 {
434  UInt_t year = datetime>>26;
435  UInt_t month = (datetime<<6)>>28;
436  UInt_t day = (datetime<<10)>>27;
437  UInt_t hour = (datetime<<15)>>27;
438  UInt_t min = (datetime<<20)>>26;
439  UInt_t sec = (datetime<<26)>>26;
440  date = 10000*(year+1995) + 100*month + day;
441  time = 10000*hour + 100*min + sec;
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Print a TDatime at the prompt.
446 
447 std::string cling::printValue(const TDatime &val) {
448  char buf[30];
449  return std::string(val.AsString(buf));
450 }
void frombuf(char *&buf, Bool_t *x)
Definition: Bytes.h:282
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
UInt_t Convert(Bool_t toGMT=kFALSE) const
Convert fDatime from TDatime format to the standard time_t format.
Definition: TDatime.cxx:179
void Set()
Set Date/Time to current time as reported by the system.
Definition: TDatime.cxx:286
void Copy(TDatime &datime) const
Copy this to datime.
Definition: TDatime.cxx:218
Bool_t IsReading() const
Definition: TBuffer.h:81
const char Option_t
Definition: RtypesCore.h:62
UInt_t Get() const
Return raw date/time as encoded by TDatime.
Definition: TDatime.cxx:237
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void ReadBuffer(char *&buffer)
Decode Date/Time from output buffer, used by I/O system.
Definition: TDatime.cxx:275
ClassImp(TDatime) TDatime
Create a TDatime and set it to the current time.
Definition: TDatime.cxx:42
Int_t GetTime() const
Return time in form of 123623 (i.e. 12:36:23)
Definition: TDatime.cxx:256
Int_t GetDayOfWeek() const
Returns day of week, with Monday being day 1 and Sunday day 7.
Definition: TDatime.cxx:83
static void GetDateTime(UInt_t datetime, Int_t &date, Int_t &time)
Static function that returns the date and time.
Definition: TDatime.cxx:432
void FillBuffer(char *&buffer)
Encode Date/Time into buffer, used by I/O system.
Definition: TDatime.cxx:226
void tobuf(char *&buf, Bool_t x)
Definition: Bytes.h:59
void Error(const char *location, const char *msgfmt,...)
char * out
Definition: TBase64.cxx:29
std::string printValue(const TDatime &val)
Print a TDatime at the prompt.
Definition: TDatime.cxx:447
unsigned int UInt_t
Definition: RtypesCore.h:42
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void Print(Option_t *option="") const
Print date and time.
Definition: TDatime.cxx:267
Int_t GetDate() const
Return date in form of 19971224 (i.e. 24/12/1997)
Definition: TDatime.cxx:245
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition: TDatime.cxx:99
UInt_t fDatime
Definition: TDatime.h:44
const char * AsSQLString() const
Return the date & time in SQL compatible string format, like: 1997-01-15 20:16:28.
Definition: TDatime.cxx:149
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:39