Dapatkan DateTime. Sekarang dengan presisi milidetik

231

Bagaimana saya bisa membuat cap waktu yang sebenarnya dengan ketepatan milidetik?

Saya butuh sesuatu seperti 16.4.2013 9: 48: 00: 123. Apakah ini mungkin? Saya memiliki aplikasi, di mana saya sampel nilai 10 kali per detik, dan saya perlu menunjukkannya dalam grafik.

LuckyHK
sumber
Ketahuilah bahwa sejumlah jawaban digunakan hhselama berjam-jam (waktu standar). Dalam hal cap waktu (dan dalam banyak kasus lainnya) ini mungkin harus dipasangkan dengan tt(am / pm) atau diganti dengan HH(waktu militer).
goz

Jawaban:

304

Bagaimana saya bisa membuat cap waktu yang sebenarnya dengan ketepatan milidetik?

Saya menduga maksud Anda akurasi milidetik . DateTimememiliki banyak presisi, tetapi cukup kasar dalam hal akurasi. Secara umum, Anda tidak bisa. Biasanya jam sistem (yang merupakan tempat pengambilan DateTime.Nowdatanya) memiliki resolusi sekitar 10-15 ms. Lihat posting blog Eric Lippert tentang presisi dan akurasi untuk detail lebih lanjut.

Jika Anda membutuhkan pengaturan waktu yang lebih akurat dari ini, Anda mungkin ingin melihat ke dalam menggunakan klien NTP.

Namun, tidak jelas bahwa Anda benar-benar membutuhkan akurasi milidetik di sini. Jika Anda tidak peduli dengan waktu yang tepat - Anda hanya ingin menunjukkan sampel dalam urutan yang benar, dengan akurasi "cukup bagus", maka jam sistem harus baik-baik saja. Saya menyarankan Anda untuk menggunakan DateTime.UtcNowdaripada DateTime.Nowuntuk menghindari masalah zona waktu di sekitar transisi musim panas, dll.

Jika pertanyaan Anda sebenarnya hanya sekitar mengkonversi DateTimeke string dengan presisi milidetik, saya sarankan menggunakan:

string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                            CultureInfo.InvariantCulture);

(Perhatikan bahwa tidak seperti sampel Anda, ini mudah disortir dan cenderung menyebabkan kebingungan apakah itu dimaksudkan sebagai "bulan / hari / tahun" atau "hari / bulan / tahun".)

Jon Skeet
sumber
5
@antonio: Dengan tidak ada informasi lebih dari "tidak berfungsi" saya tidak bisa memberikan bantuan lagi.
Jon Skeet
Ya, saya dapat memberikan info lebih lanjut: "{0: yyyyMMdd HH: mm: ss.fff}", DateTime.UtcNow -> 20180502 11: 07: 20.000 Win32.GetSystemTime (ref stime) -> 2018,2,5,11 , 7,20,0 (ymdh mm ss ms) Saya dapat membuat instance dari waktu tanggal dengan milidetik: var dt = DateTime baru (2018, 5, 2, 19, 34, 55, 200); "{0: yyyyMMdd HH: mm: ss.fff}", dt -> 20180502 19: 34: 55.200. Kerangka kerja ringkas Net, Windows Embedded ringkas 7, pada ARM Cortex-A8
antonio
@antonio: Jadi sepertinya versi .NET yang Anda gunakan pada perangkat keras yang Anda gunakan tidak memberikan akurasi subsecond - atau Anda menyebutnya dengan batas kedua. (Jika Anda terus memukul DateTime.UtcNowberulang kali, apakah hanya akan bertambah satu kali per detik? Anda belum menunjukkannya.)
Jon Skeet
Ketika saya mengambil Ticks dari DateTime. Sekarang, nilainya terpotong: Ticks 636534596580000000 DateTime dari Ticks 20180205 20: 34: 18.000. keterbatasannya ada pada hard / software, saya rasa. Saya telah menggunakan kelas Stopwatch, sebagai gantinya Terima kasih Jon
antonio
@antonio: Mungkin perlu membuat pertanyaan baru dengan perincian lengkap perangkat yang terlibat saat ini.
Jon Skeet
117

Ini seharusnya bekerja:

DateTime.Now.ToString("hh.mm.ss.ffffff");

Jika Anda tidak membutuhkannya untuk ditampilkan dan hanya perlu mengetahui perbedaan waktu, jangan mengubahnya menjadi String. Biarkan saja sebagai,DateTime.Now();

Dan gunakan TimeSpanuntuk mengetahui perbedaan antara interval waktu:

Contoh

DateTime start;
TimeSpan time;

start = DateTime.Now;

//Do something here

