Bagaimana cara mengubah DateTime menjadi jumlah detik sejak 1970?


119

Saya mencoba untuk mengubah variabel C # DateTime ke waktu Unix, yaitu, jumlah detik sejak 1 Jan 1970. Sepertinya DateTime sebenarnya diimplementasikan sebagai jumlah 'ticks' sejak Jan 1st, 0001.

Pemikiran saya saat ini adalah mengurangi 1 Jan 1970 dari DateTime saya seperti ini:

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

Apakah ada cara yang lebih baik?


Jawaban:


195

Itu pada dasarnya. Ini adalah metode yang saya gunakan untuk mengonversi ke dan dari waktu waktu Unix:

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);
}

Pembaruan: Pada .Net Core 2.1 dan .Net Standard 2.1, DateTime yang sama dengan Unix Epoch dapat diperoleh dari statis DateTime.UnixEpoch.


1
Perlu dicatat bahwa jika Anda ingin mengonversi ke millseconds untuk stempel waktu yang lebih akurat atau kompatibilitas objek Javascript Date (), Anda perlu menggunakan long, bukan int untuk jenis stempel waktu.
Soviut

3
Tidak berhasil untuk saya. Jawaban ini berhasil: stackoverflow.com/questions/249760/…
Zeezer

@Jonny - ToUniversalTime () dikonversi ke UTC, jadi ini memperhitungkan UTC.
Dave Swersky

4
Asal DateTime = DateTime baru (1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); Menarik bahwa tidak ada yang menyarankan ini. Sangat sering Anda memiliki milidetik yang mewakili waktu Utc. Dan jika Anda tidak t specify this explicitly and somewhere later in code youmemiliki ToUniversalTime () maka Anda akan mendapatkan waktu Utc yang buruk, karena secara default DateTime BUKAN Utc.
steavy

52

Jika sisa sistem Anda OK dengan DateTimeOffset daripada DateTime, ada fitur yang sangat nyaman:

long unixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();

7
Ini adalah cara yang lebih bersih, tetapi hanya tersedia dalam framework 4.6 msdn.microsoft.com/en-us/library/…
Oscar Fraxedas

1
Bagus. Dan tentu saja untuk beralih dari unix ke DateTimeOffset, Anda dapat menggunakan var time = DateTimeOffset.FromUnixTimeSeconds(5000); MS Doc
Jordan

22

Satu-satunya hal yang saya lihat adalah bahwa ini seharusnya dilakukan sejak Midnight Jan 1, 1970 UTC

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

7
Haruskah itu DateTime.UtcNow?
oferei

14

Anda mungkin ingin menggunakan DateTime.UtcNow untuk menghindari masalah zona waktu

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

Satu-satunya cara untuk menghindari masalah zona waktu adalah 1) tetap tidak peduli, dan hanya mendukung satu zona waktu, atau 2) menangani zona waktu (setidaknya) di mana pun Anda berinteraksi dengan sistem atau pengguna akhir lain. Secara khusus, menggunakan UTC dimanapun secara internal hanyalah sebagian dari pertempuran. Dalam skenario pertama, menambahkan waktu UTC sebenarnya memperburuk masalah, sampai Anda siap melakukan semua (2), karena Anda beralih dari mendukung satu zona waktu menjadi hanya mendukung UTC.
jpaugh

1

Pendekatan tersebut akan baik jika tanggal-waktu yang dipermasalahkan adalah dalam UTC, atau mewakili waktu lokal di area yang tidak pernah menggunakan waktu musim panas. Rutinitas perbedaan DateTime tidak memperhitungkan Daylight Saving Time, dan akibatnya akan menganggap tengah malam 1 Juni sebagai kelipatan dari 24 jam setelah tengah malam 1 Januari. Saya tidak mengetahui apa pun di Windows yang melaporkan aturan penghematan siang hari historis untuk saat ini lokal, jadi menurut saya tidak ada cara yang baik untuk menangani waktu dengan benar sebelum perubahan aturan pergeseran waktu siang hari terbaru.


0

Anda dapat membuat startTime dan endTime dari DateTime, lalu melakukan endTime.Subtract (startTime). Kemudian keluarkan span Anda.

Saya pikir itu seharusnya berhasil.


0

Saya menggunakan tahun 2000 daripada Epoch Time dalam kalkulus saya. Bekerja dengan nomor yang lebih kecil mudah disimpan dan diangkut dan ramah JSON.

Tahun 2000 berada di 946684800 kedua dari waktu epoch.

Tahun 2000 berada di 63082281600 kedua dari tanggal 1 Januari 0001.

DateTime.UtcNow Ticks dimulai dari 1-st Jan 0001

Detik dari tahun 2000 :

DateTime.UtcNow.Ticks/10000000-63082281600

Detik dari Waktu Unix:

DateTime.UtcNow.Ticks/10000000-946684800

Misalnya tahun 2020 adalah:

var year2020 = (new DateTime ()). AddYears (2019) .Ticks; // Karena DateTime sudah dimulai pada tahun ke-1

637134336000000000 Kutu sejak 1-st Jan 0001

63713433600 Detik sejak 1-st Jan 0001

1577836800 Detik sejak Epoch Time

631152000 Detik sejak tahun 2000

Referensi:

Konverter Waktu Epoch: https://www.epochconverter.com

Konverter tahun 1: https://www.epochconverter.com/seconds-days-since-y0

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.