У меня есть приложение С++/CX, которое обрабатывает некоторые данные из файла. В нем есть строка, представляющая культуру, которая использовалась для сохранения дат, и у нее есть некоторые даты. Мне нужно преобразовать их из строк в Platform:: DateTime. Я слышал, что Windows:: Globalization:: DateTimeFormatting является классом, который я использую, но я не вижу, как его использовать для этого. У кого-нибудь есть пример?
Как разобрать дату в приложении Metro (С++/CX)?
Ответ 1
Проекция WinRT на С++/CX отличается от управляемой (С#/VB) проекции несколькими способами, и одна из самых главных - в проекции основных типов (таких как Point
, Size
, String
и DateTime
).
Управляемый прогноз проектирует эти типы как типы .NET(со всей базовой поддержкой BCL), в то время как проекция С++ обычно минимально проектирует эти типы для взаимодействия, ожидая, что пользователь будет полагаться на поддержку библиотеки С++ для более сложных функций.
Итак, где в .NET подписанное 32-битовое целое становится System.Int32
(с его соответствующей функциональностью .Parse
) в С++, вы получаете обычный С++ 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
, и документация неверна; он не поддерживает синтаксический анализ и не предназначен для (только форматирования).
Ответ 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