2010-10-25 19 views
89

Tworzę program, w którym potrzebuję uzyskać czas w milisekundach. Przez czas mam na myśli liczbę, która nigdy nie jest równa sobie i zawsze jest o 1000 liczb większa niż przed sekundą. Próbowałem przekonwertować DateTime.Now na TimeSpan i uzyskać TotalMilliseconds z tego ... ale słyszałem, że nie jest idealnie dokładne.Uzyskaj czas w milisekundach, używając C#

Czy jest to łatwiejszy sposób?

+0

Czy spodziewasz się, że dwa połączenia będą zawsze prowadzić do wzrostu wartości? Ogólnie rzecz biorąc, wywołania bliższe niż minimalny przedział czasu, na jaki pozwala rozdzielczość czasomierza, przyniosą tę samą wartość. Będziesz musiał dodać własne rozstrzygnięcie w postaci serializatora z fałszywą precyzją. –

+14

"Liczba, która nigdy nie jest równa sobie". To brzmi ... skomplikowanie. ;) – Mizipzor

+0

NaN spełniłoby to wymaganie. Pomimo że nie jest liczbą, jest to typ liczbowy i nie jest równy samemu sobie. – Yay295

Odpowiedz

66

Użyj klasy Stopwatch.

zapewnia zestaw metod i właściwości, które można użyć do dokładnie zmierzyć czas, który upłynął.

Jest kilka dobrych informacji na wdrożenie go tutaj:

Performance Tests: Precise Run Time Measurements with System.Diagnostics.Stopwatch

+6

stoper jest częścią Diagnostyki. Czy powinien być używany w prawdziwym kodzie? – Andrey

+4

@Andrey - http://stackoverflow.com/questions/2805362/can-stopwatch-be-used-in-production-code/2805409#2805409 –

+0

Zwykle jest to dokładne tylko z dokładnością do około 15 ms. –

11

Właściwość DateTime.Ticks otrzymuje liczbę znaczników, które reprezentują datę i godzinę.

10 000 kleszczy to milisekunda (10 000 000 kleszczy na sekundę).

+4

Ale rozdzielczość kleszczy jest bardzo mniejsza niż 1/10000s, może 1/62s – codymanix

+2

@codymanix - z MSDN: 'Pojedynczy tyknięcie reprezentuje sto nanosekund lub jedną dziesiątą milionową sekundy. Jest 10 000 tyknięć w milisekundach.' –

+5

Oczywiście, ale system operacyjny nie ma takiej dokładności. – codymanix

6

Można spróbować QueryPerformanceCounter natywne metody. Aby uzyskać więcej informacji, patrz http://www.pinvoke.net/default.aspx/kernel32/QueryPerformanceCounter.html. Właśnie tego używa klasa Stopwatch.

Aby uzyskać więcej informacji, zobacz How to get timestamp of tick precision in .NET/C#?.

Stopwatch.GetTimestamp() daje dostęp do tej metody:

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

AFAIK StopWatch używa QueryPerformanceCounter wewnętrznie jeśli jest dostępny – codymanix

+0

Tak, wewnętrzna implementacja 'Stopwatch.GetTimestamp()' faktycznie zapewnia dostęp do tej metody. –

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

To jest rzeczywiście, jak różne metody konwersji Unix są realizowane w klasie DateTimeOffset (.NET Framework 4.6+, .NET 1.3 + standardowa):

long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds(); 
+49

Tytuł to "pobierz czas w milisekundach". Ta odpowiedź jest pomocna. – Aerospace

+27

Tak, dla tych z nas, którzy szukają odpowiedzi na postawione pytanie, było to bardzo pomocne, dziękuję. – user430788

+1

Jeśli chcesz ułamków dziesiętnych (nawet jeśli 'DateTime.Now' nie jest często" aktualizowany "), użyj zamiast tego' decimal milliseconds = DateTime.Now.Ticks/(decimal) TimeSpan.TicksPerMillisecond; '. –

4

użyłem DateTime.Now.TimeOfDay.TotalMilliseconds (dla bieżącego dnia), nadzieję, że to pomaga, jak również.

+1

, który nie zwróci wartości rosnących (tak jak oryginał wymagany plakat), ponieważ TimeOfDay jest resetowany do zera codziennie o północy. Dodatkowo miałoby to te same potencjalne problemy, o których wspomniał plakat, gdy używasz właśnie DateTime. Teraz otrzymujesz łączną liczbę milisekund. –

+2

Jim O'Neil Zgadzam się z tobą, dlatego wspomniałem "(na bieżący dzień)" w moim poście ... Btw, moje rozwiązanie zadziałało na mój problem, ponieważ mój problem nie dotyczył konkretnej daty, po prostu potrzebowałem aby uzyskać część Milliseconds do użycia jako licznik, więc opublikowałem ją tutaj. Jestem tu nowy, więc gdybym zamieścił go w niewłaściwym miejscu, przepraszam :) – Sarvan

1

Użyj System.DateTime.Now.ToUniversalTime(). To sprawia, że ​​twoje czytanie jest w znanym formacie milisekundy opartym na referencjach, który całkowicie eliminuje zmianę dnia, itp.

+0

Dobrze wiedzieć, ale nie ma to znaczenia dla zadawanego pytania, co dotyczy czasu (pomiaru upływu czasu), a nie dokładnego komunikowania czasu. – ToolmakerSteve

5

Używam poniższej klasy. Znalazłem go raz w Internecie, postulowałem, aby był najlepszy TERAZ().

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

Źródło nieznane.

+3

FWIW, cały punkt tego powszechnie używanego fragmentu, służy do tworzenia znacznika czasu zgodnego ze standardem znacznika czasu Unix. W tym celu jest to niezbędne. Jeśli ktoś chce robić tylko czas, jest niepotrzebnie drogi. – ToolmakerSteve

Powiązane problemy