Skip to content

Commit

Permalink
Fix conversion from FILETIME to file_time_type when using libstdc++
Browse files Browse the repository at this point in the history
  • Loading branch information
rikyoz committed Jul 10, 2024
1 parent f04d819 commit f35e1bd
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
25 changes: 17 additions & 8 deletions src/internal/dateutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,40 @@ using FileTimeDuration = std::chrono::duration< int64_t, FileTimeTickRate >;
// Seconds between 01/01/1601 (NT epoch) and 01/01/1970 (Unix epoch):
constexpr std::chrono::seconds nt_to_unix_epoch{ -11644473600 };

#ifndef _WIN32
#if defined( BIT7Z_USE_STANDARD_FILESYSTEM ) && defined( __GLIBCXX__ )
// Seconds between 01/01/1970 (Unix epoch) and 01/01/2174 (libstdc++'s file_clock epoch).
constexpr std::chrono::seconds libstdcpp_file_clock_epoch{ -6437664000 };
#endif

#ifndef _WIN32
auto FILETIME_to_file_time_type( FILETIME fileTime ) -> fs::file_time_type {
const FileTimeDuration fileTimeDuration{
( static_cast< int64_t >( fileTime.dwHighDateTime ) << 32 ) + fileTime.dwLowDateTime
( static_cast< std::uint64_t >( fileTime.dwHighDateTime ) << 32ull ) + fileTime.dwLowDateTime
};

const auto unixEpoch = fileTimeDuration + nt_to_unix_epoch;
return fs::file_time_type{ std::chrono::duration_cast< std::chrono::system_clock::duration >( unixEpoch ) };
const auto unixFileTime = fileTimeDuration + nt_to_unix_epoch;
const auto systemFileTime = std::chrono::duration_cast< fs::file_time_type::clock::duration >( unixFileTime );
#if defined( BIT7Z_USE_STANDARD_FILESYSTEM ) && defined( __GLIBCXX__ )
return fs::file_time_type{ systemFileTime + libstdcpp_file_clock_epoch };
#else
return fs::file_time_type{ systemFileTime };
#endif
}

auto time_to_FILETIME( std::time_t timeValue ) -> FILETIME {
auto time_to_FILETIME( std::time_t value ) -> FILETIME {
// NOLINTNEXTLINE(*-magic-numbers)
const uint64_t timeInSeconds = ( static_cast< uint64_t >( timeValue ) * 10000000ull ) + 116444736000000000;
const std::uint64_t timeInSeconds = ( static_cast< std::uint64_t >( value ) * 10000000ull ) + 116444736000000000ull;
FILETIME fileTime{};
fileTime.dwLowDateTime = static_cast< DWORD >( timeInSeconds );
fileTime.dwHighDateTime = static_cast< DWORD >( timeInSeconds >> 32 );
fileTime.dwHighDateTime = static_cast< DWORD >( timeInSeconds >> 32ull );
return fileTime;
}

#endif

auto FILETIME_to_time_type( FILETIME fileTime ) -> time_type {
const FileTimeDuration fileTimeDuration{
( static_cast< int64_t >( fileTime.dwHighDateTime ) << 32 ) + fileTime.dwLowDateTime
( static_cast< std::uint64_t >( fileTime.dwHighDateTime ) << 32ull ) + fileTime.dwLowDateTime
};

const auto unixEpoch = fileTimeDuration + nt_to_unix_epoch;
Expand Down
2 changes: 1 addition & 1 deletion src/internal/dateutil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace bit7z {

auto FILETIME_to_file_time_type( FILETIME fileTime ) -> fs::file_time_type;

auto time_to_FILETIME( std::time_t timeValue ) -> FILETIME;
auto time_to_FILETIME( std::time_t value ) -> FILETIME;

#endif

Expand Down

0 comments on commit f35e1bd

Please sign in to comment.