web-dev-qa-db-fra.com

Comment convertir le temps d'une époque en C #?

Comment convertissez-vous Unix Epoch time en temps réel en C #? (Epoque commençant le 1/1/1970)

341
hsatterwhite

Je suppose que vous voulez dire temps Unix , qui est défini comme le nombre de secondes depuis Minuit (UTC) le 1er janvier 1970.

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);
522
LukeH

Le dernière version de .Net (v4.6) vient d'ajouter le support intégré pour les conversions de temps Unix. Cela inclut à la fois vers et depuis le temps Unix représenté par secondes ou millisecondes.

  • Temps Unix en secondes à DateTimeOffset:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
  • DateTimeOffset au temps Unix en secondes:
long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
  • Temps Unix en millisecondes à DateTimeOffset:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
  • DateTimeOffset au temps Unix en millisecondes:
long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();

Remarque: Ces méthodes convertissent vers et à partir de DateTimeOffset. Pour obtenir une représentation DateTime, utilisez simplement la propriété DateTimeOffset.DateTime:

DateTime dateTime = dateTimeOffset.UtcDateTime;
177
i3arnon

Avec tout le mérite de LukeH, j'ai mis en place des méthodes d'extension faciles à utiliser:

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

Notez le commentaire ci-dessous de CodesInChaos selon lequel FromUnixTime ci-dessus retourne un DateTime avec un Kind de Utc, ce qui est correct, mais le ToUnixTime ci-dessus est beaucoup plus suspect car il ne tient pas compte du type de DateTime que le date est donné. Pour que date soit Kind soit Utc ou Local, utilisez 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 convertira un Local (ou Unspecified) DateTime en Utc.

si vous ne souhaitez pas créer l'instance Epoch DateTime lorsque vous passez de DateTime à Epoch, vous pouvez également effectuer les opérations suivantes:

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

Vous voulez réellement ajouter des millisecondes, pas des secondes. Ajouter des secondes vous donnera une exception hors de portée.

22
Darya

Si vous voulez de meilleures performances, vous pouvez utiliser cette version.

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

D'une référence rapide (BenchmarkDotNet) sous net471, j'obtiens ce numéro:

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

2x plus rapide contre version de LukeH (si la performance compte)

Ceci est similaire au fonctionnement interne de DateTime.

8
Jiri Sykora
// 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);
}

Devrait utiliser ToUniversalTime () pour l'objet DateTime.

7
Green Su

J'utilise les méthodes d'extension suivantes pour la conversion d'Epoch

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

    }
5
faisal00813

Utilisez la méthode DateTimeOffset.ToUnixTimeMilliseconds () Elle renvoie le nombre de millisecondes écoulées depuis le 1970-01-01T00: 00: 00.000Z.

Ceci n'est supporté qu'avec Framework 4.6 ou supérieur

var Epoch = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

C'est bien documenté ici DateTimeOffset.ToUnixTimeMilliseconds

L’autre solution consiste à utiliser les éléments suivants

long Epoch = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;

Pour obtenir l’époque en quelques secondes seulement, vous pouvez utiliser

 var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;

et convertissez le Epoch en DateTime avec la méthode suivante

private DateTime Epoch2UTCNow(int Epoch) 
{
    return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(Epoch); 
}
3
Vinod Srivastav

Si vous n'utilisez pas la version 4.6, cela peut aider Source: 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;
    }    
1
Siva Kandaraj

Dans le cas où vous auriez besoin de convertir un struct timeval (secondes, microsecondes) contenant UNIX time en DateTime sans perdre de précision, voici comment:

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