问题
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?
回答1:
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.
回答2:
Before C++20? There is no portable way to do that. It worked in that version of Visual Studio because that version of VS's filesystem implementation just so happens to use system_clock
for the filesystem clock type. This is not required by the C++ standard, but it is allowed. So your code just so happened to work.
Pre-C++20, there was no mechanism to align two clocks together, so that time from one could be converted into the time of another. So if the filesystem clock isn't system_clock
, you're out of luck. You would have to write implementation-specific code using knowledge of how that implementation implemented their filesystem clock (basically knowing what epoch it uses) so that you could manually convert it to a system_clock::time_point
.
C++20 gives system_clock
a fixed epoch to be used across all implementations (UNIX-time), and requires that file_clock
be able to convert its time points into system_clock
time points.
来源:https://stackoverflow.com/questions/61030383/how-to-convert-stdfilesystemfile-time-type-to-time-t