Fungsi yang membuat stempel waktu di c #

101

Saya bertanya-tanya, apakah ada cara untuk membuat stempel waktu di c # dari datetime? Saya membutuhkan nilai presisi milidetik yang juga berfungsi di Compact Framework (mengatakan bahwa sejak DateTime.ToBinary () tidak ada di CF).

Masalah saya adalah saya ingin menyimpan nilai ini dalam basis data agnostik sehingga saya dapat mengurutkannya nanti dan mencari tahu nilai mana yang lebih besar dari yang lain, dll.

Konstantinos
sumber
2
Jawaban yang diterima di sini memberikan solusi yang bagus, tetapi jika Anda menginginkan stempel waktu yang sebenarnya, lihat T / J ini: stackoverflow.com/questions/9814060/…
inanutshellus

Jawaban:

206

Saya selalu menggunakan sesuatu seperti berikut:

public static String GetTimestamp(this DateTime value)
{
    return value.ToString("yyyyMMddHHmmssfff");
}

Ini akan memberi Anda string seperti 200905211035131468, saat string beralih dari bit urutan tertinggi stempel waktu ke urutan terendah, penyortiran string sederhana dalam kueri SQL Anda dapat digunakan untuk mengurutkan berdasarkan tanggal jika Anda menempelkan nilai dalam database

RobV
sumber
5
Kenapa kamu bisa 21 bulan dan hanya 12? :)
PaulB
2
Token untuk tahun harus menggunakan huruf kecil di sini: return value.ToString ("yyyyMMddHHmmssffff");
Don Cote
1
@RobV Pertanyaan menanyakan ketepatan milidetik, jadi Anda membutuhkan 3 'f di akhir. 4 'f's Anda memberikan presisi 100 microsend.
Eugene Beresovsky
2
Sadarilah, bahwa Compact Framework tidak mentransfer milidetik. Mereka akan selalu 0. Anda harus memodifikasi kode dan menambahkan sesuatu seperti ini: int tick = Environment.TickCount% 1000; int ms = (centang> = MOffset)? (centang - MOffset): (1000 - (MOffset - tick)); ms = Math.Min (999, Math.Max ​​(0, ms));
Redwolf
43

Saya yakin Anda dapat membuat stempel tanggal gaya unix yang akurat untuk satu detik menggunakan yang berikut ini

//Find unix timestamp (seconds since 01/01/1970)
long ticks = DateTime.UtcNow.Ticks - DateTime.Parse("01/01/1970 00:00:00").Ticks;
ticks /= 10000000; //Convert windows ticks to seconds
timestamp = ticks.ToString();

Menyesuaikan penyebut memungkinkan Anda memilih tingkat presisi

Voxel
sumber
19

Anda dapat menggunakan properti DateTime.Ticks, yang merupakan penyimpanan yang panjang dan universal, selalu bertambah dan dapat digunakan pada kerangka kerja yang ringkas juga. Pastikan saja kode Anda tidak digunakan setelah 31 Desember 9999;)

Frans Bouma
sumber
Ketika Anda mengatakan "selalu meningkat" - tidak ada jaminan bahwa dua panggilan ke DateTime.UtcNow.Ticks akan memberikan nilai yang berbeda, bukan? Dengan kata lain, Anda masih perlu berhati-hati sebelum menggunakannya sebagai stempel waktu yang unik.
Jon Skeet
9
@Konstantinos: Anda tidak dapat menghindari duplikat jika Anda menggunakan stempel waktu. Stempel waktu tidak digunakan untuk kunci unik, tetapi untuk menandai waktu. Anda bilang Anda membutuhkan presisi milidetik, dan ticks memiliki presisi 100ns. Masalahnya adalah Anda akan memiliki duplikat. Jika Anda tidak ingin, Anda memerlukan urutan unik di DB, yang sayangnya tidak db agnostik.
Frans Bouma
3
"Ini adalah jumlah tick nyata yang meningkat seiring waktu". Tetapi jam sistem bisa mundur - misalnya di penghujung waktu musim panas jika Anda menggunakan waktu lokal, atau karena jam sistem telah disesuaikan.
Joe
1
@Frans: tentu saja. Saya hanya memberikan komentar karena orang harus memikirkan implikasi dari solusi yang mereka pilih. Misalnya saya akan menggunakan UTC daripada waktu lokal untuk setidaknya menghilangkan masalah DST.
Joe
1
@konstantinos: hmm ... dokumen mengatakan presisi 100ns, jadi aneh memang tidak presisi seperti yang didokumentasikan. Mungkin memang frameworknya kompak, bukan framework tanpa bug
Frans Bouma
6

Anda juga bisa menggunakan

Stopwatch.GetTimestamp (). ToString ();

mgokhanbakal
sumber
4

saat Anda membutuhkan stempel waktu dalam hitungan detik, Anda dapat menggunakan yang berikut ini:

var timestamp = (int)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds;
Adi_Pithwa
sumber
2

Jika Anda ingin stempel waktu yang sesuai dengan waktu nyata aktual TETAPI juga ingin mereka unik (untuk contoh aplikasi tertentu), Anda dapat menggunakan kode berikut:

public class HiResDateTime
{
   private static long lastTimeStamp = DateTime.UtcNow.Ticks;
   public static long UtcNowTicks
   {
       get
       {
           long orig, newval;
           do
           {
               orig = lastTimeStamp;
               long now = DateTime.UtcNow.Ticks;
               newval = Math.Max(now, orig + 1);
           } while (Interlocked.CompareExchange
                        (ref lastTimeStamp, newval, orig) != orig);

           return newval;
       }
   }
}
Ian Mercer
sumber