web-dev-qa-db-fra.com

Comment convertir un horodatage Unix en DateTime et inversement?

Il y a cet exemple de code, mais ensuite il commence à parler de problèmes millisecondes/nanosecondes.

La même question est sur MSDN, secondes depuis l’époque Unix en C #.

C'est ce que j'ai jusqu'ici:

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);
  }
}
647
Mark Ingram

Voici ce dont vous avez besoin:

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;
}

Ou, pour Java (ce qui est différent car l'horodatage est exprimé en millisecondes et non en secondes):

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;
}
885
ScottCher

La dernière version de .NET (v4.6) a ajouté la prise en charge intégrée des conversions de temps Unix. Cela inclut à la fois vers et depuis le temps Unix représenté par secondes ou millisecondes.

  • Temps Unix en secondes en UTC DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
  • DateTimeOffset à temps Unix en secondes:

long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
  • Temps Unix en millisecondes en UTC DateTimeOffset:

DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
  • DateTimeOffset à l'heure Unix en millisecondes:

long unixTimeStampInMilliseconds = dateTimeOffset.ToUnixTimeMilliseconds();

Remarque: Ces méthodes permettent de convertir en UTC DateTimeOffset. Pour obtenir une représentation DateTime, utilisez simplement les propriétés DateTimeOffset.UtcDateTime ou DateTimeOffset.LocalDateTime:

DateTime dateTime = dateTimeOffset.UtcDateTime;
310
i3arnon

DateTime à l'horodatage UNIX:

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

"UTC ne change pas avec le changement de saison, mais l'heure locale ou l'heure civile peut changer si une juridiction de fuseau horaire observe l'heure d'été (heure d'été). Par exemple, UTC a 5 heures d'avance (c'est-à-dire plus tard heure locale sur la côte est des États-Unis pendant l’hiver, mais 4 heures à l’avance lorsque l’heure avancée est observée. "

Donc voici mon code:

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

Attention, si vous avez besoin d'une précision supérieure à la milliseconde!

Les méthodes .NET (v4.6) (par exemple, FromUnixTimeMilliseconds ) ne fournissent pas cette précision.

AddSeconds et AddMilliseconds également couper les microsecondes dans le double.

Ces versions ont une grande précision:

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;
}
20
Felix Keil

Voir IdentityModel.EpochTimeExtensions

public static class EpochTimeExtensions
{
    /// <summary>
    /// Converts the given date value to Epoch time.
    /// </summary>
    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;
    }

    /// <summary>
    /// Converts the given date value to Epoch time.
    /// </summary>
    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;
    }

    /// <summary>
    /// Converts the given Epoch time to a <see cref="DateTime"/> with <see cref="DateTimeKind.Utc"/> kind.
    /// </summary>
    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);
    }

    /// <summary>
    /// Converts the given Epoch time to a UTC <see cref="DateTimeOffset"/>.
    /// </summary>
    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);
    }
}
13
orad

Pour compléter la réponse de ScottCher, je me suis récemment retrouvé dans le scénario agaçant de mélanger de manière arbitraire des horodatages UNIX de secondes et de millisecondes dans un jeu de données d'entrée. Le code suivant semble bien gérer cela:

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);
}
10
Chris Thoman

La conversion de temps Unix est nouvelle dans .NET Framework 4.6.

Vous pouvez désormais convertir plus facilement les valeurs de date et d'heure en types .NET Framework et en temps Unix. Cela peut être nécessaire, par exemple, lors de la conversion de valeurs temporelles entre un client JavaScript et un serveur .NET. Les API suivantes ont été ajoutées à la structure DateTimeOffset :

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

J'ai trouvé la bonne réponse en comparant simplement la conversion au 1/1/1970 sans l'ajustement de l'heure 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;
5
n8CodeGuru
DateTime unixEpoch = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
DateTime convertedTime = unixEpoch.AddMilliseconds(unixTimeInMillisconds);

Bien entendu, vous pouvez définir unixEpoch en tant que statique globale. Il ne doit donc apparaître qu'une seule fois dans votre projet et vous pouvez utiliser AddSeconds si le délai UNIX est exprimé en secondes.

Pour aller dans l'autre sens:

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

Tronquer à Int64 et/ou utiliser TotalSeconds si nécessaire.

3
Hot Licks
var dt = DateTime.Now; 
var unixTime = ((DateTimeOffset)dt).ToUnixTimeSeconds();

// 1510396991

var dt = DateTimeOffset.FromUnixTimeSeconds(1510396991);

// [11.11.2017 10:43:11 +00: 00]

2
mesut

Un tick Unix dure 1 seconde (si je me souviens bien), et un tick .NET correspond à 100 nanosecondes. 

Si vous rencontrez des problèmes en nanosecondes, essayez d’utiliser AddTick (valeur 10000000 *).

2
Luk

Je devais convertir un timeval struct (secondes, microsecondes) contenant UNIX time en DateTime sans perdre de précision et n'ayant pas trouvé de réponse ici, j'ai donc pensé ajouter le mien:

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);
}
1
i3arnon
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();
        }
    }

vous pouvez appeler UnixTime.UnixTimeToDateTime (double datetime))

0
madan

À partir de .net 4.6, vous pouvez le faire:

var dateTime = DateTimeOffset.FromUnixTimeSeconds(unixDateTime).DateTime;
0
Yang Zhang