time = DateTime.Now - start;
label1.Text = String.Format("{0}.{1}", time.Seconds, time.Milliseconds.ToString().PadLeft(3, '0'));
Pyromancer
sumber
Saya perlu menghitung dengan itu, jadi saya tidak bisa mengubahnya menjadi string.
LuckyHK
25

Saya sedang mencari solusi yang sama, berdasarkan apa yang disarankan di utas ini, saya menggunakan yang berikut DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff") , dan itu bekerja seperti pesona. Catatan: itu .fffadalah angka presisi yang ingin Anda tangkap.

Jozcar
sumber
1
Jika tanggal di sore hari (4PM) akan menunjukkan seperti di pagi hari. FIX: Gunakan HH(waktu militer) atau tambahkan tt(PM atau AM). Seperti ditunjukkan dalam contoh ini: repl.it/KGr3/1
Jaider
22

Gunakan Struktur DateTime dengan milidetik dan format seperti ini:

string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", 
CultureInfo.InvariantCulture);
timestamp = timestamp.Replace("-", ".");
Jacman
sumber
16

Jawaban Pyromancer tampaknya cukup baik bagi saya, tetapi mungkin Anda ingin:

DateTime.Now.Millisecond

Tetapi jika Anda membandingkan tanggal, TimeSpan adalah cara untuk pergi.

Renae
sumber
15
Catatan: Jika Anda membandingkan perbedaan antara dua DateTimes sebagai TimeSpan, Anda perlu TotalMilliseconds. Milidetik memegang penghitung milidetik saat ini, yang tidak pernah lebih besar dari 1000, sedangkan TotalMillisecond memegang total milidetik yang berlalu sejak zaman.
Contango
4

Jika Anda masih menginginkan kencan alih-alih string seperti jawaban lainnya, cukup tambahkan metode ekstensi ini.

public static DateTime ToMillisecondPrecision(this DateTime d) {
    return new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute,
                        d.Second, d.Millisecond, d.Kind);
}
Birch
sumber
3

Sejauh yang saya mengerti pertanyaannya, Anda bisa mencari:

DateTime dateTime = DateTime.Now;
DateTime dateTimeInMilliseconds = dateTime.AddTicks(-1 * dateTime.Ticks % 10000); 

Ini akan memotong kutu yang lebih kecil dari 1 milidetik.

Roland Dietz
sumber
Ya, tetapi resolusi aktual DateTime. Sekarang mungkin tidak lebih dari sekitar 16 ms.
Peter Mortensen
2

Masalahnya dengan DateTime.UtcNowdan DateTime.Nowapakah itu, tergantung pada komputer dan sistem operasi, itu mungkin hanya akurat antara 10 dan 15 milidetik. Namun, pada komputer windows seseorang dapat menggunakan dengan menggunakan fungsi tingkat rendah GetSystemTimePreciseAsFileTime untuk mendapatkan akurasi mikrodetik, lihat fungsi di GetTimeStamp()bawah ini.

    [System.Security.SuppressUnmanagedCodeSecurity, System.Runtime.InteropServices.DllImport("kernel32.dll")]
    static extern void GetSystemTimePreciseAsFileTime(out FileTime pFileTime);

    [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
    public struct FileTime  {
        public const long FILETIME_TO_DATETIMETICKS = 504911232000000000;   // 146097 = days in 400 year Gregorian calendar cycle. 504911232000000000 = 4 * 146097 * 86400 * 1E7
        public uint TimeLow;    // least significant digits
        public uint TimeHigh;   // most sifnificant digits
        public long TimeStamp_FileTimeTicks { get { return TimeHigh * 4294967296 + TimeLow; } }     // ticks since 1-Jan-1601 (1 tick = 100 nanosecs). 4294967296 = 2^32
        public DateTime dateTime { get { return new DateTime(TimeStamp_FileTimeTicks + FILETIME_TO_DATETIMETICKS); } }
    }

    public static DateTime GetTimeStamp() { 
        FileTime ft; GetSystemTimePreciseAsFileTime(out ft);
        return ft.dateTime;
    }
Secara stokastik
sumber
Terima kasih banyak. Saya sudah mencari ini begitu lama. Apakah ini menyebabkan masalah kinerja dan apakah aman untuk menggunakan kode produksi?
Muhammet Göktürk Ayan
-2
public long millis() {
  return (long.MaxValue + DateTime.Now.ToBinary()) / 10000;
}

Jika Anda ingin mikrodetik, ubah saja 10000ke 10, dan jika Anda ingin mikro ke-10, hapus / 10000.

mencolok
sumber
-3

DateTime.Now.ToString ("ddMMyyyyhhmmssffff")

amol jadhao
sumber