2010-05-21 13 views
275

Wie konvertiert man Unix epoch time in Echtzeit in C#? (Epoch Beginn 1.1.1970)Wie konvertiert man die Epochzeit in C#?

+1

Wenn ich etwas nicht vermisse, ist die "Epoche" einfach der Ursprung eines bestimmten Zeitschemas. Beispiele sind 1/1/0001, 1/1/1970 und 1/1/2000. Es ist eher ein Attribut eines Schemas als ein Schema (z. B. Julian) selbst. –

+5

Zeit seit der Epoche ist die Anzahl der Sekunden seit dem 1. Januar 1970 UTC. –

+12

@ Taylor Das ist die Zeit für Unix-Zeit, und es ist wahrscheinlich richtig, aber es ist nicht die einzige gültige Epoche. Unix-Zeit Benutzer sollten sich in diesem Punkt nicht verwirren. –

Antwort

441

Ich nehme an, Sie meinen Unix time, die als die Anzahl der Sekunden seit Mitternacht (UTC) am 1. Januar 1970

definiert ist
public static DateTime FromUnixTime(long unixTime) 
{ 
    return epoch.AddSeconds(unixTime); 
} 
private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
+52

Um dies richtig funktionieren zu lassen, musste ich .AddSeconds zu .AddMilliseconds ändern. Sie müssen wissen, ob Ihre Nummer aus Sekunden oder Millisekunden kommt, um das richtige Ergebnis zu erhalten. So zum Beispiel das folgende Datum: 1406310305188 (25. Juli 2014).http://www.epochconverter.com/ lässt Sie auch Ihre Konvertierungsergebnisse überprüfen. – jrandomuser

+3

Sie sollten entweder den Parametertyp auf double ändern (weil AddSeconds double akzeptiert und daher zu double reduziert wird) oder der Methodebeschreibung einen Disclaimer hinzufügen, so dass nur 53 von 64 Genauigkeitsbits im Argument beibehalten werden. – tomosius

+3

@jrandomuser: Unix Epoche wird traditionell als * Sekunden * seit The Epoch dargestellt. Es ist üblich geworden, * Millisekunden * seit The Epoch (zum Beispiel JavaScript) zu verwenden, aber die klassische Definition ist Sekunden. Bottom-Line, wissen Sie einfach, was Ihr Eingabewert ist (Sekunden, Millisekunden, Ticks, was auch immer) und verwenden Sie die richtige 'AddXYZ'-Methode. –

135

Mit allen Kredit zu LukeH zusammen einige Erweiterungsmethoden für die einfache Nutzung, ich habe:

public static DateTime FromUnixTime(this long unixTime) 
{ 
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
    return epoch.AddSeconds(unixTime); 
} 

public static long ToUnixTime(this DateTime date) 
{ 
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
    return Convert.ToInt64((date - epoch).TotalSeconds); 
} 

Hinweis Kommentar unterhalb von CodesInChaos, dass die oben FromUnixTime ein DateTime mit einem Kind von Utc, das ist in Ordnung, gibt aber den ab ove ToUnixTime ist viel verdächtiger darin, dass nicht berücksichtigt, welche Art von DateTime der angegebenen date ist. Damit für date ‚s Kind wird entweder Utc oder Local verwenden ToUniversalTime:

public static long ToUnixTime(this DateTime date) 
{ 
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
    return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds); 
} 

ToUniversalTime konvertiert eine Local (oder Unspecified) DateTime-Utc.

, wenn Sie nicht wollen, die Epoche Datetime-Instanz erstellen, wenn sie von Datetime Bewegen Sie auch tun, um Epoche können:

public static long ToUnixTime(this DateTime date) 
{ 
    return (date.ToUniversalTime().Ticks - 621355968000000000)/10000000; 
} 
+5

'ToUnixTime' funktioniert nur korrekt, wenn das Datum in Utc ist. Fügen Sie entweder einen Scheck hinzu oder konvertieren Sie ihn. (Persönlich bevorzuge ich den Scheck) – CodesInChaos

+1

Habe gerade die letzte Stunde damit verbracht herauszufinden, warum das nicht funktioniert. Sie müssen in Millisekunden arbeiten * nicht * Sekunden !!! – KristianB

+7

@KristianB: "Unix-Zeit" ist traditionell Sekunden, nicht Millisekunden, seit The Epoch, obwohl ich in diesen Tagen bin vorsichtig zu prüfen, welche Definition jemand verwendet. Sekunden waren früher gut genug und gaben uns einen vernünftigen Bereich auf beiden Seiten der Epoch in 32-Bit-Werten mit Vorzeichen. (Und deshalb, kurz nach 3:14 Uhr am 19. Januar, 2038 GMT könnte für einige eine schlechte Zeit sein ...) Die Verwendung von Millisekunden ist eine modernere Methode, da wir routinemäßig 64-Bit-Werte werfen können (beide integral und Double-Precision IEEE-754) ... –

6
// convert datetime to unix epoch seconds 
public static long ToUnixTime(DateTime date) 
{ 
    var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
    return Convert.ToInt64((date.ToUniversalTime() - epoch).TotalSeconds); 
} 

Sollte verwenden ToUniversalTime() für das Objekt Datetime.

17

Sie möchten tatsächlich Millisekunden (Millisekunden) hinzufügen, nicht Sekunden. Wenn Sie Sekunden hinzufügen, erhalten Sie eine Ausnahme außerhalb des Bereichs.

+0

Warum ist das? http://www.epochconverter.com/ Es sagt, dass Sie die Anzahl der Sekunden seit dem 1. Januar 970 nicht hinzufügen. –

+0

