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