Стандартный совместимый способ преобразования std :: time_t в System :: DateTime?
Я уже нашел несколько ответов, связанных с преобразованиемstd::time_t
значение дляSystem::DateTime
и назад. Тем не менее, почти все ответы, кажется, пренебрегают, что типstd::time_t
на самом деле не определено в стандарте. Большинство решений просто брошеныstd::time_t
к чему угодно или применять арифметические операции кstd::time_t
объект, который возможен, так как это арифметический тип, но нет никакой спецификации о результате такой операции. я знаю этонаиболее компиляторы определяютtime_t
какint
некоторого размера, но тот факт, что он изменился сint32
вint64
во многих реализациях в последнее время показано, что изменения действительно возможны.
Итак, я пришел с этим решением, котороедолжен работать с любым типомstd::time_t
, Это работает из того, что я видел. Но мне было интересно -Есть ли какие-либо возможные подводные камни, о которых я мог не знать?
template <>
inline System::DateTime marshal_as(const std::time_t &from_object)
{
// Returns DateTime in Local time format from time_t (assumed to be UTC)
const auto unix_epoch = makeUtcTime(1970, 1, 1, 0, 0, 0);
const auto unix_epoch_dt = System::DateTime(1970, 1, 1, 0, 0, 0, System::DateTimeKind::Utc);
const auto secondsSinceEpoch = std::difftime(from_object, unix_epoch);
return const_cast<System::DateTime&>(unix_epoch_dt).AddSeconds(secondsSinceEpoch).ToLocalTime();
} // end of System::DateTime marshal_as(const std::time_t &from_object)
template <>
inline std::time_t marshal_as(const System::DateTime &from_object)
{
// Returns time_t in UTC format from DateTime
auto from_dt = const_cast<System::DateTime&>(from_object).ToUniversalTime();
return makeUtcTime(from_dt.Year, from_dt.Month, from_dt.Day, from_dt.Hour, from_dt.Minute, from_dt.Second);
} // end of std::time_t marshal_as(const System::DateTime &from_object)
Было сделано 3 предположения:
Результирующийstd::time_t
должен быть в UTC, так как он не содержит никакой информации о локализацииРезультирующийSystem::DateTime
должно быть местное время сSystem::DateTime::Now
возвращает локализованныйDateTime
makeUtcTime
вспомогательная функция, создающаяstd::tm
из предоставленных значений и создает UTCstd::time_t
из этого. В настоящее время это осуществляется с использованием_mkgmtime
потому что наш код взаимодействия может безопасно полагаться на существование расширений Microsoft. Тем не менее, версия UTCmktime
легко доступен и в других компиляторах (стандартноmktime
ожидает местное время).2 менее важные вещи для рассмотрения:
const_cast
необходимо, потому что шаблон marshal_as ожидаетconst T&
в качестве параметра, и я не могу получить доступ к свойствам объекта типа const .NET. Однако может быть лучшее решение.Еслиunix_epoch...
вещи бытьstatic const
?(Я не был уверен, стоит ли это публиковать на «Бирже программистов», так как это скорее дискуссия, но, поскольку это очень специфический вопрос C ++, я подумал, что SO может быть лучше задать)