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);
AddXYZyö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. DateTimeTemsil 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 FromUnixTimedöndürür notDateTime bir ile Kindait Utciyidir, ama hangi yukarıdaki ToUnixTimeçok daha şüpheli ki dikkate almaz tür ne içindir DateTimeverilen dateolduğunu. İzin vermek için datebireyin Kindvarlık ya Utcya 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);
}
ToUniversalTimebir 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;
}
ToUnixTimeyalnızca tarih Utc'deyse doğru çalışır. Bir çek ekleyin veya dönüştürün. (Şahsen ben çek tercih ederim)
milliseconds gerekmiyor !!!
AddMillisecondsve 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.
AddMillisve 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 Epochdeğerini DateTimeaş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);
}
.Ticksatlarsanı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 timeiçin DateTimekesinlik 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);
}