Как преобразовать std :: filesystem :: file_time_type в time_t? - PullRequest
0 голосов
/ 04 апреля 2020

Я написал решение для windows с использованием MSVC2015, где следующий код преобразует 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"))

Это работает хорошо. Затем, когда я попытался перенести решение на Linux, используя g cc 9.3 (-std = C ++ 2a), я получил следующую ошибку:

Ошибка: 'to_time_t' не является членом 'std :: chrono :: time_point :: clock' {aka 'std :: filesystem :: __ file_clock'}

Я искал решение, но то, что я нашел, основано на решении включен на примере std :: filesystem :: last_write_time в cplusplus.com . Решение показано ниже:

auto ftime = fs::last_write_time(p);
std::time_t cftime = decltype(ftime)::clock::to_time_t(ftime);

К сожалению, оно не работает для меня. На самом деле, в примере есть комментарий, который говорит, что он не будет работать на MSV C (работал на MSVC2015) или G CC 9; C ++ 20 позволит переносить вывод.

Теперь я застрял ... Как я могу сделать это преобразование, используя g cc?

Ответы [ 2 ]

3 голосов
/ 04 апреля 2020

До C ++ 20? Нет портативного способа сделать это. Это работало в той версии Visual Studio, потому что в этой версии реализации файловой системы VS использовалось system_clock для типа часов файловой системы. Это не требуется стандартом C ++, но разрешено. Так что ваш код просто сработал.

До C ++ 20 не было механизма для выравнивания двух часов, чтобы время из одного можно было преобразовать во время другого. Так что, если часы файловой системы не system_clock, вам не повезло. Вам нужно будет написать код, определяющий реализацию c, используя знания о том, как эта реализация реализовала часы своей файловой системы (в основном зная, какую эпоху она использует), чтобы вы могли вручную преобразовать его в system_clock::time_point.

C ++ 20 дает system_clock фиксированную эпоху, которая будет использоваться во всех реализациях (UNIX -time), и требует, чтобы file_clock мог преобразовывать свои временные точки в system_clock временных точек.

1 голос
/ 06 апреля 2020

Как уже говорилось, в C ++ 17 нет идеального способа сделать это. В зависимости от фактического варианта использования может быть достаточно использовать переносимое приближение. Основываясь на моем ответе на "Как преобразовать std::filesystem::file_time_type в строку, используя G CC 9" , я хочу предложить вспомогательную функцию, используемую там:

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);
}

Знайте то, что он использует вызов now() на каждом такте, так что это не точное решение с гарантией двусторонней передачи, но оно может быть полезным для вас до тех пор, пока пробел в библиотеке не будет закрыт. Он основан на том факте, что разница между временными точками одних и тех же часов проста, и существует operator+ для duration и time_point разных источников.

Для способов снижения риска Соответствующая ошибка еще больше, я хочу указать на преобразование между часами C ++ 11 , где был сделан некоторый статистический анализ с идеями по уменьшению возможных ошибок, но когда это приемлемо, я просто использую приведенный выше код.

...