Wie kann ich eine DateTime in die Anzahl der Sekunden seit 1970 konvertieren?

119

Ich versuche, eine C # DateTime-Variable in Unix-Zeit zu konvertieren, dh die Anzahl der Sekunden seit dem 1. Januar 1970. Es sieht so aus, als ob eine DateTime tatsächlich als Anzahl der 'Ticks' seit dem 1. Januar 0001 implementiert ist.

Mein aktueller Gedanke ist, den 1. Januar 1970 wie folgt von meiner DateTime abzuziehen:

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0));
return span.TotalSeconds;

Gibt es einen besseren Weg?

Slider345
quelle
1
Mögliches Duplikat von Wie konvertiert man die Epochenzeit in C #?
Jpaugh

Antworten:

195

Das ist es im Grunde. Dies sind die Methoden, mit denen ich in und aus der Unix-Epoche konvertiere:

public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    return origin.AddSeconds(timestamp);
}

public static double ConvertToUnixTimestamp(DateTime date)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    TimeSpan diff = date.ToUniversalTime() - origin;
    return Math.Floor(diff.TotalSeconds);
}

Update: Ab .Net Core 2.1 und .Net Standard 2.1 kann eine DateTime gleich der Unix-Epoche aus der Statik abgerufen werden DateTime.UnixEpoch.

Dave Swersky
quelle
1
Beachten Sie, dass Sie für den Zeitstempeltyp long anstelle von int verwenden müssen, wenn Sie für genauere Zeitstempel oder Javascript Date () -Objektkompatibilität in Millisekunden konvertieren möchten.
Soviut
3
Hat bei mir nicht funktioniert. Diese Antwort hat es geschafft: stackoverflow.com/questions/249760/…
Zeezer
@Jonny - ToUniversalTime () wird in UTC konvertiert, sodass UTC berücksichtigt wird.
Dave Swersky
4
DateTime origin = new DateTime (1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); Interessant, dass niemand dies vorgeschlagen hat. Sehr oft haben Sie Millisekunden, die die Utc-Zeit darstellen. Und wenn Sie t specify this explicitly and somewhere later in code youToUniversalTime () nicht haben, haben Sie eine schlechte Utc-Zeit, da DateTime standardmäßig NICHT Utc ist.
Steavy
52

Wenn der Rest Ihres Systems mit DateTimeOffset anstelle von DateTime einverstanden ist, gibt es eine sehr praktische Funktion:

long unixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();
codeMonkey
quelle
7
Dies ist ein sauberer Weg, aber er ist nur in Framework 4.6 verfügbar. Msdn.microsoft.com/en-us/library/…
Oscar Fraxedas
1
Nett. Und natürlich können Sie für den Wechsel von Unix zu einem DateTimeOffset var time = DateTimeOffset.FromUnixTimeSeconds(5000); MS Doc
Jordan
22

Das einzige, was ich sehe, ist, dass es seit Mitternacht des 1. Januar 1970 UTC sein soll

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;
CaffGeek
quelle
7
Sollte es DateTime.UtcNow sein?
oferei
14

Sie möchten wahrscheinlich DateTime.UtcNow verwenden, um Zeitzonenprobleme zu vermeiden

TimeSpan span= DateTime.UtcNow.Subtract(new DateTime(1970,1,1,0,0,0)); 
David
quelle
Die einzige Möglichkeit, Zeitzonenprobleme zu vermeiden, besteht darin, 1) selig ignorant zu bleiben und nur eine Zeitzone zu unterstützen oder 2) Zeitzonen (mindestens) überall dort zu behandeln, wo Sie mit einem anderen System oder Endbenutzer kommunizieren. Insbesondere die interne Verwendung von UTC ist nur ein Teil des Kampfes. Im ersten Szenario verschlimmert das Hinzufügen von UTC-Datenzeiten das Problem tatsächlich, bis Sie bereit sind, alle (2) Schritte auszuführen, da Sie von der Unterstützung einer Zeitzone zur Unterstützung nur von UTC übergehen.
Jpaugh
1

Dieser Ansatz ist gut, wenn die betreffende Datums- und Uhrzeit in UTC angegeben ist oder die Ortszeit in einem Gebiet darstellt, in dem die Sommerzeit noch nie eingehalten wurde. Die DateTime-Differenzroutinen berücksichtigen nicht die Sommerzeit und betrachten daher den 1. Juni um Mitternacht als ein Vielfaches von 24 Stunden nach dem 1. Januar um Mitternacht. Mir ist in Windows nichts bekannt, das historische Sommerzeitregeln für die aktuelle Zeit meldet Ich glaube nicht, dass es eine gute Möglichkeit gibt, vor der letzten Änderung der Sommerzeitregel richtig damit umzugehen.

Superkatze
quelle
0

Sie können eine Startzeit und eine Endzeit von DateTime erstellen und dann endTime.Subtract (startTime) ausführen. Geben Sie dann Ihre span.Seconds aus.

Ich denke das sollte funktionieren.

Alec Sanger
quelle
0

Ich verwende das Jahr 2000 anstelle der Epochenzeit in meinem Kalkül. Das Arbeiten mit kleineren Stückzahlen ist einfach zu lagern und zu transportieren und JSON-freundlich.

Das Jahr 2000 war das zweite 946684800 der Epoche.

Das Jahr 2000 war das zweite 63082281600 vom 1. Januar 0001.

DateTime.UtcNow Ticks beginnen am 1. Januar 0001

Sekunden ab dem Jahr 2000 :

DateTime.UtcNow.Ticks/10000000-63082281600

Sekunden von der Unix-Zeit:

DateTime.UtcNow.Ticks/10000000-946684800

Zum Beispiel ist das Jahr 2020:

var year2020 = (new DateTime ()). AddYears (2019) .Ticks; // Da DateTime bereits im ersten Jahr beginnt

637134336000000000 Zecken seit dem 1. Januar 0001

63713433600 Sekunden seit dem 1. Januar 0001

1577836800 Sekunden seit der Epoche

631152000 Sekunden seit dem Jahr 2000

Verweise:

Epoch Time Converter: https://www.epochconverter.com

Konverter für Jahr 1: https://www.epochconverter.com/seconds-days-since-y0

profimedica
quelle