I need to find the elapsed time (duration) from local midnight.
I tried this:
1 2 3 4
// if we have a time_point, must convert to a duration first
auto tp = chr::system_clock::now();
// convert to duration first (subtract from midnight)
chr::hh_mm_ss hms2{ tp - chr::floor<chr::days>(tp) };
but gives me 6 hours more than the correct value - that's because it's taking from midnight GMT and not local midnight....I am in CST timezone
system_clock::now() gives you a time point. That is the amount of time (duration) that has elapsed since "epoch", which is usually defined as 1 January 1970, 00:00:00 UTC. And this is totally independent from any time-zone or "local" time! Regardless of where in the world you are located, the amount of time that has elapsed since "epoch" (1 January 1970, 00:00:00 UTC) is exactly the same 😏
16941712194600337[1/10000000]s <-- number of 100-nanosecond intervals elapsed since "epoch"
Okay. You can also convert the time point into a local time, which necessarily requires specifying the time-zone, because the "local" time obviously is specific to the time-zone where you are located! Here we use the system's default time-zone, for simplicity:
2023-09-08 13:11:47.7973938 <-- the "local" time at default time-zone
So, system_clock::now() is not "in GMT" (UTC), but is a time-zone agnostictime point. The point in time is the same, irregardless of time-zone. It's just that the "epoch", which is the reference point (offset) for time points, happens to be "1 January 1970, 00:00:00 UTC".
I am looking for time elapsed from local midnight. It is now approx 16:03:05 but this calculation below gives me time from GMT midnight which is 6 hours more:
1 2
auto tp = chr::system_clock::now();
cout << tp << endl;
The current time in CST is 6 hours less. How can I get time from local midnight?
(I could substract 6 hours but that would only work for CST) I want time from local midnight regardless of my current time zone!
You are not listening correctly what I am saying and think I am repeating my question which is not the case!!!
I am looking for time elapsed from local midnight. It is now approx 16:03:05 but this calculation below gives me time from GMT midnight which is 6 hours more:
1 2
auto tp = chr::system_clock::now();
cout << tp << endl;
2023-09-10 22:03:05.6599597
A better way to visualize (print) what a time point really "contains" is:
1 2
auto tp = chr::system_clock::now();
cout << tp.time_since_epoch() << endl;
std::chrono::time_point: Class template std::chrono::time_point represents a point in time. It is implemented as if it stores a value of type Duration indicating the time interval from the start of the Clock's epoch.
std::chrono::system_clock:system_clock measures Unix Time (i.e., time since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, not counting leap seconds). [since C++20]
So, what a time_point represents is not really in any time-zone, not even in UTC/GMT. It is agnostic of time-zones (local times).
It's just that the "epoch" (offset point) of the system clock happens to be defined as 00:00:00 UTC on January 1st, 1970.
As pointed out before, if you want a "local" time, then you have to convert the time_point to "local" time, by using the desired time-zone!
(Convert time_point to a zoned_time in the desired time-zone, truncate that zoned_time to "days" precision so that hours/minutes/seconds will all be zeroed out, and finally compute the difference between the truncated zoned_time and the non-truncated zoned_time)
You could also write this without zoned_time if you prefer:
1 2 3 4 5 6 7 8
int main()
{
local_time current = current_zone()->to_local(system_clock::now());
local_time midnight = floor<days>(current);
duration time_since_midnight = current - midnight;
std::cout << hh_mm_ss{ time_since_midnight } << '\n';
}
Notice the code in the prior post does call current_zone twice, which raises the question of whether or not the current time zone can change in the period between the two calls.
I think the code is fine, as long as reload_tzdb is not called. Even so it might be better to act defensively and call current_zone only once.