Come posso convertire un timestamp Unix in DateTime e viceversa?

C’è questo codice di esempio, ma poi inizia a parlare di problemi al millisecondo / nanosecondo.

La stessa domanda è su MSDN, Seconds dall’epoca Unix in C # .

Questo è quello che ho ottenuto finora:

public Double CreatedEpoch { get { DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime(); TimeSpan span = (this.Created.ToLocalTime() - epoch); return span.TotalSeconds; } set { DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime(); this.Created = epoch.AddSeconds(value); } } 

Ecco di cosa hai bisogno:

 public static DateTime UnixTimeStampToDateTime( double unixTimeStamp ) { // Unix timestamp is seconds past epoch System.DateTime dtDateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc); dtDateTime = dtDateTime.AddSeconds( unixTimeStamp ).ToLocalTime(); return dtDateTime; } 

Oppure, per Java (che è diverso perché il timestamp è in millisecondi, non secondi):

 public static DateTime JavaTimeStampToDateTime( double javaTimeStamp ) { // Java timestamp is milliseconds past epoch System.DateTime dtDateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc); dtDateTime = dtDateTime.AddMilliseconds( javaTimeStamp ).ToLocalTime(); return dtDateTime; } 

L’ ultima versione di .NET (v4.6) ha aggiunto il supporto integrato per le conversioni temporali Unix. Ciò include sia da e che il tempo di Unix rappresentato da secondi o millisecondi.

  • Tempo Unix in secondi a UTC DateTimeOffset :
 DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000); 
  • DateTimeOffset in Unix tempo in secondi:
 long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds(); 
  • Tempo Unix in millisecondi a UTC DateTimeOffset :
 DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000); 
  • DateTimeOffset all’ora Unix in millisecondi:
 long unixTimeStampInMilliseconds = dateTimeOffset.ToUnixTimeMilliseconds(); 

Nota: questi metodi convertono in e da un DateTimeOffset UTC. Per ottenere una rappresentazione DateTime usa semplicemente le proprietà DateTimeOffset.UtcDateTime o DateTimeOffset.LocalDateTime :

 DateTime dateTime = dateTimeOffset.UtcDateTime; 

Data e ora in formato UNIX:

 public static double DateTimeToUnixTimestamp(DateTime dateTime) { return (TimeZoneInfo.ConvertTimeToUtc(dateTime) - new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds; } 

“L’UTC non cambia con un cambio di stagioni, ma l’ora locale o l’ora civile possono cambiare se una giurisdizione sul fuso orario osserva l’ora legale (ora legale). Ad esempio, UTC è di 5 ore prima (ovvero, più tardi nella giornata di) ora locale sulla costa orientale degli Stati Uniti durante l’inverno, ma 4 ore in anticipo mentre si osserva l’ora legale. ”

Quindi questo è il mio codice:

 TimeSpan span = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,DateTimeKind.Utc)); double unixTime = span.TotalSeconds; 

Fai attenzione, se hai bisogno di precisione superiore ai millisecondi!

I metodi .NET (v4.6) (ad esempio FromUnixTimeMilliseconds ) non forniscono questa precisione.

AddSeconds e AddMilliseconds tagliavano anche i microsecondi nel doppio.

Queste versioni hanno alta precisione:

Unix -> DateTime

 public static DateTime UnixTimestampToDateTime(double unixTime) { DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); long unixTimeStampInTicks = (long) (unixTime * TimeSpan.TicksPerSecond); return new DateTime(unixStart.Ticks + unixTimeStampInTicks, System.DateTimeKind.Utc); } 

DateTime -> Unix

 public static double DateTimeToUnixTimestamp(DateTime dateTime) { DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); long unixTimeStampInTicks = (dateTime.ToUniversalTime() - unixStart).Ticks; return (double) unixTimeStampInTicks / TimeSpan.TicksPerSecond; } 

Vedi IdentityModel.EpochTimeExtensions

 public static class EpochTimeExtensions { ///  /// Converts the given date value to epoch time. ///  public static long ToEpochTime(this DateTime dateTime) { var date = dateTime.ToUniversalTime(); var ticks = date.Ticks - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).Ticks; var ts = ticks / TimeSpan.TicksPerSecond; return ts; } ///  /// Converts the given date value to epoch time. ///  public static long ToEpochTime(this DateTimeOffset dateTime) { var date = dateTime.ToUniversalTime(); var ticks = date.Ticks - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).Ticks; var ts = ticks / TimeSpan.TicksPerSecond; return ts; } ///  /// Converts the given epoch time to a  with  kind. ///  public static DateTime ToDateTimeFromEpoch(this long intDate) { var timeInTicks = intDate * TimeSpan.TicksPerSecond; return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddTicks(timeInTicks); } ///  /// Converts the given epoch time to a UTC . ///  public static DateTimeOffset ToDateTimeOffsetFromEpoch(this long intDate) { var timeInTicks = intDate * TimeSpan.TicksPerSecond; return new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero).AddTicks(timeInTicks); } } 

Per integrare la risposta di ScottCher, mi sono ritrovato di recente nello scenario fastidioso di avere sia timecamp sia in formato UNIX sia in secondi che in millisecondi arbitrariamente insieme in un set di dati di input. Il seguente codice sembra gestire bene questo:

 static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); static readonly double MaxUnixSeconds = (DateTime.MaxValue - UnixEpoch).TotalSeconds; public static DateTime UnixTimeStampToDateTime(double unixTimeStamp) { return unixTimeStamp > MaxUnixSeconds ? UnixEpoch.AddMilliseconds(unixTimeStamp) : UnixEpoch.AddSeconds(unixTimeStamp); } 

