Comment convertir le temps de l'époque Unix en temps réel en C #? (Epoque débutant le 1/1/1970)
Comment convertir le temps de l'époque Unix en temps réel en C #? (Epoque débutant le 1/1/1970)
Réponses:
Je suppose que vous voulez dire l' heure Unix , qui est définie 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);
AddXYZ
méthode.
La dernière version de .Net (v4.6) vient d'ajouter la prise en charge intégrée des conversions de temps Unix. Cela inclut le temps vers et depuis Unix représenté par des secondes ou des millisecondes.
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
en temps Unix en secondes:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
en Unix en millisecondes:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
Remarque: Ces méthodes convertissent vers et depuis DateTimeOffset
. Pour obtenir une DateTime
représentation, utilisez simplement la DateTimeOffset.DateTime
propriété:
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
Comment pourrais-je résoudre ce problème?
Avec tout le mérite de LukeH, j'ai mis en place quelques méthodes d'extension pour une utilisation facile:
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 ce qui précède FromUnixTime
renvoie un DateTime
avec un Kind
de Utc
, ce qui est bien, mais ce qui précède ToUnixTime
est beaucoup plus suspect car cela ne tient pas compte du type deDateTime
donné date
. Pour permettre date
de » Kind
l'être 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 voulez pas créer l'instance epoch DateTime lors du passage de DateTime à epoch, vous pouvez également faire:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTime
ne fonctionne correctement que si la date est en Utc. Ajoutez un chèque ou convertissez-le. (Personnellement, je préfère le chèque)
milliseconds
pas secondes !!!
AddMilliseconds
et vous devez utiliser Double NOT Float. Sinon, vous vous retrouverez avec un mauvais moment.
Vous voulez réellement ajouter des millisecondes (millisecondes), pas des secondes. L'ajout de secondes vous donnera une exception hors de portée.
AddMillis
et si vous partez de secondes, vous voulez évidemment AddSeconds
.
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);
}
À partir d'un benchmark 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 la version de LukeH (si la performance est importante)
Ceci est similaire au fonctionnement interne de DateTime.
Utilisez la méthode DateTimeOffset.ToUnixTimeMilliseconds () Elle renvoie le nombre de millisecondes qui se sont écoulées depuis le 1970-01-01T00: 00: 00.000Z.
Ceci n'est pris en charge 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 ce qui suit
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
Pour obtenir l'EPOCH 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);
}
.Ticks
, vous récupérerez une belle instance TimeSpan de la soustraction 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);
}
Doit utiliser ToUniversalTime () pour l'objet DateTime.
J'utilise les méthodes d'extension suivantes pour la conversion d'époque
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);
}
Pour ne pas vous soucier d'utiliser des millisecondes ou des secondes, faites simplement:
public static DateTime _ToDateTime(this long unixEpochTime)
{
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var date = epoch.AddMilliseconds(unixEpochTime);
if (date.Year > 1972)
return date;
return epoch.AddSeconds(unixEpochTime);
}
Si le temps de l'époque est en secondes, il n'y a aucun moyen de passer l'année 1972 en ajoutant des millisecondes.
Si vous n'utilisez pas 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;
}
using Microsoft.IdentityModel.Tokens; ... EpochTime.GetIntDate(dateTime);
Dans le cas où vous devez convertir une structure temporelle (secondes, microsecondes) contenant UNIX time
en DateTime
sans perdre en 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);
}
Depuis .Net 4.6 et supérieur, veuillez utiliser DateTimeOffset.Now.ToUnixTimeSeconds ()
Voici ma solution:
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);
}