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