Jak uzyskać aktualny znacznik czasu w milisekundach od 1970 roku, tak jak robi to Java


144

W Javie możemy użyć System.currentTimeMillis()do uzyskania aktualnego znacznika czasu w milisekundach od czasu epoki, który wynosi -

różnica, mierzona w milisekundach, między aktualnym czasem a północą 1 stycznia 1970 UTC.

W C ++ jak uzyskać to samo?

Obecnie używam tego, aby uzyskać aktualną sygnaturę czasową -

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;

To wygląda dobrze czy nie?

Odpowiedzi:


251

Jeśli masz dostęp do bibliotek C ++ 11, sprawdź std::chronobibliotekę. Możesz go użyć do obliczenia milisekund od Epoki Uniksa w następujący sposób:

#include <chrono>

// ...

using namespace std::chrono;
milliseconds ms = duration_cast< milliseconds >(
    system_clock::now().time_since_epoch()
);

99
Ładny. Dodaj count () na końcu wiersza, aby uzyskać liczbę milisekund w podstawowym formacie typu.
P1r4nh4

1
@lining: obie epoki prawdopodobnie będą takie same, ale ich wartości mogą być różne. steady_clockzawsze będzie postępować naprzód, jest to prawdziwa miara czasu od jego epoki, podczas gdy system_clockmoże być reprezentacją logicznego czasu od tej epoki. Z każdą sekundą przeskokową te dwa mogą się bardziej oddalać w zależności od implementacji systemu.
Oz.

4
O ile wiem, epoka każdego z zegarów jest zależna od implementacji. Konwencja ma system_clockbyć taka sama jak w epoce UNIX, ale specyfikacja mówi tylko, że musi to być systemowy zegar ścienny czasu rzeczywistego. Nie ma wymogu, steady_clockaby pasował do rzeczywistości, tylko że idzie do przodu.
Oz.

1
@Jason Poza tym, że gettimeofday nie jest dostępny w systemie Windows, biblioteka chrono może zapewnić wyższą rozdzielczość (gtod jest ograniczona do mikrosekund), zapewnia jednostki czasu w sposób bezpieczny dla typu, dzięki czemu kompilator może wymusić konwersje jednostek i działa z normalnymi operatorami arytmetycznymi ( dodawanie timevalstruktur jest denerwujące).
Oz.

4
Deweloperzy Javascript śmieją się ze mnie, widząc to :(
fantastyczne

44

posługiwać się <sys/time.h>

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

odnieś to .


dobre rozwiązanie, również myślę, że powinno być gettimeofday (& tp, NULL);
Adem,

5
Przede wszystkim jest to C, a nie C ++. Po drugie, istnieją problemy z gettimeofday, zobaczyć to na przykładzie.
rustyx

22

Ta odpowiedź jest bardzo podobna do tej z Oz. , Używając <chrono>dla C ++ - nie pobrałem jej z Oz. chociaż...

Podniosłem oryginalny fragment u dołu tej strony i nieznacznie zmodyfikowałem go, aby był kompletną aplikacją konsolową. Uwielbiam używać tej lil 'starej rzeczy. To fantastyczne, jeśli wykonujesz dużo skryptów i potrzebujesz niezawodnego narzędzia w systemie Windows, aby uzyskać epokę w rzeczywistych milisekundach bez uciekania się do używania VB lub mniej nowoczesnego, mniej przyjaznego dla czytelnika kodu.

#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;
}

Otrzymuję liczbę ujemną, -560549313to nie jest prawda, prawda?
Noitidart

1
@Noitidart Czy możesz mi powiedzieć, jakiej platformy i kompilatora C ++ używasz? Używam tego przez cały czas z narzędziami do automatyzacji i nigdy nie widziałem ujemnego wyniku o.0. Jednak z przyjemnością to sprawdzam. Czy jest to bezpośrednia kopia, czy zmodyfikowany / zintegrowany program? Chcę się tylko upewnić, że pochodzi tylko z tego kodu.
kayleeFrye_onDeck

5
Ah @kayleeFrye_onDeck to dlatego, że używałem int! int nowms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();. Przerzuciłem to na int64_ti działa! Dziękuję bardzo za prośbę o więcej informacji!
Noitidart

unsigned long longjest bardziej przenośny i __int64jest dostępny tylko na MSVC.
SS Anne

nie ma __int64typu w standardowym C ++. std::int64_tZamiast tego można użyć .
jaskmar

19

Od C ++ 11 możesz używać std::chrono:

  • pobierz aktualny czas systemowy: std::chrono::system_clock::now()
  • uzyskać czas od epoki: .time_since_epoch()
  • przetłumacz jednostkę bazową na milisekundy: duration_cast<milliseconds>(d)
  • przetłumacz std::chrono::millisecondsna liczbę całkowitą ( uint64_taby uniknąć przepełnienia)
#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;
}

Proponuję użyć unsigned long longzamiast uint64_t.
csg

1
Dlaczego unsigned long longzamiast uint64_t? Mam naturalną wolę pisania krótszych
czcionek

13

Jeśli używasz gettimeofday, musisz rzucać zbyt długo, w przeciwnym razie wystąpią przepełnienia, a tym samym nie rzeczywista liczba milisekund od epoki: long int msint = tp.tv_sec * 1000 + tp.tv_usec / 1000; poda Ci liczbę taką jak 767990892, czyli około 8 dni po epoce ;-).

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

-26

Uwzględnij <ctime>i używaj timefunkcji.


32
Zwraca liczbę sekund, które upłynęły od epoki. Nie milisekundy.
Progo
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.