Cómo obtener la marca de tiempo actual en milisegundos desde 1970 tal como lo hace Java

134

En Java, podemos usar System.currentTimeMillis()para obtener la marca de tiempo actual en milisegundos desde el tiempo de época que es:

la diferencia, medida en milisegundos, entre la hora actual y la medianoche del 1 de enero de 1970 UTC.

En C ++, ¿cómo obtener lo mismo?

Actualmente estoy usando esto para obtener la marca de tiempo actual:

struct timeval tp;
gettimeofday(&tp, NULL);
long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000; //get current timestamp in milliseconds

cout << ms << endl;

Esto se ve bien o no?

AKIWEB
fuente

Respuestas:

239

Si tiene acceso a las bibliotecas C ++ 11, consulte la std::chronobiblioteca. Puede usarlo para obtener los milisegundos desde la época de Unix así:

#include <chrono>

// ...

using namespace std::chrono;
milliseconds ms = duration_cast< milliseconds >(
    system_clock::now().time_since_epoch()
);
Onz.
fuente
92
Agradable. Agregue count () al final de la línea para obtener el número de milisegundos en un formato de tipo fundamental.
P1r4nh4
1
@linea: Es probable que ambas épocas sean iguales, pero sus valores podrían ser diferentes. steady_clocksiempre avanzará, es una verdadera medida del tiempo desde su época, mientras que system_clockpuede ser una representación del tiempo lógico desde la época. Por cada segundo intercalar, los dos podrían separarse más dependiendo de la implementación del sistema.
Oz
44
Hasta donde yo sé, la época de cada uno de los relojes depende de la implementación. La convención es para system_clockser igual a la época de UNIX, pero la especificación solo dice que debe ser el reloj de pared en tiempo real de todo el sistema. No hay ningún requisito para steady_clockque coincida con la realidad, solo que solo avance.
Oz
1
@ Jason Además de que gettimeofday no está disponible en Windows, la biblioteca de crono puede ofrecerle una resolución más alta (gtod está limitado a microsegundos), proporciona unidades de tiempo de forma segura para que el compilador pueda aplicar conversiones de unidades y funciona con operadores aritméticos normales ( agregar timevalestructuras es molesto).
Oz
3
Los desarrolladores de Javascript se están riendo de mí al ver esto :(
fantastory
42

utilizar <sys/time.h>

struct timeval tp;
gettimeofday(&tp, NULL);
long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;

referir esto .

Molesto
fuente
buena solución, también creo que debería ser gettimeofday (& tp, NULL);
Además el
44
En primer lugar, esto es C, no C ++. En segundo lugar, hay problemas con gettimeofday, vea esto por ejemplo.
rustyx
17

Esta respuesta es bastante similar a la de Oz. , Usando <chrono>C ++: no la tomé de Oz. aunque...

Recogí el fragmento original en la parte inferior de esta página y lo modifiqué ligeramente para que fuera una aplicación de consola completa. Me encanta usar esta pequeña cosa. Es fantástico si hace muchos scripts y necesita una herramienta confiable en Windows para obtener la época en milisegundos reales sin recurrir al uso de VB, o algún código menos moderno y menos amigable para el lector.

#include <chrono>
#include <iostream>

int main() {
    unsigned __int64 now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    std::cout << now << std::endl;
    return 0;
}
kayleeFrye_onDeck
fuente
Me sale un número negativo, -560549313esto no está bien, ¿verdad?
Noitidart
1
@Noitidart ¿Puede decirme qué plataforma y compilador de C ++ está utilizando? Lo uso todo el tiempo con herramientas de automatización, y nunca he visto una salida negativa de 0.0 Sin embargo, estoy más que feliz de comprobarlo. Además, ¿es una copia directa o un programa modificado / integrado? Solo quiero asegurarme de que solo se origine en este código.
kayleeFrye_onDeck
55
Ah @kayleeFrye_onDeck es porque estaba usando int! int nowms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();. ¡Cambié eso int64_ty funciona! ¡Muchas gracias por pedir más información para ayudar!
Noitidart
unsigned long longes más portátil y __int64solo está disponible en MSVC.
SS Anne
No hay ningún __int64tipo en C ++ estándar. Uno puede usar std::int64_ten su lugar.
Jaskmar
14

Desde C ++ 11 puedes usar std::chrono:

  • obtener la hora actual del sistema: std::chrono::system_clock::now()
  • obtener tiempo desde la época: .time_since_epoch()
  • traducir la unidad subyacente a milisegundos: duration_cast<milliseconds>(d)
  • traducir std::chrono::millisecondsa entero ( uint64_tpara evitar el desbordamiento)
#include <chrono>
#include <cstdint>
#include <iostream>

uint64_t timeSinceEpochMillisec() {
  using namespace std::chrono;
  return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
}

int main() {
  std::cout << timeSinceEpochMillisec() << std::endl;
  return 0;
}
Alessandro Pezzato
fuente
Sugiero usar en unsigned long longlugar de uint64_t.
csg
13

Si usa gettimeofday, tiene que emitir demasiado tiempo, de lo contrario obtendrá desbordamientos y, por lo tanto, no el número real de milisegundos desde la época: largo int msint = tp.tv_sec * 1000 + tp.tv_usec / 1000; le dará un número como 767990892 que es redondo 8 días después de la época ;-).

int main(int argc, char* argv[])
{
    struct timeval tp;
    gettimeofday(&tp, NULL);
    long long mslong = (long long) tp.tv_sec * 1000L + tp.tv_usec / 1000; //get current timestamp in milliseconds
    std::cout << mslong << std::endl;
}
rli
fuente
-25

Incluir <ctime>y usar la timefunción.

Owen
fuente
30
Esto devuelve los segundos desde la época. No milisegundos.
Progo