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