Comment convertissez-vous Unix Epoch time en temps réel en C #? (Epoque commençant le 1/1/1970)
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);
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.
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
au temps Unix en secondes:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
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;
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;
}
Vous voulez réellement ajouter des millisecondes, pas des secondes. Ajouter des secondes vous donnera une exception hors de portée.
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.
// 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.
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);
}
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);
}
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;
}
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);
}