如何在 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) 投影不同,其中最主要的一种是基本类型的投影(例如 PointSizeStringDateTime)。

托管投影将这些类型投影为 .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 进行同步服务调用?

Python:如何在 for 中解压缩多个值?

如何在“native c ++”环境中使用WinRT IAsyncOperation *对象

如何在 Metro 应用程序中为组合框添加颜色?