如何在 Metro (C++/CX) 应用程序中解析日期?
Posted
技术标签:
【中文标题】如何在 Metro (C++/CX) 应用程序中解析日期?【英文标题】:How do I parse a date in a Metro (C++/CX) app? 【发布时间】:2012-07-21 21:26:38 【问题描述】:我有一个 C++/CX 应用程序正在处理文件中的一些数据。它有一个字符串,表示用于保存日期的文化,并且它有一些日期。我需要将它们从字符串转换为 Platform::DateTime。我听说Windows::Globalization::DateTimeFormatting 是要使用的类,但我不知道如何使用它。有人举个例子吗?
【问题讨论】:
我对 winrt 不太熟悉,但看起来DateTimeFormatter
类与 DateTime
-> string
不同。你需要解析它。我相信 DateTimeOffset::Parse()
或 DateTimeOffset::ParseExact()
是您正在寻找的东西(或任何 winrt/C++ 等价物)。
仅基于名称,我并不反对,但 DateTimeFormatting 类的文档(完整地)说“格式化和解析日期和时间”。 Platform::DateTime 只是一个没有方法的结构。
文档中的措辞会误导/错误,这对我来说并不奇怪。该类中只有一种方法 (Format()
),并且没有明确的方法/构造函数来进行解析。它可能只是为了格式化。至少有 one case 的文档毫无意义。
【参考方案1】:
WinRT 的 C++/CX 投影在许多方面与托管 (C#/VB) 投影不同,其中最主要的一种是基本类型的投影(例如 Point
、Size
、 String
和 DateTime
)。
托管投影将这些类型投影为 .NET 类型(具有 BCL 的所有底层支持),而 C++ 投影通常最低限度地投影这些类型以进行互操作,期望用户依赖 C++ 库支持来获得更高级的功能。
因此,在 .NET 中,带符号的 32 位整数在 C++ 中变为 System.Int32
(及其相关的 .Parse
功能)时,您将获得常规 C++ int
并有望使用 CRT 功能(_wtoi
) 来完成类似的任务。这种差异通常会导致不同投影之间的“特征差距”,其中一个更痛苦的问题是处理DateTime
结构(在 BCL 中有非常丰富的支持)。
我设法得到的解决方案是从 COleDateTime
类(通过包含 ATLComTime.h 找到)开始,然后转到 COleDateTime
->SYSTEMTIME
->FILETIME
->_ULARGE_INTEGER
-> Windows::Foundation::DateTime
。这是一项严肃的体操,但COleDateTime
类具有您需要的特定于语言的解析能力。
LCID lcid = LocaleNameToLCID(L"es-es", LOCALE_ALLOW_NEUTRAL_NAMES); //parse language tag to get locale ID
COleDateTime dt;
dt.ParseDateTime(L"12 enero, 2012 10:00:01", 0, lcid); //parse date string based on language
//get system time struct
SYSTEMTIME st;
dt.GetAsSystemTime(st);
//COleDateTime is in local timezone, DateTime is in UTC, so we need to convert
SYSTEMTIME st_utc;
TzSpecificLocalTimeToSystemTime(nullptr, &st, &st_utc);
//get filetime struct to get a time format compatible with DateTime
FILETIME ft;
SystemTimeToFileTime(&st_utc, &ft);
//use _ULARGE_INTEGER to get a uint64 to set the DateTime struct to
_ULARGE_INTEGER ulint = ft.dwLowDateTime, ft.dwHighDateTime;
Windows::Foundation::DateTime wfdt;
wfdt.UniversalTime = ulint.QuadPart;
我已经询问了DateTimeFormatter
类,但文档不正确;它不支持解析,也不打算(仅格式化)。
【讨论】:
由于与夏令时和往返 UTC 相关的问题,我不得不稍微调整此代码,但只要您考虑到这一点,您就可以使用此解决方案 -这肯定不是我会想到的事情。谢谢!【参考方案2】:std::get_time
会成功吗?页面底部的示例建议您可以使用语言环境将日期字符串解析为 tm
结构。我想你可以将 tm
结构转换为正确的 WinRT DateTime
。
【讨论】:
我相信这也可行,但与COleDateTime::ParseDateTime
相比,它似乎不太灵活。但我认为当您收到格式正确的日期时,这将是一个更简单的解决方案。【参考方案3】:
我使用这个代码:
auto cal = ref new Windows::Globalization::Calendar();
cal->AddSeconds(additionalSeconds);
return cal->GetDateTime();
使用 Windows::Globalization::Calendar,您可以获得所需的所有美好时光功能:https://msdn.microsoft.com/library/windows/apps/br206724
【讨论】:
以上是关于如何在 Metro (C++/CX) 应用程序中解析日期?的主要内容,如果未能解决你的问题,请参考以下文章
如何在C#的metro应用程序中使用contactPickerUI添加联系人?
如何在 64 位 Perl 中解压缩(64 位)无符号长整数?
如何在 C#/XAML Metro App 中使用 HttpWebRequest(或)HttpClient 进行同步服务调用?