La conversione di tempo Unix è nuova in .NET Framework 4.6.

È ora ansible convertire più facilmente i valori di data e ora in o da tipi di .NET Framework e ora Unix. Questo può essere necessario, ad esempio, durante la conversione dei valori temporali tra un client JavaScript e un server .NET. Le seguenti API sono state aggiunte alla struttura DateTimeOffset :

 static DateTimeOffset FromUnixTimeSeconds(long seconds) static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) long DateTimeOffset.ToUnixTimeSeconds() long DateTimeOffset.ToUnixTimeMilliseconds() 

Ho trovato la risposta giusta semplicemente confrontando la conversione in 1/1/1970 senza la regolazione dell’ora locale;

 DateTime date = new DateTime(2011, 4, 1, 12, 0, 0, 0); DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); TimeSpan span = (date - epoch); double unixTime =span.TotalSeconds; 
 DateTime unixEpoch = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); DateTime convertedTime = unixEpoch.AddMilliseconds(unixTimeInMillisconds); 

Ovviamente, è ansible rendere unixEpoch una statica globale, quindi è sufficiente che appaia una sola volta nel progetto e si può utilizzare AddSeconds se il tempo UNIX è in secondi.

Per andare dall’altra parte:

 double unixTimeInMilliseconds = timeToConvert.Subtract(unixEpoch).TotalMilliseconds; 

Tronca a Int64 e / o usa TotalSeconds secondo necessità.

Un tick Unix è 1 secondo (se ricordo bene) e un tick di .NET è di 100 nanosecondi.

Se hai riscontrato problemi con i nanosecondi, potresti provare a utilizzare AddTick (valore 10000000 *).

Avevo bisogno di convertire una struttura UNIX time (secondi, microsecondi) contenente UNIX time to DateTime senza perdere precisione e non ho trovato una risposta qui quindi ho pensato di aggiungere il mio:

 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); } 
 public static class UnixTime { private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); public static DateTime UnixTimeToDateTime(double unixTimeStamp) { return Epoch.AddSeconds(unixTimeStamp).ToUniversalTime(); } } 

puoi chiamare UnixTime.UnixTimeToDateTime (double datetime))

Per .NET 4.6 e versioni successive:

 public static class UnixDateTime { public static DateTimeOffset FromUnixTimeSeconds(long seconds) { if (seconds < -62135596800L || seconds > 253402300799L) throw new ArgumentOutOfRangeException("seconds", seconds, ""); return new DateTimeOffset(seconds * 10000000L + 621355968000000000L, TimeSpan.Zero); } public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) { if (milliseconds < -62135596800000L || milliseconds > 253402300799999L) throw new ArgumentOutOfRangeException("milliseconds", milliseconds, ""); return new DateTimeOffset(milliseconds * 10000L + 621355968000000000L, TimeSpan.Zero); } public static long ToUnixTimeSeconds(this DateTimeOffset utcDateTime) { return utcDateTime.Ticks / 10000000L - 62135596800L; } public static long ToUnixTimeMilliseconds(this DateTimeOffset utcDateTime) { return utcDateTime.Ticks / 10000L - 62135596800000L; } [Test] public void UnixSeconds() { DateTime utcNow = DateTime.UtcNow; DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow); long unixTimestampInSeconds = utcNowOffset.ToUnixTimeSeconds(); DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeSeconds(unixTimestampInSeconds); Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year); Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month); Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date); Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour); Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute); Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second); } [Test] public void UnixMilliseconds() { DateTime utcNow = DateTime.UtcNow; DateTimeOffset utcNowOffset = new DateTimeOffset(utcNow); long unixTimestampInMilliseconds = utcNowOffset.ToUnixTimeMilliseconds(); DateTimeOffset utcNowOffsetTest = UnixDateTime.FromUnixTimeMilliseconds(unixTimestampInMilliseconds); Assert.AreEqual(utcNowOffset.Year, utcNowOffsetTest.Year); Assert.AreEqual(utcNowOffset.Month, utcNowOffsetTest.Month); Assert.AreEqual(utcNowOffset.Date, utcNowOffsetTest.Date); Assert.AreEqual(utcNowOffset.Hour, utcNowOffsetTest.Hour); Assert.AreEqual(utcNowOffset.Minute, utcNowOffsetTest.Minute); Assert.AreEqual(utcNowOffset.Second, utcNowOffsetTest.Second); Assert.AreEqual(utcNowOffset.Millisecond, utcNowOffsetTest.Millisecond); } }