C # kullanarak mili saniye cinsinden zamanı öğrenin


133

Zamanı milisaniye cinsinden almam gereken bir program yapıyorum. Zamanla, asla kendisine eşit olmayan ve her zaman bir saniye öncesine göre 1000 sayı daha büyük olan bir sayıyı kastediyorum. A'ya dönüştürmeyi ve DateTime.Nowondan TimeSpanalmayı denedim TotalMilliseconds... ama bunun tam olarak doğru olmadığını duydum.

Bunu yapmanın daha kolay bir yolu var mı?


Her zaman artan değerlere yol açacak iki çağrının olmasını mı bekliyorsunuz? Genel olarak, zamanlayıcı çözünürlüğünün izin verdiği minimum aralıktan daha yakın aramalar aynı değeri verecektir. Sahte hassas serileştirici biçiminde kendi eşitlik bozucunuzu eklemeniz gerekir.
Steven Sudit

16
"Asla kendisine eşit olmayan bir sayı". Kulağa karmaşık geliyor. ;)
Mizipzor

1
NaN aslında bu gereksinimi karşılayacaktır. "Sayı olmamasına" rağmen bir sayı türüdür ve kendisine eşit değildir.
Yay295

Yanıtlar:


78

StopwatchSınıfı kullanın .

Geçen zamanı doğru bir şekilde ölçmek için kullanabileceğiniz bir dizi yöntem ve özellik sağlar.

Burada uygulamakla ilgili bazı iyi bilgiler var:

Performans Testleri: System.Diagnostics.Stopwatch ile Hassas Çalışma Süresi Ölçümleri


8
kronometre Tanılama uygulamasının bir parçasıdır. Gerçek kodda kullanılmalı mı?
Andrey


Bu normalde yalnızca en yakın 15 ms'ye kadar doğrudur.
Steven Sudit

11
ne kadar pahalı olsa da? belki bir kronometreyi kronometre etmeliyiz :)
jb.

3
@Steven, bu işletim sistemine ve temel donanıma bağlıdır. Mümkünse yüksek çözünürlüklü bir zamanlayıcı kullanılıyorsa, bu durum bildiğim tüm mevcut masaüstü ve sunucu tabanlı x86 Windows sürümleri için geçerlidir. Daha fazla ayrıntı için Frequency ve IsHighResolution özelliklerini kontrol edin. İşletim sistemi düzeyinde, QueryPerformanceCounter ve QueryPerformanceFrequency, bu işlevselliği destekleyen düşük düzeyli API'lerdir.
Chris Taylor

322
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;

Bu aslında DateTimeOffsetsınıfta çeşitli Unix dönüştürme yöntemlerinin uygulanma şeklidir (.NET Framework 4.6+, .NET Standard 1.3+):

long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();

65
Başlık "milisaniye cinsinden zamanı al" şeklindedir. Bu cevap faydalıdır.
Havacılık

33
Evet, sorulan sorunun cevabını arayanlar için bu çok yardımcı oldu, teşekkür ederim.
user430788

1
Ondalık sayılar istiyorsanız ( DateTime.Nowçok sık "güncellenmemiş" olsa bile ), tabii ki decimal milliseconds = DateTime.Now.Ticks / (decimal)TimeSpan.TicksPerMillisecond;yerine kullanın.
Jeppe Stig Nielsen

1
Bu, arama sonuçları için seçilen cevaptan ve hatta orijinal sorudan topladıklarım için çok daha kullanışlıdır.
bwoogie

1
Bu cevap hayatımı kurtardı. Benzer kod var ama çalışmıyor. Nedenini çözemedim. Daha sonra longveri türünü milisaniyelerin önünde gördüm . Kullanmak intkesinlikle taşacak.
FisNaN

13

DateTime.TicksMülkiyet tarih ve saatini temsil kene sayısını alır.

10.000 Tik, bir milisaniyedir (saniyede 10.000.000 tik).


4
Ancak Kenelerin çözünürlüğü 1 /
10000sn'den

2
@codymanix - MSDN'den:A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.
Itay Karo

5
Elbette, ancak işletim sistemi bu kadar kesin bir çözünürlüğe sahip değil.
codymanix

