Milisaniye hassasiyetiyle DateTime alın.


231

Gerçek zamanlı zaman damgasını milisaniye hassasiyetle tam olarak nasıl oluşturabilirim?

16.4.2013 9: 48: 00: 123 gibi bir şeye ihtiyacım var. Mümkün mü? Saniyede 10 kez değerleri örneklediğim bir uygulama var ve bunları bir grafikte göstermem gerekiyor.



Bazı cevapların hhsaatlerce kullanıldığını unutmayın (standart süre). Bir zaman damgası (ve diğer birçok durumda), bu muhtemelen tt(am / pm) ile eşleştirilmeli veya HH(askeri zaman) ile değiştirilmelidir.
wentz

Yanıtlar:


304

Gerçek zamanlı zaman damgasını milisaniye hassasiyetle tam olarak nasıl oluşturabilirim?

Milisaniye doğruluk demek istediğinizden şüpheleniyorum . DateTimeçok hassastır, ancak doğruluk açısından oldukça kabadır. Genel olarak konuşamazsınız. Genellikle sistem saatinin ( DateTime.Nowverilerini aldığı yer) yaklaşık 10-15 ms'lik bir çözünürlüğe sahiptir. Daha fazla ayrıntı için hassasiyet ve doğruluk hakkında Eric Lippert'in blog gönderisine bakın.

Bundan daha doğru bir zamanlamaya ihtiyacınız varsa, bir NTP istemcisi kullanmaya bakmak isteyebilirsiniz.

Bununla birlikte, burada gerçekten milisaniye hassasiyete ihtiyacınız olduğu açık değildir. Kesin zamanlamayı umursamıyorsanız - sadece örnekleri "oldukça iyi" doğrulukta doğru sırada göstermek istiyorsanız, sistem saati iyi olmalıdır. Kullandığım öneriyorum DateTime.UtcNowziyade DateTime.Nowyaz saati geçişleri vb etrafında saat dilimi sorunları önlemek için, gerçi

Sorunuz aslındaDateTime bir milisaniye hassasiyetle bir dizeye dönüştürmek etrafında ise , ben kullanmanızı öneririz:

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

(Örneğinizin aksine, bunun sıralanabilir olduğunu ve "ay / gün / yıl" veya "gün / ay / yıl" olması gerektiği konusunda karışıklığa neden olma olasılığının düşük olduğunu unutmayın.)


5
@antonio: "Çalışmıyor" dan başka bilgi olmadan daha fazla yardım sağlayamam.
Jon Skeet

Evet, daha fazla bilgi sağlayabilirim: "{0: yyyyMMdd SS: dd: ss.fff}", DateTime.UtcNow -> 20180502 11: 07: 20.000 Win32.GetSystemTime (ref stime) -> 2018,2,5,11 , 7,20,0 (ymdh mm ss ms) Milisaniye ile tarih saatinin bir örneğini oluşturabilirim: var dt = new DateTime (2018, 5, 2, 19, 34, 55, 200); "{0: yyyyMMdd SS: dd: ss.fff}", dt -> 20180502 19: 34: 55.200. Net kompakt çerçeve, Windows Embedded Compact 7, ARM Cortex-A8 üzerinde
antonio

@antonio: Kullandığınız donanımda kullandığınız .NET sürümü gibi görünüyorsa ikinci derecede doğruluk sağlamıyor - ya da ikinci bir sınırda çağırdınız. (Tekrar DateTime.UtcNowtekrar vurmaya devam ederseniz , saniyede yalnızca bir kez artar mı? Bunu göstermediniz.)
Jon Skeet

Keneleri DateTime'dan aldığımda.Şimdi, değer kesildi: Keneler 636534596580000000 Keneler 20180205 20: 34: 18.000. sınırlama zor / yazılım, bence. Bunun yerine Kronometre sınıfını kullanıyorum, Teşekkürler Jon
antonio

@antonio: Muhtemelen bu noktada yer alan cihazın tüm detaylarıyla yeni bir soru yaratmaya değer.
Jon Skeet

117

Bu çalışmalı:

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

Görüntülenmesi gerekmiyorsa ve sadece zaman farkını bilmeniz gerekiyorsa, onu bir String'e dönüştürmeyin. Sadece şu şekilde bırakın,DateTime.Now();

Ve TimeSpanzaman aralıkları arasındaki farkı bilmek için kullanın :

Misal

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

Onunla hesaplamak gerekir, bu yüzden dizeye dönüştürmek olamaz.
LuckyHK

25

Ben benzer bir çözüm arıyordum, bu konu ne önerildi baz, ben aşağıdakini kullanın DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff") ve çekicilik gibi çalışır. Not: .fffyakalamak istediğiniz hassas sayılardır.


1
Tarih öğleden sonra ise (4:00) sabah olduğu gibi gösterecektir. Düzeltme: kullanın HH(askeri zaman) veya ekleyin tt(pm veya am). Bu örnekte gösterildiği gibi: repl.it/KGr3/1
Jaider

22

DateTime Yapısını milisaniye ve formatla şu şekilde kullanın:

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

16

Pyromancer'ın cevabı benim için oldukça iyi görünüyor, ama belki istedin:

DateTime.Now.Millisecond

Ancak tarihleri ​​karşılaştırıyorsanız, TimeSpan gidilecek yoldur.


15
Not: İki DateTimes arasındaki farkı TimeSpan olarak karşılaştırıyorsanız, ihtiyacınız vardır TotalMilliseconds. Milisaniye, geçerli 1000 Milisaniye sayacını tutar ve asla 1000'den büyük değildir, TotalMilliseconds ise çağdan bu yana geçen toplam milisaniye tutar.
Contango

4

Diğer yanıtlar gibi bir dize yerine hala bir tarih istiyorsanız, bu uzantı yöntemini eklemeniz yeterlidir.

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

3

Soruyu anladığım kadarıyla şunları yapabilirsiniz:

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

Bu 1 milisaniyeden küçük keneleri kesecektir.


Evet, ancak DateTime'ın gerçek çözünürlüğü.Şimdi yaklaşık 16 ms'den fazla olamaz.
Peter Mortensen

2

Sorun DateTime.UtcNowve DateTime.Nowbilgisayara ve işletim sistemine bağlı olarak, sadece 10 ila 15 milisaniye arasında doğru olabilir. Ancak, Windows bilgisayarlarda mikrosaniye doğruluğu elde etmek için düşük seviye GetSystemTimePreciseAsFileTime işlevini kullanarak kullanabilirsiniz , GetTimeStamp()aşağıdaki işleve bakın.

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

Çok teşekkür ederim. Bunu çok uzun zamandır araştırıyorum. Performans sorunlarına neden oluyor mu ve üretim kodunu kullanmak güvenli mi?
Muhammet Göktürk Ayan


-2
public long millis() {
  return (long.MaxValue + DateTime.Now.ToBinary()) / 10000;
}

Eğer mikrosaniye istiyorsanız, sadece değiştirmek 10000için 10ve mikro 10. istiyorsanız, silmek / 10000.


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.