Wie konvertiert man Unix- Epochenzeit in C # in Echtzeit? (Epoche beginnend am 1.1.1970)
Wie konvertiert man Unix- Epochenzeit in C # in Echtzeit? (Epoche beginnend am 1.1.1970)
Antworten:
Ich nehme an, Sie meinen die Unix-Zeit , die als die Anzahl der Sekunden seit Mitternacht (UTC) am 1. Januar 1970 definiert ist.
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
Methode.
Die neueste Version von .Net (v4.6) hat gerade die integrierte Unterstützung für Unix- Zeitkonvertierungen hinzugefügt. Dies schließt sowohl die Unix-Zeit als auch die Unix-Zeit ein, die entweder durch Sekunden oder Millisekunden dargestellt wird.
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
Unix-Zeit in Sekunden:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
Unix-Zeit in Millisekunden:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
Hinweis: Diese Methoden konvertieren nach und von DateTimeOffset
. Um eine DateTime
Darstellung zu erhalten, verwenden Sie einfach die DateTimeOffset.DateTime
Eigenschaft:
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
Wie würde ich das lösen?
Mit aller Ehre für LukeH habe ich einige Erweiterungsmethoden für die einfache Verwendung zusammengestellt:
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);
}
Beachten Sie den Kommentar von CodesInChaos unten, dass das obige FromUnixTime
ein DateTime
mit einem Kind
von zurückgibt Utc
, was in Ordnung ist, aber das Obige ToUnixTime
ist viel verdächtiger, da es nicht berücksichtigt, welche Art von DateTime
gegeben date
ist. Um zuzulassen date
, Kind
dass entweder Utc
oder ist Local
, verwenden Sie 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
konvertiert ein Local
(oder Unspecified
) DateTime
in Utc
.
Wenn Sie beim Übergang von DateTime in die Epoche keine DateTime-Instanz für die Epoche erstellen möchten, können Sie außerdem Folgendes tun:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTime
funktioniert nur richtig, wenn das Datum in Utc ist. Fügen Sie entweder einen Scheck hinzu oder konvertieren Sie ihn. (Ich persönlich bevorzuge den Scheck)
milliseconds
nicht Sekunden arbeiten !!!
AddMilliseconds
Double NOT Float verwenden und verwenden. Andernfalls haben Sie eine falsche Zeit.
Sie möchten tatsächlich Millisekunden (Millisekunden) hinzufügen, nicht Sekunden. Wenn Sie Sekunden hinzufügen, erhalten Sie eine Ausnahme außerhalb des Bereichs.
AddMillis
und wenn Sie von Sekunden beginnen, wollen Sie offensichtlich AddSeconds
.
Wenn Sie eine bessere Leistung wünschen, können Sie diese Version verwenden.
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);
}
Aus einem schnellen Benchmark (BenchmarkDotNet) unter net471 erhalte ich folgende Nummer:
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 schneller gegen LukeHs Version (wenn die Leistung wichtig ist )
Dies ähnelt der internen Funktionsweise von DateTime.
Verwenden Sie die Methode DateTimeOffset.ToUnixTimeMilliseconds (). Sie gibt die Anzahl der Millisekunden zurück, die seit 1970-01-01T00: 00: 00.000Z vergangen sind.
Dies wird nur mit Framework 4.6 oder höher unterstützt
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
Es ist hier gut dokumentiert DateTimeOffset.ToUnixTimeMilliseconds
Der andere Ausweg besteht darin, Folgendes zu verwenden
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
Um die EPOCH mit nur Sekunden zu erhalten, dürfen Sie verwenden
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
und Konvertieren der Epoch
zu DateTime
dem folgende Verfahren
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
.Ticks
, erhalten Sie eine schöne TimeSpan-Instanz aus der DateTime-Subtraktion zurück.
// 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);
}
Sollte ToUniversalTime () für das DateTime-Objekt verwenden.
Ich verwende die folgenden Erweiterungsmethoden für die Epochenkonvertierung
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);
}
Um sich keine Gedanken über die Verwendung von Millisekunden oder Sekunden zu machen, gehen Sie wie folgt vor:
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);
}
Wenn die Epochenzeit in Sekunden angegeben ist, können Sie das Jahr 1972 nicht mit Millisekunden verlängern.
Wenn Sie 4.6 nicht verwenden, kann dies hilfreich sein. Quelle: 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);
Wenn Sie eine Zeitstruktur (Sekunden, Mikrosekunden) konvertieren müssen, die enthält UNIX time
, DateTime
ohne an Genauigkeit zu verlieren, gehen Sie wie folgt vor:
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);
}
Seit .Net 4.6 und höher verwenden Sie bitte DateTimeOffset.Now.ToUnixTimeSeconds ()
Hier ist meine Lösung:
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);
}