Bug of TDatime

Dear Expert

I meet a problem when I run my code, so I checked all the output and find a problem about the e TDatime. I tried some simple codes here:

root [0] TDatime t root [1] t.Set(3.11266e+09,false) root [2] t.GetDay() (const Int_t)20 root [3] t.GetMonth() (const Int_t)8 root [4] t.GetYear() (const Int_t)2004 root [5] t.Set(2.32275e+09,false) root [6] t.GetDay() (const Int_t)9 root [7] t.GetMonth() (const Int_t)8 root [8] t.GetYear() (const Int_t)2043
Apparently the first value is larger than the second one, but the GetYear() out put is smaller than second one. Did any of you meet this problem before?

Hi,

At least on Linux systems TDatime uses GNU’s time_t internally and you might have just run into the Year2038 problem (en.wikipedia.org/wiki/Year_2038_problem). I believe GNU’s time_t uses ints to store the number of seconds since the epoch.

The best you can do is to store your dates in a larger type (like unsigned int or long long unsigned int) instead of using TDatime and you should be covered for either the next 100 years or til the heat death of the universe.

[quote=“honk”]Hi,

At least on Linux systems TDatime uses GNU’s time_t internally and you might have just run into the Year2038 problem (en.wikipedia.org/wiki/Year_2038_problem). I believe GNU’s time_t uses ints to store the number of seconds since the epoch.

The best you can do is to store your dates in a larger type (like unsigned int or long long unsigned int) instead of using TDatime and you should be covered for either the next 100 years or til the heat death of the universe.[/quote]
Hi, thank you very much! I tried the ULong_t, but still with wrong time.

root [0] TDatime t
root [1] ULong_t time = 3.11266e+09;
root [2] t.Set(time,false)
root [3] t.GetYear()
(const Int_t)2004

[quote=“luohaofei”]
Hi, thank you very much! I tried the ULong_t, but still with wrong time.

root [0] TDatime t root [1] ULong_t time = 3.11266e+09; root [2] t.Set(time,false) root [3] t.GetYear() (const Int_t)2004 [/quote]
You misunderstood my point: It looks like system’s C library and thus ROOT’s
TDatime cannot handle these kind of time values. This is the fundamental Year
2038 problem.

My suggestion was that you stay away from TDatime (and indirectly your time_t) completely and store your seconds in plain types like unsigned or long long unsigned instead which have a sufficient range. I am not sure what the easiest way to extract e.g. the year or month would be in C++ code, but at least in the shell with my date implementation I seem to get reasonable values.

# date -d "@3112660000"
Sun Aug 19 22:46:40 EST 2068
# date -d "@2322750000"
Sun Aug  9 11:20:00 EST 2043

# date -d "@2322750000" "+%Y"
2043
# date -d "@3112660000" "+%Y"
2068

Hi honk

Thank you very much! I tried you suggestion, it only works when I run it in root session

root [0] gSystem->Exec("date -d \"@3112660000\" \"+%Y\"")
2068
(Int_t)0

if I put the code in the script and compile the script, The output is 0.

cout << "use the shell command : " << gSystem->Exec("date -d \"@3112660000\" \"+%Y\"") <<endl;
use the shell command : 0

Did I missed something?

Hi,

yes, the output of date in on stdout and the return value of Exec is the ‘exit code’. You want to be using gSystem->OpenPipe instead.

Cheers,
Philippe.