Unix dönemini C # ile gerçek zamana nasıl dönüştürürsünüz ? (Dönem 1/1/1970)
Unix dönemini C # ile gerçek zamana nasıl dönüştürürsünüz ? (Dönem 1/1/1970)
Yanıtlar:
1 Ocak 1970'te gece yarısından bu yana (UTC) geçen saniye sayısı olarak tanımlanan Unix zamanını kastettiğini varsayıyorum .
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
yöntemi kullanın .
Net (v4.6) en son sürümü sadece dahili eklendi Unix zaman dönüşümleri için destek. Bu, saniye veya milisaniye ile gösterilen Unix zamanına ve Unix zamanını içerir.
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(1000);
DateTimeOffset
saniye cinsinden Unix zamanı:long unixTimeStampInSeconds = dateTimeOffset.ToUnixTimeSeconds();
DateTimeOffset
:DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(1000000);
DateTimeOffset
milisaniye cinsinden Unix zamanı:long unixTimeStampInMilliseconds= dateTimeOffset.ToUnixTimeMilliseconds();
Not: Bu yöntemler ve cihazlara dönüştürülür DateTimeOffset
. DateTime
Temsil almak için DateTimeOffset.DateTime
özelliği kullanmanız yeterlidir :
DateTime dateTime = dateTimeOffset.UtcDateTime;
'DateTimeOffset' does not contain a definition for 'FromUnixTimeSeconds'
nasıl çözebilirim?
LukeH'ye verilen tüm krediyle, kolay kullanım için bazı uzantı yöntemlerini bir araya getirdim:
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);
}
Aşağıdaki CodesInChaos yukarıdaki açıklama bir FromUnixTime
döndürür notDateTime
bir ile Kind
ait Utc
iyidir, ama hangi yukarıdaki ToUnixTime
çok daha şüpheli ki dikkate almaz tür ne içindir DateTime
verilen date
olduğunu. İzin vermek için date
bireyin Kind
varlık ya Utc
ya Local
, kullanım 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
bir Local
(veya Unspecified
) dönüştürürDateTime
için Utc
.
DateTime'dan epoch'a geçerken epoch DateTime örneğini oluşturmak istemiyorsanız şunları da yapabilirsiniz:
public static long ToUnixTime(this DateTime date)
{
return (date.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
ToUnixTime
yalnızca tarih Utc'deyse doğru çalışır. Bir çek ekleyin veya dönüştürün. (Şahsen ben çek tercih ederim)
milliseconds
gerekmiyor !!!
AddMilliseconds
ve Double NOT Float kullanmalısınız. Aksi takdirde yanlış bir zamanla karşılaşırsınız.
Aslında saniye değil, Milisaniye (milisaniye) eklemek istiyorsunuz. Saniye eklemek size aralık dışı bir istisna verecektir.
AddMillis
ve saniyeler içinde başlıyorsanız bariz istersiniz AddSeconds
.
Daha iyi performans istiyorsanız bu sürümü kullanabilirsiniz.
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);
}
Net471 altında hızlı bir karşılaştırmadan (BenchmarkDotNet) bu numarayı alıyorum:
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 |
LukeH versiyonuna göre 2 kat daha hızlı (performans mater ise)
Bu, DateTime'ın dahili olarak çalışma şekline benzer.
DateTimeOffset.ToUnixTimeMilliseconds () yöntemini kullanın . 1970-01-01T00: 00: 00.000Z'den bu yana geçen milisaniye sayısını döndürür.
Bu yalnızca Framework 4.6 veya üstü ile desteklenir
var EPOCH = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
Burada iyi belgelenmiştir DateTimeOffset.ToUnixTimeMilliseconds
Diğer çıkış yolu aşağıdakileri kullanmaktır
long EPOCH = DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1,0,0,0,0).Ticks;
EPOCH'u sadece saniyeler içinde almak için
var Epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
ve Epoch
değerini DateTime
aşağıdaki yöntemle dönüştürün
private DateTime Epoch2UTCNow(int epoch)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epoch);
}
.Ticks
atlarsanız, DateTime çıkarma işleminden güzel bir TimeSpan örneği geri alınır.
// 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);
}
DateTime nesnesi için ToUniversalTime () kullanmalıdır.
Dönem dönüşümü için aşağıdaki uzantı yöntemlerini kullanıyorum
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);
}
Milisaniye veya saniye kullanma konusunda endişelenmemek için yapmanız gerekenler:
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);
}
Dönem zamanı saniye cinsindeyse, 1972 yılını milisaniye ekleyerek geçemezsiniz.
4.6 kullanmıyorsanız, bu yardımcı olabilir Kaynak: 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);
Eğer bir dönüştürmek için gereken timeval yapı içeren (saniye, mikrosaniye) UNIX time
için DateTime
kesinlik kaybetmeden bu nasıl:
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);
}
Net 4.6 ve üstü sürümler için DateTimeOffset.Now.ToUnixTimeSeconds () kullanın.
İşte benim çözümüm:
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);
}