Comment convertir un horodatage Unix en DateTime et inversement?
-
05-07-2019 - |
Question
Il y a cet exemple de code, mais ensuite il commence à parler de problèmes millisecondes / nanosecondes.
La même question concerne MSDN, secondes depuis l'époque Unix en C # .
Voici 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);
}
}
La solution
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;
}
Autres conseils
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 pour UTC
DateTimeOffset
:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
-
DateTimeOffset
à la durée Unix en secondes:
long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
- Temps Unix en millisecondes jusqu'à UTC
DateTimeOffset
:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
-
DateTimeOffset
à l'heure Unix en millisecondes:
long unixTimeStampInMilliseconds = dateTimeOffset.ToUnixTimeMilliseconds();
Remarque: ces méthodes permettent de convertir un code UTC DateTimeOffset
. Pour obtenir une représentation DateTime
, utilisez simplement les propriétés DateTimeOffset.UtcDateTime
ou DateTimeOffset.LocalDateTime
:
DateTime dateTime = dateTimeOffset.UtcDateTime;
Horodatage DateTime sur UNIX:
public static double DateTimeToUnixTimestamp(DateTime dateTime)
{
return (TimeZoneInfo.ConvertTimeToUtc(dateTime) -
new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
}
UTC ne change pas en fonction des saisons, mais de l’heure locale ou civile l'heure peut changer si une juridiction de fuseau horaire observe l'heure d'été heure (heure d'été). Par exemple, UTC a 5 heures d’avance (c’est-à-dire plus tard dans la journée que) l'heure locale sur la côte est des États-Unis Aux États-Unis en hiver, mais 4 heures à l’avance lorsque l’heure avancée est observé là-bas.
Voici donc mon code:
TimeSpan span = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,DateTimeKind.Utc));
double unixTime = span.TotalSeconds;
Faites attention si vous avez besoin d'une précision supérieure à la milliseconde!
Lesméthodes .NET (v4.6) ( FromUnixTimeMilliseconds , par exemple) ne fournissent pas cette précision.
AddSeconds et AddMilliseconds ont également coupé 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;
}
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);
}
}
Pour compléter la réponse de ScottCher, je me suis récemment retrouvé dans le désagréable scénario que des horodatages UNIX en secondes et en millisecondes soient mélangés de manière arbitraire 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);
}
La conversion du temps Unix est nouvelle dans .NET Framework 4.6.
Vous pouvez maintenant plus facilement convertir 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()
J'ai trouvé la bonne réponse en comparant simplement la conversion au 1/1/1970 sans le réglage 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;
DateTime unixEpoch = DateTime.ParseExact("1970-01-01", "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
DateTime convertedTime = unixEpoch.AddMilliseconds(unixTimeInMillisconds);
Bien sûr, on peut faire de unixEpoch
un statique global, de sorte qu'il ne doit apparaître qu'une seule fois dans votre projet et que l'on peut utiliser AddSeconds
si le temps UNIX est écoulé. secondes.
Pour aller dans l'autre sens:
double unixTimeInMilliseconds = timeToConvert.Subtract(unixEpoch).TotalMilliseconds;
Tronquez-vous sur Int64 et / ou utilisez TotalSeconds
selon vos besoins.
Un tick Unix dure 1 seconde (si je me souviens bien) et un tick .NET correspond à 100 & nbsp; nanosecondes.
Si vous rencontrez des problèmes en nanosecondes, essayez d’utiliser AddTick (valeur 10000000 *).
var dt = DateTime.Now;
var unixTime = ((DateTimeOffset)dt).ToUnixTimeSeconds();
// 1510396991
var dt = DateTimeOffset.FromUnixTimeSeconds(1510396991);
// [11.11.2017 10:43:11 +00: 00]
À partir de .net 4.6, vous pouvez le faire:
var dateTime = DateTimeOffset.FromUnixTimeSeconds(unixDateTime).DateTime;
Je devais convertir une la structure de timeval . (secondes, microsecondes) contenant heure UNIX
en DateTime
sans perte de précision et n'ayant trouvé aucune 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);
}
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 Unix Time.Unix Time To DateTime (double date / heure))
Pour .NET 4.6 et versions ultérieures:
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);
}
}