微软的 WinUI3 C++/WinRT 版本的 DateTime 有问题
下面的代码功能很简单,遍历
C:\users\<username>\local\notes 文件夹中的所有文件,读取每个文件的内容和创建时间。问题出在把获取到的文件创建时间转换为字符串时。当把获取到的文件创建时间转换为字符串时,用 C++/WinRT 提供的方法,总比用 Windows 原生 API 提供的方法晚 1 秒或 2 秒。
// 这是 C++/WinRT 方法:
wchar_t buf[128]{};
struct tm atm;
__time64_t tim64{winrt::clock::to_time_t((*it).DateCreated())};
_localtime64_s(&atm, &tim64);
size_t length{wcsftime(buf, std::size(buf), L"%x %X", &atm)};
// 这是 Windows 原生 API 方法:
WIN32_FILE_ATTRIBUTE_DATA wfad{};
GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &wfad);
SYSTEMTIME system_time{};
FILETIME local_file_time{};
FileTimeToLocalFileTime(&wfad.ftCreationTime, &local_file_time);
FileTimeToSystemTime(&local_file_time, &system_time);
(void)_snwprintf_s(&buf[length], std::size(buf) - length,
_countof(buf) - length - 1,
L"\r\n%hu-%hu-%hu %hu:%hu:%hu", system_time.wYear,
system_time.wMonth, system_time.wDay,
system_time.wHour, system_time.wMinute,
system_time.wSecond);
下面是完整的代码:
winrt::Windows::Foundation::IAsyncAction
NoteViewModel::GetFilesInFolderAsync()
{
_wsetlocale(LC_ALL, L"");
winrt::Windows::Storage::StorageFolder storage_folder{nullptr};
storage_folder
= co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(
m_storage_folder);
winrt::Windows::Foundation::Collections::IVectorView<
winrt::Windows::Storage::IStorageItem>
storage_items;
storage_items = co_await storage_folder.GetItemsAsync();
for (winrt::impl::fast_iterator<
winrt::Windows::Foundation::Collections::IVectorView<
winrt::Windows::Storage::IStorageItem>>
it{storage_items.begin()};
it != storage_items.end();
++it) {
winrt::WinUI3DefaultIcon::Note note{
winrt::make<winrt::WinUI3DefaultIcon::implementation::Note>(
L"这是书名")};
note.set_storage_folder(m_storage_folder);
// 这个无所谓,后面会把这个名字覆盖掉。
note.FileName((*it).Name());
note.set_added_date_time((*it).DateCreated());
{
wchar_t buf[128]{};
struct tm atm;
__time64_t tim64{winrt::clock::to_time_t((*it).DateCreated())};
_localtime64_s(&atm, &tim64);
size_t length{wcsftime(buf, std::size(buf), L"%x %X", &atm)};
std::wstring path{m_storage_folder + LR"raw(\)raw"};
path += (*it).Name().c_str();
WIN32_FILE_ATTRIBUTE_DATA wfad{};
GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &wfad);
SYSTEMTIME system_time{};
FILETIME local_file_time{};
FileTimeToLocalFileTime(&wfad.ftCreationTime, &local_file_time);
FileTimeToSystemTime(&local_file_time, &system_time);
(void)_snwprintf_s(&buf[length], std::size(buf) - length,
_countof(buf) - length - 1,
L"\r\n%hu-%hu-%hu %hu:%hu:%hu", system_time.wYear,
system_time.wMonth, system_time.wDay,
system_time.wHour, system_time.wMinute,
system_time.wSecond);
MessageBoxW(MainWindow::hwnd, buf, buf, MB_OK);
}
co_await note.LoadNoteAsync();
m_many_notes.Append(note);
}
}
下面是个运行结果:

可以看到,同样的文件创建时间,C++/WinRT 转换后的时间,比 Windows 原生 API 快了一秒。我估计问题出在 winrt::Windows::Foundation::DateTime 和 winrt::clock::to_time_t上。
下面是其代码:
WINRT_EXPORT namespace winrt::Windows::Foundation
{
using TimeSpan = std::chrono::duration<int64_t, impl::filetime_period>;
using DateTime = std::chrono::time_point<clock, TimeSpan>;
}
WINRT_EXPORT namespace winrt
{
struct clock
{
...
using time_point = Windows::Foundation::DateTime;
...
}
static time_t to_time_t(time_point const& time) noexcept
{
return static_cast<time_t>(std::chrono::system_clock::to_time_t(std::chrono::time_point_cast<std::chrono::system_clock::duration>(to_sys(time))));
}
但是我先不去分析具体问题了。
1894

被折叠的 条评论
为什么被折叠?



