Reputation: 21
I have been writing unit tests for a class in our codebase that basically converts date, time values from std::string
to std::chrono::time_point
and vice versa, for different kinds of timestamps (yyyy-mm-dd , hh:mm:ss.ms etc).
One way I tried to test whether a std::chrono::system_clock::time_point
returned by a function in our codebase as the same as one created in the unit tests was to do something like this -
std::chrono::system_clock::time_point m_TimePoint{}; // == Clock's epoch
auto foo = convertToString(n_TimePoint); //foo is std::string
auto bar = getTimePoint(foo);
ASSERT_EQ(m_TimePoint, bar);
This was on Ubuntu , now the constructor should return a time point as UTC Jan 1 00:00:00 1970. Now when I used ctime()
to see the textual representation of the epoch it returned Dec 31 19:00:00 1969. I was puzzled and checked that EST(my system timezone) is equal to UTC-5.
Once I created the object as -
std::chrono::duration d{0};
d += std::chrono::hours(5);
std::chrono::system_clock::time_point m_TimePoint{d}; //== clock epoch + 5 hours
All worked fine.
My question is it possible for the system clock epoch to be adjusted based on the system timezone?
Upvotes: 2
Views: 1663
Reputation: 218780
There's two answers to this question, and I'll try to hit both of them.
system_clock
was introduced in C++11, and its epoch was left unspecified. So the technical answer to your question is: yes, it is possible for the system_clock
epoch to be adjusted based on the system timezone.
But that's not the end of the story.
There's only a few implementations of system_clock
, and all of them model Unix Time. Unix Time is a measure of time duration since 1970-01-01 00:00:00 UTC, excluding leap seconds. It is not dependent on the system timezone.
The C++20 spec standardizes this existing practice.
So from a practical standpoint, the answer to your question is: no, it is not possible for the system_clock
epoch to be adjusted based on the system timezone.
One thing that could be tripping you up is that system_clock
typically counts time in units finer than milliseconds. It varies from platform to platform, and you can inspect what it is with system_clock::duration::period::num
and system_clock::duration::period::den
. These are two compile-time integral constants that form a fraction, n/d
which describes the length of time in seconds that system_clock
is measuring. For Ubuntu my guess would be this forms the fraction 1/1'000'000'000
, or nanoseconds
.
You can get milliseconds
(or whatever unit you want) out of system_clock::time_point
with:
auto tp = time_point_cast<milliseconds>(system_clock::now());
Upvotes: 5