Как мне разобрать дату в приложении Metro (C++/CX)?
У меня есть приложение C++/CX, которое обрабатывает некоторые данные из файла. Там есть строка, представляющая культуру, которая использовалась для сохранения дат, и несколько дат. Мне нужно преобразовать их из строк в Platform:: DateTime. Я слышал, что Windows:: Globalization:: DateTimeFormatting - это класс для использования, но я не вижу, как его использовать для этого. У кого-нибудь есть пример?
3 ответа
Проекция WinRT на C++/CX отличается от проекции Managed (C#/VB) по ряду причин, и один из наиболее важных - проекция фундаментальных типов (таких как Point
, Size
, String
, а также DateTime
).
Управляемая проекция проецирует эти типы как типы.NET (со всей базовой поддержкой BCL), в то время как проекция C++ обычно минимально проецирует эти типы для взаимодействия, ожидая, что пользователь будет полагаться на поддержку библиотеки C++ для более продвинутой функциональности.
Итак, где в.NET 32-разрядное целое число со знаком становится System.Int32
(с его соответствующими .Parse
функциональность) в C++ вы получаете обычный C++ int
и, как ожидается, будут использовать функциональность ЭЛТ (_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
класс, а документация неверная; он не поддерживает разбор и не предназначен для (только форматирования).
Было бы std::get_time
сделать трюк? Пример внизу страницы предлагает вам проанализировать строку даты, используя локаль в tm
структура. Я думаю, что вы могли бы затем преобразовать tm
структурировать в правильный WinRT DateTime
,
Я использую этот код:
auto cal = ref new Windows::Globalization::Calendar();
cal->AddSeconds(additionalSeconds);
return cal->GetDateTime();
С Windows::Globalization::Calendar у вас есть все приятные функции времени, которые вам нужны: https://msdn.microsoft.com/library/windows/apps/br206724