Bir DateTime'ı 1970'ten sonraki saniye sayısına nasıl dönüştürebilirim?


120

Bir C # DateTime değişkenini Unix zamanına dönüştürmeye çalışıyorum, yani 1 Ocak 1970'den beri geçen saniye sayısı. Görünüşe göre 1 Ocak 0001'den bu yana bir DateTime 'tik' sayısı olarak uygulanıyor.

Şu anki düşüncem DateTime'ımdan 1 Ocak 1970'i şu şekilde çıkarmak:

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0));
return span.TotalSeconds;

Daha iyi bir yol var mı?


Yanıtlar:


196

Bu temelde bu. Unix çağ zamanına dönüştürmek için kullandığım yöntemler şunlardır:

public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    return origin.AddSeconds(timestamp);
}

public static double ConvertToUnixTimestamp(DateTime date)
{
    DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
    TimeSpan diff = date.ToUniversalTime() - origin;
    return Math.Floor(diff.TotalSeconds);
}

Güncelleme: .Net Core 2.1 ve .Net Standard 2.1'den itibaren statikten Unix Epoch'a eşit bir DateTime elde edilebilir DateTime.UnixEpoch.


1
Daha doğru zaman damgaları veya Javascript Date () nesne uyumluluğu için mil saniyeye dönüştürmek istiyorsanız, zaman damgası türü için int yerine long kullanmanız gerektiğini belirtmek gerekir.
Soviut

3
Benim için çalışmadı. Bu cevap hile yaptı: stackoverflow.com/questions/249760/…
Zeezer

@Jonny - ToUniversalTime () UTC'ye dönüştürür, bu nedenle UTC'yi hesaba katar.
Dave Swersky

4
DateTime kaynağı = yeni DateTime (1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); Kimsenin bunu önermemesi ilginç. Çoğu zaman, Utc zamanını temsil eden milisaniyeleriniz olacaktır. Ve eğer t specify this explicitly and somewhere later in code youToUniversalTime () 'a sahip değilseniz, kötü Utc zamanıyla sonuçlanır, çünkü varsayılan olarak DateTime Utc DEĞİLDİR.
steavy

52

Sisteminizin geri kalanı DateTime yerine DateTimeOffset ile uygunsa, gerçekten kullanışlı bir özellik vardır:

long unixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();

7
Bu daha temiz bir yoldur, ancak yalnızca 4.6 msdn.microsoft.com/en-us/library/…
Oscar Fraxedas

1
Güzel. Ve tabii ki unix'ten DateTimeOffset'e geçmek için var time = DateTimeOffset.FromUnixTimeSeconds(5000); MS Doc
Jordan'ı

22

Gördüğüm tek şey, 1 Ocak 1970 UTC'den beri gece yarısı olması gerekiyordu.

TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;

7
DateTime.UtcNow olmalı mı?
oferei

14

Saat dilimi sorununu önlemek için muhtemelen DateTime.UtcNow kullanmak istiyorsunuz

TimeSpan span= DateTime.UtcNow.Subtract(new DateTime(1970,1,1,0,0,0)); 

Saat dilimi sorunlarını önlemenin tek yolu 1) cahilce bilgisiz kalmak ve yalnızca bir saat dilimini desteklemektir veya 2) saat dilimlerini (en azından) başka bir sistemle veya son kullanıcıyla arayüz oluşturduğunuz her yerde ele almaktır. Özellikle, her yerde dahili olarak UTC kullanmak savaşın yalnızca bir parçasıdır. İlk senaryoda, UTC tarih zamanlarının eklenmesi, siz (2) 'nin tümünü yapmaya hazır olana kadar sorunu daha da kötüleştirir, çünkü herhangi bir saat dilimini desteklemekten yalnızca UTC'yi desteklemeye geçersiniz.
jpaugh

1

Söz konusu tarih-saat UTC ise veya gün ışığından yararlanma saatini hiç gözlemlemeyen bir bölgedeki yerel saati temsil ediyorsa, bu yaklaşım iyi olacaktır. Tarih Saat farkı rutinleri, Yaz Saati Uygulamasını hesaba katmaz ve sonuç olarak 1 Haziran gece yarısını, 1 Ocak gece yarısından sonraki 24 saatin katı olarak kabul eder. Windows'ta, güncel gün ışığından yararlanma kurallarını bildiren herhangi bir şeyin farkında değilim. locale, bu nedenle en son gün ışığından yararlanma kuralı değişikliğinden önce herhangi bir zamanı doğru şekilde işlemenin iyi bir yolu olduğunu düşünmüyorum.


0

DateTime için bir startTime ve endTime oluşturabilir, ardından endTime.Subtract (startTime) yapabilirsiniz. Ardından yayılma sürenizin çıktısını alın.Saniye.

Bunun işe yarayacağını düşünüyorum.


0

Analizimde Epoch Time yerine 2000 yılını kullanıyorum. Daha küçük sayılarla çalışmanın saklanması ve taşınması kolaydır ve JSON dostudur.

2000 yılı, çağın ikinci 946684800'üydü.

2000 yılı, 1 Ocak 0001'den itibaren 63082281600 ikinci oldu.

DateTime.UtcNow Ticks, 1 Ocak 0001'den başlıyor

2000 yılından itibaren saniye :

DateTime.UtcNow.Ticks/10000000-63082281600

Unix Zamanından Saniyeler:

DateTime.UtcNow.Ticks/10000000-946684800

Örneğin 2020 yılı:

var year2020 = (yeni DateTime ()). AddYears (2019) .Ticks; // DateTime 1. yılda başladığı için

637134336000000000 1 Ocak 0001'den beri işaretler

63713433600 1 Ocak 0001'den beri geçen saniye

1577836800 Epoch Time'dan beri geçen saniye

631152000 saniye 2000 yılından beri

Referanslar:

Epoch Time dönüştürücü: https://www.epochconverter.com

Yıl 1 dönüştürücü: https://www.epochconverter.com/seconds-days-since-y0

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.