diff options
Diffstat (limited to 'zen/format_unit.cpp')
-rw-r--r-- | zen/format_unit.cpp | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/zen/format_unit.cpp b/zen/format_unit.cpp index cfaaa329..cb92f1e4 100644 --- a/zen/format_unit.cpp +++ b/zen/format_unit.cpp @@ -8,7 +8,7 @@ #include "basic_math.h" #include "i18n.h" #include "time.h" -#include <cwchar> //swprintf +#include <cwchar> //swprintf #include <ctime> #include <cstdio> @@ -293,7 +293,7 @@ std::wstring zen::utcToLocalTimeString(std::int64_t utcTime) auto errorMsg = [&] { return _("Error") + L" (time_t: " + numberTo<std::wstring>(utcTime) + L")"; }; #ifdef ZEN_WIN - FILETIME lastWriteTimeUtc = timetToFileTime(utcTime); //convert ansi C time to FILETIME + const FILETIME lastWriteTimeUtc = timetToFileTime(utcTime); //convert ansi C time to FILETIME SYSTEMTIME systemTimeLocal = {}; @@ -342,3 +342,71 @@ std::wstring zen::utcToLocalTimeString(std::int64_t utcTime) std::wstring dateString = formatTime<std::wstring>(L"%x %X", loc); return !dateString.empty() ? dateString : errorMsg(); } + + +#ifdef ZEN_WIN_VISTA_AND_LATER +Opt<std::int64_t> zen::mtpVariantTimetoUtc(double localVarTime) //returns empty on error +{ + SYSTEMTIME localSystemTime = {}; + if (!::VariantTimeToSystemTime(localVarTime, //_In_ DOUBLE vtime, + &localSystemTime)) //_Out_ LPSYSTEMTIME lpSystemTime + return NoValue(); + + /* + Windows Explorer isn't even consistent within itself: the modification time shown in the details list is calculated differently than the + one shown in MTP file properties => different result shown for files from a DST interval distinct from the current one. + -> Variant 1 matches the calculation of Explorer's details list and produces stable results irrespective of currently selected DST + -> Explorer uses different algorithms for MTP and FAT file systems! FAT's local time jumps between DST intervals in Explorer (since Vista)! + */ +#if 1 + SYSTEMTIME utcSystemTime = {}; + if (!::TzSpecificLocalTimeToSystemTime(nullptr, //_In_opt_ LPTIME_ZONE_INFORMATION lpTimeZoneInformation, + &localSystemTime, //_In_ LPSYSTEMTIME lpLocalTime, + &utcSystemTime)) //_Out_ LPSYSTEMTIME lpUniversalTime + return NoValue(); + + FILETIME utcFiletime = {}; + if (!::SystemTimeToFileTime(&utcSystemTime, //_In_ const SYSTEMTIME *lpSystemTime, + &utcFiletime)) //_Out_ LPFILETIME lpFileTime + return NoValue(); + +#else + FILETIME localFiletime = {}; + if (!::SystemTimeToFileTime(&localSystemTime, //_In_ const SYSTEMTIME *lpSystemTime, + &localFiletime)) //_Out_ LPFILETIME lpFileTime + return NoValue(); + + FILETIME utcFiletime = {}; + if (!LocalFileTimeToFileTime(&localFiletime, //_In_ const FILETIME *lpLocalFileTime, + &utcFiletime)) //_Out_ LPFILETIME lpFileTime + return NoValue(); + +#endif + + return filetimeToTimeT(utcFiletime); +} + + +Opt<double> zen::utcToMtpVariantTime(std::int64_t utcTime) //returns empty on error +{ + const FILETIME lastWriteTimeUtc = timetToFileTime(utcTime); //convert ansi C time to FILETIME + + SYSTEMTIME systemTimeUtc = {}; + if (!::FileTimeToSystemTime(&lastWriteTimeUtc, //__in const FILETIME *lpFileTime, + &systemTimeUtc)) //__out LPSYSTEMTIME lpSystemTime + return NoValue(); + + SYSTEMTIME systemTimeLocal = {}; + if (!::SystemTimeToTzSpecificLocalTime(nullptr, //__in_opt LPTIME_ZONE_INFORMATION lpTimeZone, + &systemTimeUtc, //__in LPSYSTEMTIME lpUniversalTime, + &systemTimeLocal)) //__out LPSYSTEMTIME lpLocalTime + return NoValue(); + + double localVarTime = 0; + if (!SystemTimeToVariantTime(&systemTimeLocal, //_In_ LPSYSTEMTIME lpSystemTime, + &localVarTime)) //_Out_ DOUBLE *pvtime + return NoValue(); + + return localVarTime; +} +#endif
\ No newline at end of file |