2013-02-28 6 views
8

Podczas obliczania milisekundowej różnicy między dwoma obiektami DateTime zawsze wydaje mi się, że zwracana jest liczba, w której dziesiętna część liczby jest taka sama, jak liczba całkowita składnika. Na przykład: 1235.1235Dlaczego suma milisekund długości okresu ma takie same cyfry w częściach całkowitych i dziesiętnych?

Dlaczego tak się dzieje? czy robię coś źle? Czy jest to dziwactwo języka lub ograniczenie ziarnistości lub coś w tym stylu?

Można to wykazać za pomocą następującego kodu:

 DateTime then = DateTime.Now; 
     Thread.Sleep(1234); 
     DateTime now = DateTime.Now; 
     TimeSpan taken = now - then; 
     string result = taken.TotalMilliseconds.ToString(CultureInfo.InvariantCulture); 
     //result = "1235.1235" 

Jak komentował CodesInChaos:

DateTime` nie jest z dokładnością do tego poziomu dokładności: patrz C# DateTime.Now precision

Jednak - że nie całkiem wyjaśnia to zachowanie.

+1

to prawdopodobnie szczęście losowania. również: spójrz na klasę 'Stopwatch'. –

+2

Ile razy jest zawsze? –

+1

'DateTime.Now' * w najlepszym przypadku * ma dokładność milisekundy. W praktyce często jest to zaledwie 16 ms. Podejrzewam, że część ułamkowa jest artefaktem, w jaki sposób okna (nie .net) reprezentują dane wewnątrz. – CodesInChaos

Odpowiedz

4

Istnieje techniczne wytłumaczenie tego, nie mogę w inny sposób udowodnić, że wyjaśnia to twoją obserwację. Z pewnością nie jest to repro na mojej maszynie.

Na początek szukacie cyfr szumów, zegar systemu operacyjnego nie jest na tyle dokładny, aby zapewnić dokładność poniżej milisekund. Upewnij się więc, że nigdy nie polegasz na ich wartości, aby zrobić coś ważnego. Jeśli chcesz zmierzyć interwał z wysoką rozdzielczością, musisz zamiast tego użyć Stopwatch.

Na zegar systemu operacyjnego wpływ mają aktualizacje z serwera czasu. Większość urządzeń jest skonfigurowana tak, aby okresowo kontaktowały się z time.windows.com, aby ponownie skalibrować zegar. To pozbywa się dryfowania zegara, sprzęt komputerowy zwykle nie jest wystarczająco dobry, aby utrzymać dokładność czasu do lepszej niż sekunda przez miesiąc. Kryształy o niskiej tolerancji są drogie i nigdy całkowicie nie dryfują ze względu na temperaturę i efekty starzenia. Co sekundę wskakuje sekunda, aby synchronizować zegary ze spowalniającym obrotem planety. Ostatni z nich spowodował awarię wielu maszyn Linux, Google "Linux leap second bug" dla przyjemnej lektury.

Ważne jest, co dzieje się, gdy komputer otrzymuje nową aktualizację wymagającą dostosowania zegara. Windows nagle zeruje wartość zegara, co powoduje poważne problemy z programami, które zwracają uwagę na zegar i oczekują, że będzie on konsekwentnie zwiększał się w przewidywalnych ilościach.

Zamiast tego dodaje trochę za jednym razem z każdym przyrostem taktu zegara. W efekcie sprawi, że zegar będzie działał wolniej lub szybciej, więc stopniowo zmieni różnicę i ponownie osiągnie dokładność. Być może widzisz, gdzie to idzie, dodatkowe dodane mikrosekundy są proporcjonalne do długości interwału. Widzenie interwału powtórzonego w cyfrach szumów jest wiarygodne.

Jedynym sposobem na udowodnienie tej teorii jest wybranie funkcji GetSystemTimeAdjustment(). Zwróci wartości niezerowe, gdy trwa regulacja czasu systemowego. Następnie wybierz funkcję SetSystemTimeAdjustment(), aby ją wyłączyć i obserwuj, czy ma to wpływ na wyświetlaną wartość. Lub po prostu poczekaj wystarczająco długo, aż zegar się dogoni, więc nie będzie już więcej regulowany.

+0

Więc jeśli testowałeś to na świeżej instalacji Windows, 'GetSystemTimeAdjustment()' powinien zwrócić zero, a nie zobaczysz takiego zachowania? –

+0

To chyba najgorsza pora, z pewnością zegar jest wyłączony. Nie podłączaj kabla sieciowego. –

+0

Interesujące :-) Sprawdziłem TimeAdjustment i jest on włączony - przyrost jest zwracany jako 156001 ticków i nie wydaje się być różny. Aby to sprawdzić, będę musiał złapać go w niezerowym momencie, aby sprawdzić, czy wyniki są inne. (Nie udało mi się ustawić SetSystemTimeAdjustment w celu wyłączenia dopasowania - spróbuję później). – Kaine

Powiązane problemy