2010-04-09 18 views
13

quiero tener una marca de tiempo para registros en un proyecto de Windows Mobile. La precisión debe estar en el rango de cien milisegundos al menos.Milisegundos en DateTime.Now en .NET Compact Framework siempre es cero?

Sin embargo, mi llamada a DateTime.Now devuelve un objeto DateTime con la propiedad Millisecond establecida en cero. Además, la propiedad Ticks se redondea en consecuencia.

¿Cómo obtener una precisión de tiempo mejor?
Recuerde que mi código se ejecuta en Compact Framework, versión 3.5. Uso un dispositivo HTC Touch Pro 2.

Sobre la base de la respuesta de MusiGenesis he creado la siguiente clase que solucionó este problema:

/// <summary> 
/// A more precisely implementation of some DateTime properties on mobile devices. 
/// </summary> 
/// <devdoc>Tested on a HTC Touch Pro2.</devdoc> 
public static class DateTimePrecisely 
{ 
    /// <summary> 
    /// Remembers the start time when this model was created. 
    /// </summary> 
    private static DateTime _start = DateTime.Now; 
    /// <summary> 
    /// Remembers the system uptime ticks when this model was created. This 
    /// serves as a more precise time provider as DateTime.Now can do. 
    /// </summary> 
    private static int _startTick = Environment.TickCount; 

    /// <summary> 
    /// Gets a DateTime object that is set exactly to the current date and time on this computer, expressed as the local time. 
    /// </summary> 
    /// <returns></returns> 
    public static DateTime Now 
    { 
     get 
     { 
      return _start.AddMilliseconds(Environment.TickCount - _startTick); 
     } 
    } 
} 
+2

No es necesario volver a marcar su pregunta con "[SOLUCIONADO]". Puede ver que la pregunta tiene una respuesta aceptada en el contador de respuestas amarillas en la página principal o en los resultados de búsqueda. – spoulson

+2

Como fuente de esto, debo mencionar que esta clase casi con certeza se "alejará" del valor devuelto por el 'DateTime.Now' regular, posiblemente hasta unos pocos segundos (o incluso mucho más) en el transcurso de un día.Puede probar esto simplemente configurando la propiedad _start de su clase, esperando un poco de tiempo (un día o lo que sea) y comparando 'DateTime.Now' con' DateTimePrecisely.Now'. – MusiGenesis

+1

Si considera que la cantidad de deriva es inaceptable, puede agregar un método 'Restablecer 'que obtiene valores nuevos para' _start' y '_startTick', y llámelo periódicamente. Esto lo mantendrá sincronizado a largo plazo con el reloj del sistema y le dará (supuestamente) una resolución de milisegundos. O use el código 'ctacke'. – MusiGenesis

Respuesta

14

Environment.TickCount devolverá el número de milisegundos que Windows (o Windows Mobile) ha estado funcionando desde el último reinicio.

Para utilizar esta, añadir estas dos variables a nivel de formulario a su código:

private DateTime _start; 
private int _startTick; 

En el evento Load del formulario, hacer esto:

private void Form1_Load(object sender, EventArgs e) 
{ 
    _start = DateTime.Now; 
    _startTick = Environment.TickCount; 
} 

Siempre que necesite un objeto DateTime con milisegundos , hacer esto:

DateTime timeStamp = 
    _start.AddMilliseconds(Environment.TickCount - _startTick); 

Environment.TickCount es un int y este valor se "ajustará" al Int32.MinValue después de 25 días más o menos. Si su dispositivo va a funcionar durante tanto tiempo sin reiniciar, querrá agregar una marca para un valor Environment.TickCount que sea menor que el último valor leído, y restablecer ambos _start y _startTick si es así.

+0

+1. esto hizo el truco. Lástima que Microsoft (o HTC?) No haga esto en su código. – Marcel

+3

Es la falla de HTC, no de Microsoft. Depende del OEM proporcionarle un tiempo al sistema operativo. – ctacke

+0

Por favor, ayúdenme ya que no veo, cómo devolverá el tiempo con más precisión. Tendrás "más dígitos", pero eso es todo, porque el tiempo de inicio ya no contiene partes fraccionarias de segundos, así que solo estás agregando números "imaginarios". Si se usa en el registro, puede ver el tiempo transcurrido entre las entradas del registro, pero no puede compararse con el tiempo de otros sistemas. – HoGo

1

La principal alternativa es la clase System.Diagnostics.Stopwatch.

Está disponible en la CE, pero tenga en cuenta la propiedad IsHighResolution. Probablemente sea falso en su dispositivo, pero verifique.

Es tan preciso como lo que obtendrá sin P/Invoke.

-3

En el marco regular v2.0 puede usar DateTime.Now.ToString ("aaaa-MM-dd HH: mm: ss.fff") para obtener milisegundos. Más f significa más precisión.

+0

No es cierto en el CF. Ver las otras respuestas a la pregunta. – ctacke

Cuestiones relacionadas