Comment puis-je convertir un timestamp Unix en DateTime et vice versa?
il y a cet exemple de code, mais il commence à parler des problèmes de milliseconde / nanoseconde.
la même question Est sur MSDN, secondes depuis L'époque Unix en C# .
C'est ce que j'ai obtenu jusqu'à présent:
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);
}
}
14 réponses
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 (qui est différent, car l'heure est exprimée en millisecondes, non pas 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;
}
The latest version of .NET (v4.6) a ajouté le support intégré pour les conversions de temps Unix. Cela inclut à la fois le temps Unix et le temps Unix représenté par des secondes ou des millisecondes.
- Unix temps en secondes à l'UTC
DateTimeOffset
:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
-
DateTimeOffset
Unix temps en secondes:
long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
- Unix time in millisecondes to UTC
DateTimeOffset
:
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
-
DateTimeOffset
Unix temps en millisecondes:
long unixTimeStampInMilliseconds = dateTimeOffset.ToUnixTimeMilliseconds();
Note: Ces méthodes sont converties en UTC DateTimeOffset
. Pour obtenir une représentation DateTime
il suffit d'utiliser le DateTimeOffset.UtcDateTime
ou DateTimeOffset.LocalDateTime
propriétés de:
DateTime dateTime = dateTimeOffset.UtcDateTime;
DateTime to UNIX timestamp:
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 avec le changement des saisons, mais l'heure locale ou l'heure civile peut changer si une fois la zone de compétence observe l'heure d'été (heure d'été). Par exemple, UTC a 5 heures d'avance sur (c'est-à-dire plus tard dans la journée que) l'heure locale sur la côte Est des États-Unis pendant l'hiver, mais 4 heures d'avance pendant que l'on observe le passage à l'heure d'été."
donc c'est mon code:
TimeSpan span = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0,DateTimeKind.Utc));
double unixTime = span.TotalSeconds;
soyez prudent, si vous avez besoin de précision supérieure à millisecondes!
.NET (v4.6) les méthodes (par exemple Fromunixtimemillisecondes ) ne fournissent pas cette précision.
Addsecondes and Addmillisecondes also cut off the microsecondes in the double.
ces versions ont une haute 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 scénario ennuyeux d'avoir à la fois secondes et millisecondes Unix timestamps arbitrairement mélangés ensemble dans un ensemble 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 de temps Unix est nouvelle dans le cadre de .NET 4.6.
vous pouvez maintenant convertir plus facilement les valeurs de date et d'heure vers ou depuis les types de Framework .NET et Unix time. Cela peut être nécessaire, par exemple, lors de la conversion de valeurs de temps 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 juste en comparant la conversion au 1/1/1970 avec 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;
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, donc il ne doit apparaître qu'une seule fois dans votre projet, et on peut utiliser AddSeconds
si le temps UNIX est en secondes.
aller dans l'autre sens:
double unixTimeInMilliseconds = timeToConvert.Subtract(unixEpoch).TotalMilliseconds;
tronquer à Int64 et/ou utiliser TotalSeconds
au besoin.
un tic Unix est de 1 seconde (si je me souviens bien), et un tic.net est de 100 nanosecondes.
si vous avez rencontré des problèmes avec les nanosecondes, vous pouvez essayer D'utiliser AddTick(valeur 10000000*).
j'avais besoin de convertir une timeval struct (secondes, microsecondes) contenant UNIX time
en DateTime
sans perdre de précision et je n'ai pas trouvé de réponse ici donc j'ai pensé que je pourrais juste ajouter la mienne:
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 UnixTime.UnixTimeToDateTime (double datetime))
pour .NET 4.6 et suivants:
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);
}
}