Standardkonforme Konvertierung von std :: time_t nach System :: DateTime?
Ich habe bereits einige Antworten gefunden, die sich auf das Konvertieren von a beziehenstd::time_t
Wert aufSystem::DateTime
und zurück. Allerdings scheinen fast alle Antworten diese Art von zu vernachlässigenstd::time_t
ist eigentlich im Standard undefiniert. Die meisten Lösungen werden nur gegossenstd::time_t
auf was auch immer benötigt wird oder arithmetische Operationen auf a anwendenstd::time_t
Objekt, das möglich ist, da es ein arithmetischer Typ ist, aber es gibt keine Angabe über das Ergebnis einer solchen Operation. ich weiß dasdie meisten Compiler definierentime_t
als einint
von einiger größe ist aber die tatsache alleine, dass es sich von geändert hatint32
zuint64
in vielen umsetzungen zeigt sich in jüngerer zeit, dass änderungen tatsächlich möglich sind.
Also habe ich mir welche Lösung ausgedachtsollte arbeiten mit jeder Art vonstd::time_t
. Es funktioniert nach dem, was ich gesehen habe. Aber ich habe mich gefragt -Gibt es mögliche Fallstricke, die mir möglicherweise nicht bewusst sind?
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)
Es wurden 3 Annahmen getroffen:
Resultierendstd::time_t
sollte in UTC sein, da es keine Informationen zur Lokalisierung enthältResultierendSystem::DateTime
sollte seit Ortszeit seinSystem::DateTime::Now
gibt eine lokalisierte zurückDateTime
makeUtcTime
ist eine Hilfsfunktion, die einestd::tm
aus den angegebenen Werten und erstellt eine UTCstd::time_t
heraus. Dies wird derzeit mit implementiert_mkgmtime
weil sich unser Interop-Code auf das Vorhandensein von Microsoft-Erweiterungen verlassen kann. Eine UTC-Version vonmktime
ist auch in anderen Compilern verfügbar (Standardmktime
Ortszeit erwartet).2 weniger wichtige Dinge zu beachten:
Dasconst_cast
ist notwendig, da das marshal_as-template a erwartetconst T&
als Parameter und ich kann nicht auf die Eigenschaften eines konstanten .NET-Werttypobjekts zugreifen. Es könnte jedoch eine bessere Lösung geben.Sollte dieunix_epoch...
Zeug seinstatic const
?(Ich war mir nicht sicher, ob dies auf "Programmers Exchange" veröffentlicht werden sollte, da es sich eher um eine Diskussion handelt, aber da es sich um eine sehr spezifische C ++ - Frage handelt, dachte ich, SO wäre der bessere Ort, um Fragen zu stellen.)