Как разобрать дату в приложении Metro (С++/CX)?

У меня есть приложение С++/CX, которое обрабатывает некоторые данные из файла. В нем есть строка, представляющая культуру, которая использовалась для сохранения дат, и у нее есть некоторые даты. Мне нужно преобразовать их из строк в Platform:: DateTime. Я слышал, что Windows:: Globalization:: DateTimeFormatting является классом, который я использую, но я не вижу, как его использовать для этого. У кого-нибудь есть пример?

Ответы

Ответ 1

Проекция WinRT на С++/CX отличается от управляемой (С#/VB) проекции несколькими способами, и одна из самых главных - в проекции основных типов (таких как Point, Size, String и DateTime).

Управляемый прогноз проектирует эти типы как типы .NET(со всей базовой поддержкой BCL), в то время как проекция С++ обычно минимально проектирует эти типы для взаимодействия, ожидая, что пользователь будет полагаться на поддержку библиотеки С++ для более сложных функций.

Итак, где в .NET подписанное 32-битовое целое становится System.Int32 (с его соответствующей функциональностью .Parse) в С++, вы получаете обычный С++ int и, как ожидается, будете использовать функциональность CRT (_wtoi) для выполнения аналогичной задачи. Это различие часто приводит к "отличительному признаку" между различными проекциями, одним из наиболее болезненных из которых является рассмотрение структуры DateTime (которая имеет очень богатую поддержку в BCL).

Решение, которое мне удалось получить, это начать с класса COleDateTime (найденного путем включения ATLComTime.h) и перейти COleDateTimeSYSTEMTIMEFILETIME_ULARGE_INTEGERWindows::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, и документация неверна; он не поддерживает синтаксический анализ и не предназначен для (только форматирования).

Ответ 2

Будет std::get_time сделать трюк? В примере внизу страницы вы можете проанализировать строку даты, используя локаль, в структуру tm. Я предполагаю, что вы могли бы преобразовать структуру tm в правильный WinRT DateTime.

Ответ 3

Я использую этот код:

auto cal = ref new Windows::Globalization::Calendar(); cal->AddSeconds(additionalSeconds); return cal->GetDateTime();

В Windows:: Глобализация:: Календарь у вас есть все необходимые функции времени: https://msdn.microsoft.com/library/windows/apps/br206724