I'm using HowardHinnant/date in lieu of the new C++20 calendar/timezone facilities that are not yet available in Clang/GCC. My question applies equally to both implementations: How do I safely clock_cast time_points having days duration?
When I try:
using namespace date; // or using std::chrono in C++20
tai_time<days> tai{days{42}};
sys_days sys = clock_cast<std::chrono::system_clock>(tai);
I get a "no viable conversion" error for the last statement. It turns out the result uses a duration that is common_type<days, seconds>, which comes from utc_clock::to_sys() that's used in the conversion. The common duration type is std::chrono::seconds, so it's normal that it can't be directly converted to a days duration.
I can get it to compile if I use an explicit duration_cast:
using namespace date; // or using std::chrono in C++20
tai_time<days> tai{days{42}};
auto casted = clock_cast<std::chrono::system_clock>(tai);
sys_days sys{std::chrono::duration_cast<days>(casted.time_since_epoch())};
... but I'm worried that the result might by off by a day due to the truncation (especially for dates preceding the epoch). Is this the correct way to do what I'm trying to do? Should I be using floor instead of duration_cast?
Why is there even a std::common_type_t<Duration, std::chrono::seconds> in utc_clock::to_sys() anyway? Shouldn't it simply return the same duration type?