How can I extract hours, minutes, and seconds from a given std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
?
My code in below does not return the hour correctly. It returns a vary large value for the hour (e.g., Hours: 472057, Minutes: 3).
std::chrono::system_clock::time_point tp = std::chrono::system_clock::now();
auto hours = std::chrono::duration_cast<std::chrono::hours>(tp.time_since_epoch()).count();
auto minutes = std::chrono::duration_cast<std::chrono::minutes>(tp.time_since_epoch()).count() % 60;
// Print the hours and minutes
std::cout << "Hours: " << hours << std::endl;
std::cout << "Minutes: " << minutes << std::endl;
As you've specified C++11, and removed the part about using Howard Hinnant's date lib, you'll have to re-create that part of the date lib that exists only as 3rd party lib until C++20. This isn't too much trouble if you are content with UTC. Getting local time is more effort:
#include <chrono>
#include <iostream>
int
main()
{
// This is a date_time in UTC
std::chrono::system_clock::time_point tp = std::chrono::system_clock::now();
// This is a date in UTC
auto tp_days = std::chrono::time_point_cast<std::chrono::duration<int, std::ratio<86400>>>(tp);
// This is a time in UTC
auto tod = tp - tp_days;
// This is how to separate a duration into {h, m, s}
auto h = std::chrono::duration_cast<std::chrono::hours>(tod);
tod -= h;
auto m = std::chrono::duration_cast<std::chrono::minutes>(tod);
tod -= m;
auto s = std::chrono::duration_cast<std::chrono::seconds>(tod);
std::cout << "Hours: " << h.count() << '\n';
std::cout << "Minutes: " << m.count() << '\n';
std::cout << "Seconds: " << s.count() << '\n';
}
Note that this only works correctly for system_clock
time_point
s after 1970-01-01T00:00:00 UTC. This is because time_point_cast
truncates towards zero. C++17 introduces floor
which truncates towards negative infinity, and should be preferred as it works both before and after the epoch.
To get local time you'll need to figure out your current UTC offset and add that to your time_point
prior to splitting it up into a date and time (prior to truncating to days precision).