Bei der Berechnung der Millisekunden-Differenz zwischen zwei DateTime
-Objekten scheine ich immer eine Zahl zu erhalten, bei der der Dezimalteil der Zahl der Ganzzahl-Komponente der Zahl entspricht. Zum Beispiel: 1235.1235
Warum passiert das? Mache ich etwas falsch? Ist das eine Eigenart der Sprache oder eine Begrenzung der DateTime
Granularität oder etwas?
Dies kann mit dem folgenden Code demonstriert werden:
%Vor%Wie von CodesInChaos kommentiert:
DateTime 'stimmt nicht mit dieser Genauigkeit überein: siehe C # DateTime.Now precision
Allerdings - das erklärt dieses Verhalten nicht ganz.
Dafür gibt es eine technische Erklärung, ich kann nicht anders beweisen, dass es Ihre Beobachtung erklärt. Es ist sicherlich nicht meine Maschine repro.
Für den Anfang suchen Sie eine Rauschzahl, die Betriebssystemuhr ist nicht annähernd genau genug, um Ihnen eine Genauigkeit im Millisekundenbereich zu geben. Also stellen Sie sicher, dass Sie sich nie auf ihren Wert verlassen, um etwas Wichtiges zu tun. Wenn Sie ein Intervall mit hoher Auflösung messen möchten, müssen Sie stattdessen die Stoppuhr verwenden.
Die Betriebssystemuhr wird von Aktualisierungen von einem Zeitserver beeinflusst. Die meisten Maschinen sind so eingerichtet, dass sie sich periodisch mit time.windows.com
in Verbindung setzen, um die Uhr neu zu kalibrieren. Dadurch wird die Taktdrift beseitigt, die Maschinenhardware ist normalerweise nicht gut genug, um die Zeit über einen Monat besser als eine Sekunde zu halten. Kristalle mit geringer Toleranz sind teuer und niemals völlig ohne Drift aufgrund von Temperatur- und Alterungseffekten. Und eine Schaltsekunde wird hin und wieder eingefügt, um die Uhren mit der Verlangsamung der Rotation des Planeten zu synchronisieren. Der letzte hat viele Linux-Rechner abgestürzt, google "Linux leap second bug" für etwas Spaß beim Lesen.
Hier kommt es darauf an, wenn Ihr Computer ein neues Update erhält, das eine Anpassung der Uhr erfordert. Windows springt nicht plötzlich den Wert der Uhr, was zu großen Problemen mit Programmen führt, die auf die Uhr achten und erwarten, dass sie in vorhersagbaren Mengen konsistent zunimmt.
Stattdessen fügt es mit jedem Taktimpulsschritt ein Bit auf einmal hinzu. Dadurch wird die Uhr etwas langsamer oder schneller, so dass die Differenz allmählich wieder ausgeglichen wird. Vielleicht können Sie sehen, wohin das geht, die extra hinzugefügten Mikrosekunden sind proportional zur Länge des Intervalls. Es ist also plausibel, das in den Rauschziffern wiederholte Intervall zu sehen.
Der einzige wirkliche Weg, diese Theorie zu beweisen, besteht darin, GetSystemTimeAdjustment () zu pinnen. Wenn eine Systemzeitanpassung durchgeführt wird, werden Werte ungleich null zurückgegeben. Und dann pinvoke SetSystemTimeAdjustment (), um es zu deaktivieren und zu beobachten, ob das den Wert unterscheidet, den Sie sehen. Oder warte einfach lange genug, bis die Uhr aufgeholt hat, damit sie nicht mehr eingestellt wird.