2010-10-25 22 views
89

Estoy haciendo un programa en el que necesito obtener el tiempo en milisegundos. Por tiempo, me refiero a un número que nunca es igual a sí mismo, y siempre es 1000 números más grande que hace un segundo. Intenté convertir DateTime.Now en un TimeSpan y obtener el TotalMilliseconds de eso ... pero he oído que no es perfectamente exacto.Obtenga tiempo en milisegundos usando C#

¿Hay alguna manera más fácil de hacerlo?

+0

¿Está esperando que dos llamadas conduzcan siempre a valores crecientes? En general, las llamadas más cercanas que el intervalo mínimo que permite la resolución del temporizador producirán el mismo valor. Debería agregar su propio desempate en forma de un serializador de precisión falsa. –

+14

"Un número que nunca es igual a sí mismo". Eso suena ... complicado. ;) – Mizipzor

+0

NaN encajaría realmente en ese requisito. A pesar de ser "no un número", es un tipo de número, y no es igual a sí mismo. – Yay295

Respuesta

66

Utilice la clase Stopwatch.

proporciona un conjunto de métodos y propiedades que se pueden utilizar para medir con precisión el tiempo transcurrido.

Hay algo de buena información sobre la aplicación aquí:

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

+6

cronómetro es parte de Diagnostics. ¿Debería usarse en código real? – Andrey

+4

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

+0

Esto normalmente solo es exacto a los 15 ms cercanos más o menos. –

11

La propiedad DateTime.Ticks obtiene la cantidad de marcas que representan la fecha y la hora.

10,000 Ticks es un milisegundo (10,000,000 de tics por segundo).

+4

Pero la resolución de Ticks es muy inferior a 1/10000s, quizás 1/62s – codymanix

+2

@codymanix - de MSDN: 'Una sola marca representa cien nanosegundos o una décima millonésima de segundo. Hay 10,000 tics en un milisegundo.' –

+5

Claro que sí, pero el sistema operativo no tiene la resolución para ser así de exacto. – codymanix

6

Puede probar el método nativo QueryPerformanceCounter. Consulte http://www.pinvoke.net/default.aspx/kernel32/QueryPerformanceCounter.html para obtener más información. Esto es lo que usa la clase Stopwatch.

Consulte How to get timestamp of tick precision in .NET/C#? para obtener más información.

Stopwatch.GetTimestamp() da acceso a este método:

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

AFAIK StopWatch utiliza QueryPerformanceCounter internamente si está disponible – codymanix

+0

Sí, la implementación interna de 'Stopwatch.GetTimestamp()' en realidad proporciona acceso a ese método. –

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

Esto es en realidad cómo se implementan los diferentes métodos de conversión de Unix en la clase DateTimeOffset (.NET Framework 4.6+, .NET Standard 1.3+):

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

El título es "obtener tiempo en milisegundos". Esta respuesta es útil. – Aerospace

+27

Sí, para aquellos de nosotros en busca de una respuesta a la pregunta planteada, esto fue muy útil, gracias. – user430788

+1

Si desea decimales (incluso si 'DateTime.Now' no se" actualiza "muy a menudo), por supuesto use' decimal milisegundos = DateTime.Now.Ticks/(decimal) TimeSpan.TicksPerMillisecond; 'en su lugar. –

4

que utilizan DateTime.Now.TimeOfDay.TotalMilliseconds (para el día actual), espero que le ayuda a cabo también.

+1

que no devolverá valores crecientes (como el original cartel requerido) ya que TimeOfDay se restablece a cero todos los días a la medianoche. Además, tendría los mismos problemas potenciales que el póster mencionó al usar DateTime.Now y obtener los milisegundos totales de eso. –

+2

Jim O'Neil Estoy de acuerdo contigo, es por eso que mencioné "(para el día actual)" en mi publicación ... Por cierto, mi solución funcionó para mi problema, ya que mi problema no es específico de la fecha, simplemente necesitaba para hacer que la parte de milisegundos se use como contador, así que la publiqué aquí. Soy nuevo aquí, entonces si lo publiqué en un lugar equivocado, lo siento :) – Sarvan

1

Use System.DateTime.Now.ToUniversalTime(). Eso pone su lectura en un conocido formato de milisegundos basado en referencias que elimina por completo el cambio de día, etc.

+0

Es bueno saberlo, pero no es relevante para la pregunta que se hace, que es sobre el tiempo (medición del tiempo de paso), no sobre la precisión de la comunicación del tiempo. – ToolmakerSteve

5

Utilizo la siguiente clase. Lo encontré en Internet una vez, postulado como el mejor AHORA().

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

Fuente desconocida.

+3

FWIW, el punto completo de este fragmento de código de uso común, es hacer una marca de tiempo que sea compatible con el estándar de marca de tiempo Unix. Para eso, es vital. Si uno solo quiere hacer el tiempo, es innecesariamente costoso. – ToolmakerSteve

Cuestiones relacionadas