C # DateTime.Ora precisione

Ho appena eseguito un comportamento imprevisto con DateTime.UtcNow mentre eseguivo alcuni test unitari. Sembra che quando si chiama DateTime.Now/UtcNow in rapida successione, sembra che si restituisca lo stesso valore per un intervallo di tempo più lungo del previsto, invece di acquisire incrementi di millisecondo più precisi.

So che esiste una class di cronometro che sarebbe più adatta per eseguire misurazioni precise del tempo, ma ero curioso di sapere se qualcuno potesse spiegare questo comportamento in DateTime? Esiste una precisione ufficiale documentata per DateTime.Ora (ad esempio, precisa entro 50 ms?)? Perché DateTime.Ora sarà reso meno preciso di quello che potrebbe gestire la maggior parte degli orologi della CPU? Forse è solo progettato per il minimo comune denominatore della CPU?

public static void Main(string[] args) { var stopwatch = new Stopwatch(); stopwatch.Start(); for (int i=0; i<1000; i++) { var now = DateTime.Now; Console.WriteLine(string.Format( "Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond)); } stopwatch.Stop(); Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}", stopwatch.ElapsedMilliseconds); Console.ReadLine(); } 

Perché DateTime.Ora sarà reso meno preciso di quello che potrebbe gestire la maggior parte degli orologi della CPU?

Un buon orologio dovrebbe essere sia preciso che preciso ; quelli sono diversi Come dice la vecchia battuta, un orologio fermo è esattamente preciso due volte al giorno, un orologio al minuto lento non è mai preciso in qualsiasi momento. Ma l’orologio un minuto lento è sempre preciso al minuto più vicino, mentre un orologio fermo non ha alcuna precisione utile.

Perché il DateTime dovrebbe essere preciso , ad esempio un microsecondo quando non può essere accurato al microsecondo? La maggior parte delle persone non ha alcuna fonte per i segnali orari ufficiali che siano precisi al microsecondo. Dando quindi sei cifre dopo la cifra decimale di precisione , gli ultimi cinque dei quali sono immondizia .

Ricorda, lo scopo di DateTime è rappresentare una data e un’ora . I tempi di alta precisione non hanno affatto lo scopo di DateTime; come si nota, questo è lo scopo di StopWatch. Lo scopo di DateTime è rappresentare una data e un’ora per scopi come visualizzare l’ora corrente all’utente, calcolare il numero di giorni fino al martedì successivo e così via.

In breve, “che ore sono?” e “quanto ci è voluto?” sono domande completamente diverse; non utilizzare uno strumento progettato per rispondere a una domanda per rispondere all’altra.

Grazie per la domanda; questo sarà un buon articolo del blog! 🙂

La precisione di DateTime è in qualche modo specifica per il sistema su cui viene eseguito. La precisione è correlata alla velocità di un interruttore di contesto, che tende ad essere intorno a 15 o 16 ms. (Sul mio sistema, in realtà sono circa 14 ms dai miei test, ma ho visto alcuni laptop dove è più vicino a un’accuratezza di 35-40 ms.)

Peter Bromberg ha scritto un articolo sulla temporizzazione del codice di alta precisione in C #, che ne discute.

Vorrei un preciso Datetime.Ora :), quindi ho preparato questo:

 public class PreciseDatetime { // using DateTime.Now resulted in many many log events with the same timestamp. // use static variables in case there are many instances of this class in use in the same program // (that way they will all be in sync) private static readonly Stopwatch myStopwatch = new Stopwatch(); private static System.DateTime myStopwatchStartTime; static PreciseDatetime() { Reset(); try { // In case the system clock gets updated SystemEvents.TimeChanged += SystemEvents_TimeChanged; } catch (Exception) { } } static void SystemEvents_TimeChanged(object sender, EventArgs e) { Reset(); } // SystemEvents.TimeChanged can be slow to fire (3 secs), so allow forcing of reset static public void Reset() { myStopwatchStartTime = System.DateTime.Now; myStopwatch.Restart(); } public System.DateTime Now { get { return myStopwatchStartTime.Add(myStopwatch.Elapsed); } } } 

Per quello che vale, a parte il controllo effettivo della fonte .NET, Eric Lippert ha fornito un commento su questa domanda SO affermando che DateTime ha una precisione di circa 30 ms. Il ragionamento per non essere accurato al nanosecondo, nelle sue parole, è che “non ha bisogno di essere”.

Da MSDN scoprirai che DateTime.Now ha una risoluzione approssimativa di 10 millisecondi su tutti i sistemi operativi NT.

La precisione effettiva dipende dall’hardware. È ansible ottenere una precisione migliore utilizzando QueryPerformanceCounter .

Dalla documentazione MSDN :

La risoluzione di questa proprietà dipende dal timer di sistema.

Affermano inoltre che la risoluzione approssimativa su Windows NT 3.5 e successivi è 10 ms 🙂