Come si converte il tempo di Unix in tempo reale in C #? (Epoca inizio 1/1/1970)
Come si converte il tempo di Unix in tempo reale in C #? (Epoca inizio 1/1/1970)
Risposte:
Presumo che intendi l' ora di Unix , che è definita come il numero di secondi dalla mezzanotte (UTC) del 1 ° gennaio 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);
AddXYZmetodo giusto .
L' ultima versione di .Net (v4.6) ha appena aggiunto il supporto integrato per le conversioni temporali Unix. Ciò include sia il tempo di andata e ritorno di Unix rappresentato da secondi o millisecondi.
DateTimeOffset:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset tempo Unix in secondi:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset al tempo Unix in millisecondi:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
Nota: questi metodi vengono convertiti da e verso DateTimeOffset. Per ottenere una DateTimerappresentazione è sufficiente utilizzare la DateTimeOffset.DateTimeproprietà:
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'Come potrei fare per risolvere questo?
Con tutto il merito di LukeH, ho messo insieme alcuni metodi di estensione per un facile utilizzo:
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);
}
Nota il commento qui sotto di CodesInChaos che quanto sopra FromUnixTimerestituisce a DateTimecon a Kinddi Utc, il che va bene, ma quanto sopra ToUnixTimeè molto più sospetto in quanto non tiene conto del tipo di DateTimedato date. Per consentire date's Kindessere uno Utco Local, uso 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);
}
ToUniversalTimeconvertirà un Local(o Unspecified) DateTimein Utc.
se non si desidera creare l'istanza DateTime di epoca quando ci si sposta da DateTime a epoca è possibile anche:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTimefunziona correttamente solo se la data è in Utc. Aggiungi un segno di spunta o convertilo. (Personalmente preferisco il controllo)
milliseconds non secondi !!!
AddMillisecondse dovresti usare Double NOT Float. Altrimenti finirai con un momento sbagliato.
In realtà si desidera aggiungere Millisecondi (millisecondi), non secondi. L'aggiunta di secondi ti darà un'eccezione fuori portata.
AddMillise se stai partendo da pochi secondi, ovviamente, vuoi AddSeconds.
Se vuoi prestazioni migliori puoi usare questa versione.
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);
}
Da un rapido benchmark (BenchmarkDotNet) sotto net471 ottengo questo numero:
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 più veloce rispetto alla versione di LukeH (se la performance mater)
Questo è simile al funzionamento interno di DateTime.
Usa il metodo DateTimeOffset.ToUnixTimeMilliseconds () Restituisce il numero di millisecondi trascorsi dal 1970-01-01T00: 00: 00.000Z.
Questo è supportato solo con Framework 4.6 o versioni successive
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
È ben documentato qui DateTimeOffset.ToUnixTimeMilliseconds
L'altra via d'uscita è usare quanto segue
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
Per ottenere l'EPOCH in pochi secondi puoi usare
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
e converti Epochin DateTimecon il seguente metodo
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
.Ticks, si otterrebbe una bella istanza TimeSpan dalla sottostrazione 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);
}
Dovrebbe usare ToUniversalTime () per l'oggetto DateTime.
Uso i seguenti metodi di estensione per la conversione di epoca
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);
}
Per non preoccuparti di usare millisecondi o secondi, fai semplicemente:
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);
}
Se il tempo è in secondi, non è possibile passare l'anno 1972 aggiungendo millisecondi.
Se non si utilizza 4.6, questo può aiutare 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);
In caso di necessità di convertire una struct timeval (secondi, microsecondi) contenente UNIX timea DateTime, senza perdere in precisione, questo è il modo:
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);
}
Da .Net 4.6 e versioni successive, utilizzare DateTimeOffset.Now.ToUnixTimeSeconds ()
Ecco la mia soluzione:
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);
}