I wrote a solution for windows using MSVC2015 where the follow code converts the std::filesystem::last_write_time result time_t:
time_t ftime = std::file_time_type::clock::to_time_t(fs::last_write_time("/Path/filename"))
It works well. Then when I tried to port the solution to Linux using gcc 9.3 (-std=C++2a) I've got the follow error:
Error: 'to_time_t' is not member of 'std::chrono::time_point::clock' {aka 'std::filesystem::__file_clock'}
I searched for a solution, but what I found is based on solution included on example of std::filesystem::last_write_time at cplusplus.com. The solution is shown bellow:
auto ftime = fs::last_write_time(p);
std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime);
Unfortunately it doesn't work to me. Actually, the example has a comment that say it won't work at MSVC(worked at MSVC2015) or GCC 9; C++20 will allow portable output.
Now, I'm stuck... How can I make this conversion using gcc?
The following function converts a filetime in the UNIX time_t format to a Win32 FILETIME format. Note that time_t is a 32-bit value and FILETIME is a 64-bit structure, so the Win32 function, Int32x32To64 () is used in the following function:
Under UNIX platforms, file times are maintained in the form of a ANSI C runtime arithmetic type named 'time_t', which represents seconds since midnight January 1, 1970 UTC (coordinated universal time).
Under Win32 platforms, file times are maintained primarily in the form of a 64-bit FILETIME structure, which represents the number of 100-nanosecond intervals since January 1, 1601 UTC (coordinate universal time). This article shows how to convert UNIX time to other Win32 time formats.
This worked for me in C++17. Use FileTimeToSystemTime to return the file time in a human-readable format. From there you use using mktime to convert to time_t.
As already said, there is no perfect way to do that in C++17. Depending on the actual use-case it might be good enough to use a portable approximation. Based on my answer to "How to convert std::filesystem::file_time_type
to a string using GCC 9", I want to suggest the helper function used there:
template <typename TP>
std::time_t to_time_t(TP tp)
{
using namespace std::chrono;
auto sctp = time_point_cast<system_clock::duration>(tp - TP::clock::now()
+ system_clock::now());
return system_clock::to_time_t(sctp);
}
Be aware, that it uses a call to now()
on each clock, so it is not an exact, round-trip-guaranteed solution, but it might be usable for you, until the gap in the library is closed. It is based on the fact that difference between time points of the same clock is easy and there is an operator+
for duration
and time_point
of different sources.
For ways to lower the risk of a relevant error even more, I want to point to the conversion between C++11 clocks where some statistical analysis was made with ideas to mitigate possible errors, but when acceptable, I just use the code above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With