2009-11-08 25 views

Respuesta

36

Para obtener el tiempo expresado como UTC, use GetSystemTime en la API de Win32.

SYSTEMTIME st; 
GetSystemTime(&st); 

SYSTEMTIME se documenta como que tiene estos miembros relevantes:

WORD wYear; 
WORD wMonth; 
WORD wDayOfWeek; 
WORD wDay; 
WORD wHour; 
WORD wMinute; 
WORD wSecond; 
WORD wMilliseconds; 

Como shf301 amablemente señala a continuación, GetLocalTime (con el mismo prototipo) dará lugar a una tiempo corregido a zona horaria actual del usuario.

Aquí tiene algunas buenas respuestas, dependiendo de lo que esté buscando. Si está buscando solo hora del día, mi respuesta es la mejor, si necesita fechas concretas para la aritmética, considere la de Alex. Hay a lot of ways to skin the time cat en Windows, y algunos de ellos son más precisos que otros (y nadie ha mencionado QueryPerformanceCounter todavía).

+5

Uso GetLocalTime para obtener el tiempo y fecha como el usuario vería. http://msdn.microsoft.com/en-us/library/ms724338%28VS.85%29.aspx – shf301

+2

QueryPerformanceCounter ... Creo que podría estar bromeando, ya que tiene muchos inconvenientes que lo convertirían en un pobre selección aquí. –

+1

@Heath: Sí, lo siento, no estaba claro. :) –

2

Según las necesidades de su aplicación, existen seis opciones comunes. Este Dr Dobbs Journal article le dará toda la información (y más) que necesita para elegir la mejor.

En su caso específico, a partir de este artículo:

GetSystemTime() recupera la hora actual sistema y crea la instancia de una estructura SYSTEMTIME, que es compuesto por una serie de campos separados incluyendo el año, el mes , día, horas, minutos, segundos y milisegundos.

+1

Corrígeme si me equivoco, pero ¿GetTickCount no da la cantidad de milisegundos que han pasado desde que se lanzó la aplicación? – Mark

+1

Sí, es cierto, agregué la cita incorrecta. Lo siento. Lo he arreglado ahora. – Ash

+1

@Mark: desde que se inició el sistema. 'GetTickCount64', desde Windows Vista, expande eso a 64 bits; el primero está limitado a 32. –

2

Utilice GetSystemTime, primero; luego, si lo necesita, puede llamar al SystemTimeToFileTime en la estructura SYSTEMTIME que el primero rellena para usted. Un FILETIME es un recuento de 64 bits de intervalos de 100 nanosegundos desde una época, y por lo tanto más adecuado para la aritmética; a SYSTEMTIME es una estructura con todos los campos esperados (año, mes, día, hora, etc., hasta milisegundos). Si desea saber "cuántos milisegundos han transcurrido desde la medianoche", por ejemplo, restar dos estructuras FILETIME (una para la hora actual, una obtenida al convertir el mismo SYSTEMTIME después de poner a cero los campos apropiados) y dividir por la potencia adecuada de diez es probablemente el enfoque más simple disponible.

+0

Jed, a la derecha, escribiendo de memoria, pensé que había un guión bajo: editando ahora para corregir, tx. –

+0

Eso es lo que pensé. :) –

41

La forma más fácil (y más directa) es llamar GetSystemTimeAsFileTime(), que devuelve un FILETIME, una estructura que almacena el número de 64 bits de intervalos de 100 nanosegundos desde la medianoche del 1 de Ene, 1601.

Al menos al la hora de Windows NT 3.1, 3.51 y 4.01, la API GetSystemTimeAsFileTime() fue la API de modo de usuario más rápida capaz de recuperar la hora actual. También ofrece la ventaja (en comparación con GetSystemTime() -> SystemTimeToFileTime()) de ser una única llamada a API, que en circunstancias normales no puede fallar.

