如何比较time_t和std :: filesystem :: file_time_type

Pet*_*eUK 7 c++ boost-filesystem c++-chrono

我正在将一些代码转换boost::filesystemstd::filesystem.使用的先前代码boost::filesystem::last_write_time()返回time_ttime_t我已经持有的对象如此直接的比较是微不足道的.顺便说一下,这个time_t我持有的文件内容很久以前就已经存在了,所以我坚持使用这个"自unix epoch以来的时间"类型.

std::filesystem::last_write_time返回一个std::filesystem::file_time_type.是否有可移植的方式将a转换file_time_type为a time_t或以其他方式可比较两个对象?

#include <ctime>
#include <filesystem>

std::time_t GetATimeInSecondsSince1970Epoch()
{
    return 1207609200;  // Some time in April 2008 (just an example!)
}

int main()
{
    const std::time_t time = GetATimeInSecondsSince1970Epoch();
    const auto lastWriteTime = std::filesystem::last_write_time("c:\\file.txt");

    // How to portably compare time and lastWriteTime?
}
Run Code Online (Sandbox Code Playgroud)

编辑:请注意cppreference.comlast_write_time上的示例代码表示它假设时钟是std::chrono::system_clock实现该to_time_t功能的状态.这个假设并不总是如此,并不在我的平台上(VS2017).

How*_*ant 9

Fwiw,当 C++20 到来时,可移植的解决方案将是:

clock_cast<file_clock>(system_clock::from_time_t(time)) < lastWriteTime
Run Code Online (Sandbox Code Playgroud)

这将转换time_tfile_time,反之亦然。这种方法的优点是file_time通常具有比 更高的精度time_t。转换file_timetime_t将在转换过程中失去精度,从而有可能使比较不准确。


小智 7

我遇到了同样的问题,我使用 Visual Studio 的专用代码解决了它。

在 VS 的情况下,我使用_wstati64函数(w对于宽字符,因为 Windows 以 Utf16 编码 Unicode 路径)和类wstring的转换path

整个事情都集中在这个函数中:

#if defined ( _WIN32 )
#include <sys/stat.h>
#endif

std::time_t GetFileWriteTime ( const std::filesystem::path& filename )
{
    #if defined ( _WIN32 )
    {
        struct _stat64 fileInfo;
        if ( _wstati64 ( filename.wstring ().c_str (), &fileInfo ) != 0 )
        {
            throw std::runtime_error ( "Failed to get last write time." );
        }
        return fileInfo.st_mtime;
    }
    #else
    {
        auto fsTime = std::filesystem::last_write_time ( filename );
        return decltype ( fsTime )::clock::to_time_t ( fsTime );
    }
    #endif
}
Run Code Online (Sandbox Code Playgroud)


Ser*_*eyA 6

您链接的文章展示了如何执行此操作:to_time_t通过.clockfile_time_type

从您自己的链接复制粘贴:

auto ftime = fs::last_write_time(p);
std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime); 
Run Code Online (Sandbox Code Playgroud)

如果您的平台不提供system_clock的时钟file_time_type,那么就没有可移植的解决方案(至少在 C++20 时钟file_time_type标准化之前)。在此之前,您必须弄清楚它实际上是什么时钟,然后通过duration_cast和朋友适当地投射时间。

  • 链接的文章仅显示了一个示例,假设时钟类型是 system_clock。无法做出该假设,并且在 VS2017 上它不是 system_clock,因此 to_time_t 不可用。我将编辑我的问题以提及这一点。 (3认同)
  • @PeteUK我添加了一些措辞(解释说在这种情况下没有便携式解决方案)。 (2认同)