6
@codymanix doğru. Benzetme yapmak gerekirse, Angstrom bir uzunluk birimidir; on milyar Angstrom bir metre yapar. Boyunuzu Angstroms cinsinden 64 bitlik bir tamsayı olarak bildiren bir işlev yazabilirsiniz, ancak sahip olduğunuz tek şey santimetreye göre doğru bir ölçüm çubuğuysa, işlevin nanometre altı hassasiyeti temsil ettiği gerçeği tamamen alakasızdır. Daha az önemli basamaklar çöp olacak.
Eric Lippert

4
@RedFilter: Yaşınızı en yakın milisaniye kadar biliyor olsaydınız, "Tekrar göz kırptığımda yaşım x milisaniye olacak" gibi bir şey söyleyebilirsiniz. Daha derin sorun iletişim değil ölçümdür: doğumunuzun en yakın saniye bile bilinmesi pek olası değildir.
Steven Sudit

11

Aşağıdaki sınıfı kullanıyorum. ŞİMDİ () en iyisi olduğu kabul edilen bir kez internette buldum .

/// <summary>Class to get current timestamp with enough precision</summary>
static class CurrentMillis
{
    private static readonly DateTime Jan1St1970 = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    /// <summary>Get extra long current timestamp</summary>
    public static long Millis { get { return (long)((DateTime.UtcNow - Jan1St1970).TotalMilliseconds); } }
}

Kaynak bilinmiyor.


5
FWIW, bu yaygın olarak kullanılan parçacığın tüm amacı, Unix zaman damgası standardı ile uyumlu bir zaman damgası oluşturmaktır. Bunun için hayati önem taşıyor. Kişi sadece zamanlama yapmak isterse, gereksiz yere pahalıdır.
ToolmakerSteve

8

QueryPerformanceCounterYerel yöntemi deneyebilirsiniz . Daha fazla bilgi için http://www.pinvoke.net/default.aspx/kernel32/QueryPerformanceCounter.html bakın . Bu nedir Stopwatchsınıf kullanır.

Bkz . .NET / C # 'da işaretleme duyarlığının zaman damgası nasıl alınır? daha fazla bilgi için.

Stopwatch.GetTimestamp() bu yönteme erişim sağlar:

public static long GetTimestamp() {
     if(IsHighResolution) {
         long timestamp = 0;
         SafeNativeMethods.QueryPerformanceCounter(out timestamp);
         return timestamp;
     }
     else {
         return DateTime.UtcNow.Ticks;
     }
 }

1
AFAIK StopWatch, mevcutsa dahili olarak QueryPerformanceCounter kullanır
codymanix

Evet, dahili uygulaması Stopwatch.GetTimestamp()aslında bu yönteme erişim sağlar.
Pieter van Ginkel

5

DateTime.Now.TimeOfDay.TotalMilliseconds (mevcut gün için) kullandım, umarım size de yardımcı olur.


1
Bu, her gün gece yarısı sıfıra sıfırlandığı için (orijinal poster gerekli olduğu gibi) artan değerler döndürmez. Artı, posterin sadece DateTime kullanırken bahsettiği aynı potansiyel sorunlara sahip olacaktı. Şimdi bundan toplam milisaniye elde ediliyor.
Jim O'Neil

3
Jim O'Neil Size katılıyorum, bu yüzden yazımda "(şimdiki gün için)" den bahsetmiştim ... Btw, benim çözümüm sorunum için çalıştı, sorunum tarihe özgü olmadığından Milisaniye bölümü sayaç olarak kullanılacak, bu yüzden buraya gönderdim. Burada yeniyim, bu yüzden yanlış bir yere gönderdiysem özür dilerim :)
Sarvan

2

Kullanın System.DateTime.Now.ToUniversalTime(). Bu, okumanızı, gün değişimini vb. Tamamen ortadan kaldıran bilinen bir referans tabanlı milisaniye formatına yerleştirir.


Bilmekte fayda var, ancak sorulan soruyla alakalı değil, bu zamanlama (zaman geçişinin ölçümü) ile ilgili, zamanı doğru bir şekilde iletmekle ilgili değil.
ToolmakerSteve
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.