Para convertir un FILETIME ft_now; a un número entero de 64 bits llamado ll_now, utilice la siguiente:
ll_now = (LONGLONG)ft_now.dwLowDateTime + ((LONGLONG)(ft_now.dwHighDateTime) << 32LL);

continuación, usted puede dividir por el número de intervalos de 100 nanosegundos en un milisegundo (10.000 de ellas) y tienen milisegundos desde la época Win32.

Para convertir a la época Unix, restar 116444736000000000LL para llegar a Jan 1, 1970.

Usted mencionó el deseo de encontrar el número de milisegundos en el día actual. Como la época de Win32 comienza a medianoche, la cantidad de milisegundos pasados ​​hasta el momento se puede calcular a partir del tiempo de archivo con una operación de módulo. Específicamente, debido a que hay 24 hours/day * 60 minutes/hour * 60 seconds/minute * 1000 milliseconds/second = 86,400,000 milliseconds/day, puede usar el módulo del tiempo del sistema en milisegundos módulo 86400000LL.

Para una aplicación diferente, puede que uno no quiera usar el módulo. Especialmente si uno está calculando los tiempos transcurridos, uno podría tener dificultades debido a envolverse a la medianoche. Estas dificultades se pueden resolver, el mejor ejemplo que conozco es la línea de Linus Torvald en el kernel de Linux que maneja el conteo del contador.

Tenga en cuenta que la hora del sistema se devuelve como hora UTC (tanto en el caso de GetSystemTimeAsFileTime() como simplemente GetSystemTime()). Si necesita la hora local configurada por el administrador, puede usar GetLocalTime().

+2

+1 por desglose en profundidad. Tenga cuidado de agregar el bit para NT5.1 + con respecto a "al menos en el momento de Windows NT 3.1, 3.51 y 4.01 ... user-api más rápido". ¿Implica que ya no es el caso? –

+1

Solo implica que no puedo jurar sobre la situación post-4.01, pero de hecho creo que esta API sigue siendo la más rápida. En los viejos tiempos, se implementó como un par de operaciones MOV: SystemTimeAsFileTime se almacena en una página de memoria compartida que pueden leer todos los procesos. –

+1

Muy agradable, en profundidad, respuesta. Para responder a su última pregunta, estoy simulando un escenario de entorno, donde a medida que avanza el día, el entorno se vuelve más oscuro (como lo haría el aire libre).Es solo cuestión de obtener la hora del día (en milisegundos desde la medianoche es el formato que mi motor lee actualmente) para sincronizar :) – Mark

1

Aquí hay algunos códigos que funcionan en Windows que he usado en un proyecto Open Watcom C. Se debe trabajar en C++ Devuelve segundos (no milisegundos) utilizando _dos_gettime o gettime

double seconds(void) 
    { 
    #ifdef __WATCOMC__ 
    struct dostime_t t; 
    _dos_gettime(&t); 
    return ((double)t.hour * 3600 + (double)t.minute * 60 + (double)t.second + (double)t.hsecond * 0.01); 
    #else 
    struct time t; 
    gettime(&t); 
    return ((double)t.ti_hour * 3600 + (double)t.ti_min * 60 + (double)t.ti_sec + (double)t.ti_hund * 0.01); 
    #endif 
} 
3

Un ejemplo de corte a la persecución de la respuesta de Jed arriba:

const std::string currentDateTime() { 

SYSTEMTIME st, lt; 

GetSystemTime(&st); 

char currentTime[84] = ""; 

sprintf(currentTime,"%d/%d/%d %d:%d:%d %d",st.wDay,st.wMonth,st.wYear, st.wHour, st.wMinute, st.wSecond , st.wMilliseconds); 

return string(currentTime); } 
+0

'sprintf (tiempo actual,"% .4d% .2d% .2d% .2d% .2d% .2d% .4d ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); 'para una cadena de longitud fija – Antonio

+0

Esto obtiene la hora UTC; 'GetLocalTime()' funciona de manera similar, pero le da tiempo a la zona horaria local –

Cuestiones relacionadas