Dear experts,
TTimeStamp somtimes gives incorrect results when it’s constructed with date and time, whether using the unsigned date and time version, or the explicit year, month, day, hours, minutes, and seconds.
Here’s a minimal reproducible example:
time_t ut = -295372800; // from GNU date 8.32: Mon 22 Aug 08:00:00 UTC 1960
TTimeStamp tts(ut, 0);
std::printf("Original time_t = %+10ld; TTimeStamp = %s\n",
ut, tts.AsString("s"));
unsigned d = tts.GetDate();
unsigned H, M, S;
tts.GetTime(true, 0, &H, &M, &S);
std::printf("Values extracted from TTimeStamp: date = %u; H = %u, M = %u, S = %u\n",
d, H, M, S);
ut -= H*3600 + M*60 + S;
std::printf("Shifted time_t to start of day = %+10ld; TTimeStamp = %s\n",
ut, TTimeStamp(ut, 0).AsString("s"));
TTimeStamp tt1(d, 0u, 0u, true, 0);
std::printf("TTimeStamp(%u, 0u, 0u, true, 0) = %s, time_t = %+10ld\n",
d, tt1.AsString("s"), (time_t)tt1);
TTimeStamp tt2(1960, 8, 22, 0, 0, 0);
std::printf("TTimeStamp(1960, 8, 22, 0, 0, 0) = %s, time_t = %+10ld\n",
tt2.AsString("s"), (time_t)tt2);
and its output:
Original time_t = -295372800; TTimeStamp = 1960-08-22 08:00:00
Values extracted from TTimeStamp: date = 19600822; H = 8, M = 0, S = 0
Shifted time_t to start of day = -295401600; TTimeStamp = 1960-08-22 00:00:00
TTimeStamp(19600822, 0u, 0u, true, 0) = 1960-08-23 00:00:00, time_t = -295315200
TTimeStamp(1960, 8, 22, 0, 0, 0) = 1960-08-23 00:00:00, time_t = -295315200
It looks like before Jan 1st, 1970, TTimeStamp skip the January 1st for some years, when using the date and time constructor, while everything looks good using the time_t constructor:
const std::vector<int> days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
time_t ut = -410227200; // from GNU date 8.32: Mon 1 Jan 00:00:00 UTC 1957
for (int year = 1957; year <= 1958; ++year) {
for (int month = 1; month <= 12; ++month) {
int add_day = month == 2 && TTimeStamp::IsLeapYear(year);
for (int day = 1; day <= days[month-1] + add_day; ++day, ut += 86400) {
TTimeStamp tt3(year, month, day, 0, 0, 0);
std::string date3 = tt3.AsString("s");
date3.erase(10);
TTimeStamp tt4(ut, 0);
std::string date4 = tt4.AsString("s");
date4.erase(10);
std::printf("In:%d-%02d-%02d Out:%s %+10ld; In:%+10ld Out:%+10ld %s\n",
year, month, day, date3.c_str(), (time_t)tt3,
ut, (time_t)tt4, date4.c_str());
}
}
}
In:1957-01-01 Out:1957-01-01 -410227200; In:-410227200 Out:-410227200 1957-01-01
[…
all days in between are ok
…]
In:1957-12-31 Out:1957-12-31 -378777600; In:-378777600 Out:-378777600 1957-12-31
In:1958-01-01 Out:1958-01-02 -378604800; In:-378691200 Out:-378691200 1958-01-01
This happens by running the attached macro in both interpreted and compiled mode.
test.C (1.8 KB)
Best,
Claudio
ROOT Version: 6.26/02, heads/latest-stable@c8d49336
Platform: Ubuntu 22.04.2
Compiler: linuxx8664gcc