Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 <cstring>
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
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
72
73////////////////////////////////////////////////////////////////////////////////
74/// Expects as input a string in SQL date/time compatible format, like:
75/// yyyy-mm-dd hh:mm:ss.
76
78{
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" };
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#ifndef WIN32
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#ifdef WIN32
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;
159 UInt_t min = (fDatime<<20)>>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;
187 UInt_t min = (fDatime<<20)>>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#ifndef WIN32
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
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;
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{
261 UInt_t min = (fDatime<<20)>>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(nullptr);
292 struct tm tpa;
293 struct tm *tp = localtime_r(&tloc, &tpa);
294 UInt_t year = tp->tm_year;
295 UInt_t month = tp->tm_mon + 1;
296 UInt_t day = tp->tm_mday;
297 UInt_t hour = tp->tm_hour;
298 UInt_t min = tp->tm_min;
299 UInt_t sec = tp->tm_sec;
300#else
303 UInt_t year = tp.wYear-1900;
304 UInt_t month = tp.wMonth;
305 UInt_t day = tp.wDay;
306 UInt_t hour = tp.wHour;
307 UInt_t min = tp.wMinute;
308 UInt_t sec = tp.wSecond;
309#endif
310
311 fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
312}
313
314////////////////////////////////////////////////////////////////////////////////
315/// The input arg is a time_t value returned by time() or a value
316/// returned by Convert(). This value is the number of seconds since
317/// the EPOCH (i.e. 00:00:00 on Jan 1m 1970). If dosDate is true then
318/// the input is a dosDate value.
319
321{
322 UInt_t year, month, day, hour, min, sec;
323
324 if (dosDate) {
325 year = ((tloc >> 25) & 0x7f) + 80;
326 month = ((tloc >> 21) & 0xf);
327 day = (tloc >> 16) & 0x1f;
328 hour = (tloc >> 11) & 0x1f;
329 min = (tloc >> 5) & 0x3f;
330 sec = (tloc & 0x1f) * 2;
331 } else {
332 time_t t = (time_t) tloc;
333#ifndef WIN32
334 struct tm tpa;
335 struct tm *tp = localtime_r(&t, &tpa);
336#else
337 struct tm *tp = localtime(&t);
338#endif
339 year = tp->tm_year;
340 month = tp->tm_mon + 1;
341 day = tp->tm_mday;
342 hour = tp->tm_hour;
343 min = tp->tm_min;
344 sec = tp->tm_sec;
345 }
346
347 fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
348}
349
350////////////////////////////////////////////////////////////////////////////////
351/// Set date and time. Data must be in format 980418 or 19980418 and time in
352/// 224512 (second precision). The date must
353/// be >= 950101.
354///
355/// For years >= 2000, date can be given in the form 20001127 or 1001127
356/// internally the date will be converted to 1001127
357
359{
360 if (date > 19000000) date -= 19000000;
361 if (date < 950101) {
362 Error("TDatime::Set", "year smaller than 1995");
363 return;
364 }
365
366 Int_t year = date/10000;
367 Int_t month = (date-year*10000)/100;
368 Int_t day = date%100;
369
370 Int_t hour, min, sec;
371
372 hour = time/10000;
373 min = (time-hour*10000)/100;
374 sec = time%100;
375
376 fDatime = (year-95)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
377}
378
379////////////////////////////////////////////////////////////////////////////////
380/// Set date and time. Year may be xx where 95 <= xx <= 158 (158 being 2058).
381/// The year must be >= 1995.
382
384 Int_t hour, Int_t min, Int_t sec)
385{
386 if (year < 159) year += 1900;
387 if (year < 1995) {
388 Error("TDatime::Set", "year must be >= 1995");
389 return;
390 }
391
392 fDatime = (year-1995)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec;
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Expects as input a string in SQL date/time compatible format, like:
397/// yyyy-mm-dd hh:mm:ss.
398
399void TDatime::Set(const char* sqlDateTime)
400{
401 Int_t yy, mm, dd, hh, mi, ss;
402
403 if (sscanf(sqlDateTime, "%d-%d-%d %d:%d:%d", &yy, &mm, &dd, &hh, &mi, &ss) == 6)
404 Set(yy, mm, dd, hh, mi, ss);
405 else {
406 Error("TDatime(sqlDatTime)", "input string not in right format, set"
407 " to current date/time");
408 Set();
409 }
410}
411
412////////////////////////////////////////////////////////////////////////////////
413/// Stream a object of type TDatime.
414
416{
417 if (b.IsReading()) {
418 b >> fDatime;
419 } else {
420 b << fDatime;
421 }
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// Static function that returns the date and time. The input is
426/// in TDatime format (as obtained via TDatime::Get()).
427/// Date is returned in the format 950223 February 23 1995.
428/// Time is returned in the format 102459 10h 24m 59s.
429
431{
432 UInt_t year = datetime>>26;
436 UInt_t min = (datetime<<20)>>26;
438 date = 10000*(year+1995) + 100*month + day;
439 time = 10000*hour + 100*min + sec;
440}
441
442////////////////////////////////////////////////////////////////////////////////
443/// Static function that returns the global day number from date. The input is
444/// in TDatime format yyyymmdd (as obtained via TDatime::GetDate()).
445/// This algorithm is only accurate for dates later than October 1582
446/// (earliest date on Gregorian calendar).
447
449{
450 // date is in form yyyymmdd
451 Int_t dy = date / 10000;
452 Int_t dm = (date - dy*10000)/100;
453 Int_t dd = (date - dy*10000 - dm*100);
454
455 Int_t m = (dm + 9)%12; // mar=0, feb=11
456 Int_t y = dy - m/10; // if Jan/Feb, year--
457 return y*365 + y/4 - y/100 + y/400 + (m*306 + 5)/10 + (dd - 1);
458}
459
460////////////////////////////////////////////////////////////////////////////////
461/// Static function that returns the date from the global day number.
462/// The output is in TDatime yyyymmdd format (as obtained via
463/// TDatime::GetDate()).
464
466{
467 Long64_t ld = day;
468 Int_t y = int((10000*ld + 14780)/3652425);
469 Int_t ddd = day - (y*365 + y/4 - y/100 + y/400);
470 if (ddd < 0) {
471 y--;
472 ddd = day - (y*365 + y/4 - y/100 + y/400);
473 }
474 Int_t mi = (52 + 100*ddd)/3060;
475 Int_t dy = y + (mi + 2)/12;
476 Int_t dm = (mi + 2)%12 + 1;
477 Int_t dd = ddd - (mi*306 + 5)/10 + 1;
478
479 return dy*10000 + dm*100 + dd;
480}
481
482////////////////////////////////////////////////////////////////////////////////
483/// Static function that returns the global day number from date. The input is
484/// in TDatime format yyyymmdd (as obtained via TDatime::GetDate()).
485/// This algorithm is only accurate for dates later than October 1582
486/// (earliest date on Gregorian calendar) and it is checked that the date
487/// is larger than 15821001 and conversion is correct.
488/// In case of conversion failure 0 is returned.
489/// No need to use when you know dates are larger than October 1582.
490
492{
493 static Int_t calstart = 0;
494 if (!calstart)
497 if (d < calstart)
498 ::Warning("TDatime::GetLegalGlobalDayFromDate", "dates before Oct. 1582 are inaccurate.");
500 if (dte != date) {
501 ::Error("TDatime::GetLegalGlobalDayFromDate", "illegal date %d", dte);
502 return 0;
503 }
504 return d;
505}
506
507////////////////////////////////////////////////////////////////////////////////
508/// Print a TDatime at the prompt.
509
510std::string cling::printValue(const TDatime* val) {
511 char buf[30];
512 return std::string(val->AsString(buf));
513}
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
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
#define snprintf
Definition civetweb.c:1579
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:448
static Int_t GetDateFromGlobalDay(Int_t day)
Static function that returns the date from the global day number.
Definition TDatime.cxx:465
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:491
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
virtual void Streamer(TBuffer &)
Stream a object of type TDatime.
Definition TDatime.cxx:415
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:430
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:138
Double_t y[n]
Definition legend1.C:17
TMarker m
Definition textangle.C:8