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