Wenn Sie von ms gehen Sie offensichtlich wollen 'AddMillis' und wenn Sie von Sekunden beginnen Sie offensichtlich' AddSeconds'. – Shoe

+0

Ich hatte das selbe Problem, dass ich außerhalb der Reichweite war, wenn ich Sekunden benutzte. Die Unix-Zeit, die ich konvertieren wollte, war in Millisekunden. Ich dachte es wäre in Sekunden. Ich denke, einige Unix-Zeiten werden in Millisekunden gemessen. – DoodleKana

-3

Hier ist meine Lösung:

public long GetTime() 
{ 
    DateTime dtCurTime = DateTime.Now.ToUniversalTime(); 

    DateTime dtEpochStartTime = Convert.ToDateTime("1/1/1970 0:00:00 AM"); 

    TimeSpan ts = dtCurTime.Subtract(dtEpochStartTime); 

    double epochtime; 

    epochtime = ((((((ts.Days * 24) + ts.Hours) * 60) + ts.Minutes) * 60) + ts.Seconds); 

    return Convert.ToInt64(epochtime); 
} 
+7

macht dieses Konto für Schaltjahre und Schaltsekunden usw.? – Jodrell

+1

Um auf den vorherigen Kommentar zu erweitern, hier ist ein kurzes Video, das erklärt, warum die Zeit kompliziert ist und warum sollten Sie nicht versuchen, es selbst zu tun: https://www.youtube.com/watch?v=5wpm-gesOY – vmrob

0

Falls Sie eine timeval struct (Sekunden, Mikrosekunden) konvertieren müssen UNIX time-DateTime ohne Präzision enthält, zu verlieren, das ist, wie:

DateTime _epochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
private DateTime UnixTimeToDateTime(Timeval unixTime) 
{ 
    return _epochTime.AddTicks(
     unixTime.Seconds * TimeSpan.TicksPerSecond + 
     unixTime.Microseconds * TimeSpan.TicksPerMillisecond/1000); 
} 
117

Die latest version of .Net (v4.6) gerade eingebaute Unterstützung für Unix-Zeitkonvertierungen hinzugefügt. Dies umfasst sowohl die Unix-Zeit als auch die Unix-Zeit, die entweder durch Sekunden oder Millisekunden repräsentiert wird.

  • Unix Zeit in Sekunden DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000); 
  • DateTimeOffset auf Unix Zeit in Sekunden:

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds(); 
  • Unix Zeit in Millisekunden DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000); 
  • DateTimeOffset auf Unix-Zeit in Millisekunden:

long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds(); 

Hinweis: Diese Methoden konvertieren und von DateTimeOffset. Um eine DateTime Darstellung einfach die DateTimeOffset.DateTime Eigenschaft:

DateTime dateTime = dateTimeOffset.UtcDateTime; 
+0

Ich bin "DateTimeOffset" zu bekommen, enthält keine Definition für "FromUnixTimeSeconds". Wie würde ich das Problem lösen? –

+0

@HappyBird Sind Sie auf .NET 4.6 oder höher? – i3arnon

0

Wenn Sie nicht 4.6 verwenden, können diese Quelle helfen:System.IdentityModel.Tokens

/// <summary> 
    /// DateTime as UTV for UnixEpoch 
    /// </summary> 
    public static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); 

    /// <summary> 
    /// Per JWT spec: 
    /// Gets the number of seconds from 1970-01-01T0:0:0Z as measured in UTC until the desired date/time. 
    /// </summary> 
    /// <param name="datetime">The DateTime to convert to seconds.</param> 
    /// <remarks>if dateTimeUtc less than UnixEpoch, return 0</remarks> 
    /// <returns>the number of seconds since Unix Epoch.</returns> 
    public static long GetIntDate(DateTime datetime) 
    { 
     DateTime dateTimeUtc = datetime; 
     if (datetime.Kind != DateTimeKind.Utc) 
     { 
      dateTimeUtc = datetime.ToUniversalTime(); 
     } 

     if (dateTimeUtc.ToUniversalTime() <= UnixEpoch) 
     { 
      return 0; 
     } 

     return (long)(dateTimeUtc - UnixEpoch).TotalSeconds; 
    }  
4

Ich verwende folgende Erweiterungsmethoden für Epoche Umwandlung

public static int GetEpochSeconds(this DateTime date) 
    { 
     TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1); 
     return (int)t.TotalSeconds; 
    } 

public static DateTime FromEpochSeconds(this DateTime date, long EpochSeconds) 
    { 
     var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 
     return epoch.AddSeconds(EpochSeconds); 

    } 
1

Wenn Sie eine bessere Leistung wünschen, können Sie diese Version verwenden.

public const long UnixEpochTicks = 621355968000000000; 
public const long TicksPerMillisecond = 10000; 
public const long TicksPerSecond = TicksPerMillisecond * 1000; 

//[MethodImpl(MethodImplOptions.AggressiveInlining)] 
public static DateTime FromUnixTimestamp(this long unixTime) 
{ 
    return new DateTime(UnixEpochTicks + unixTime * TicksPerSecond); 
} 

Von der schnellen Benchmark (BenchmarkDotNet) unter net471 bekomme ich diese Nummer:

 Method |  Mean |  Error | StdDev | Scaled | 
-------------- |---------:|----------:|----------:|-------:| 
StackOverflow | 5.897 ns | 0.0897 ns | 0.0795 ns | 1.00 | 
     MyCustom | 3.176 ns | 0.0573 ns | 0.0536 ns | 0.54 | 

2x schneller gegen LukeH Version (wenn die Leistung mater)

Dies ist ähnlich wie Datetime intern Arbeit.

Verwandte Themen