Як отримати поточну мітку часу в мілісекундах з 1970 року саме так, як отримує Java


134

На Java ми можемо використовувати System.currentTimeMillis()поточну мітку часу в мілісекундах з часу епохи, яка становить -

різниця, виміряна в мілісекундах, між поточним часом та півночі, 1 січня 1970 року UTC.

Як на C ++ як отримати те саме?

В даний час я використовую це для отримання поточної позначки часу -

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;

Це виглядає правильно чи ні?

Відповіді:


239

Якщо у вас є доступ до бібліотек C ++ 11, ознайомтеся з std::chronoбібліотекою. Ви можете використовувати його, щоб отримати мілісекунди після Unix Epoch таким чином:

#include <chrono>

// ...

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

92
Приємно. Додайте count () в кінці рядка, щоб отримати кількість мілісекунд у форматі основного типу.
P1r4nh4

1
@lining: Обидві епохи, ймовірно, будуть однаковими, але їх значення можуть бути різними. steady_clockзавжди буде просуватися вперед, це істинна міра часу з моменту його епохи, хоча system_clockможе бути відображенням логічного часу з епохи. Кожну стрибкову секунду вони можуть зростати далі, залежно від впровадження системи.
Оз.

4
Наскільки мені відомо, епоха кожного з годин залежить від реалізації. Конвенція system_clockповинна бути такою самою, як епоха UNIX, але специфікація лише говорить, що це повинен бути загальносистемний настінний годинник у режимі реального часу. Немає вимоги steady_clockвідповідати дійсності, лише вона рухається лише вперед.
Оз.

1
@Jason Окрім того, що gettimeofday не доступний у Windows, бібліотека хроно може давати вам більш високу роздільну здатність (gtod обмежена мікросекундами), забезпечує одиниці часу безпечним для типу способом, щоб компілятор міг здійснювати перетворення одиниць і працює з звичайними арифметичними операторами ( додавання timevalструктур дратує).
Оз.

3
Розробники Javascript сміються з мене, бачачи це :(
фантастика

42

використання <sys/time.h>

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

зверніться до цього .


хороше рішення, також я думаю, що це має бути timetimeofday (& tp, NULL);
Адем

4
Перш за все, це C, а не C ++. По-друге, є проблеми з gettimeofday, див. Це, наприклад.
rustyx

17

Ця відповідь досить схожа на Oz.'s , використовуючи <chrono>для C ++ - я не схопив її з Oz. хоча ...

Я взяв оригінальний фрагмент внизу цієї сторінки і трохи змінив його, щоб він був повноцінним консольним додатком. Я люблю використовувати цю штучку. Це фантастично, якщо ви робите багато сценаріїв і вам потрібен надійний інструмент в Windows, щоб отримати епоху за фактичні мілісекунди, не вдаючись до використання VB або якогось менш сучасного, менш зручного для читача коду.

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

Я отримую від’ємне число, -560549313це не так, правда?
Noitidart

1
@Noitidart Чи можете ви сказати, яку платформу та компілятор C ++ ви використовуєте? Я використовую цю річ весь час з інструментами автоматизації, і ніколи не бачив негативного виводу o.0 Більше ніж радий перевірити це. Також це пряма копія чи змінена / інтегрована програма? Просто хочете переконатися, що він походить лише з цього коду.
kayleeFrye_onDeck

5
Ах @kayleeFrye_onDeck це тому, що я використовував int! int nowms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();. Я поклав на int64_tце, і це працює! Дуже дякую, що попросили отримати більше інформації, щоб допомогти!
Noitidart

unsigned long longє більш портативним та __int64доступний лише на MSVC.
СС Енн

__int64у стандартному C ++ немає типу. Можна використовувати std::int64_tзамість цього.
jaskmar

14

Оскільки C ++ 11 ви можете використовувати std::chrono:

  • отримати поточний системний час: std::chrono::system_clock::now()
  • отримати час з епохи: .time_since_epoch()
  • перекладіть базовий блок в мілісекунди: duration_cast<milliseconds>(d)
  • перевести std::chrono::millisecondsна ціле число ( uint64_tщоб уникнути переповнення)
#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;
}

Я пропоную використовувати unsigned long longзамість uint64_t.
csg

13

Якщо ви користуєтеся timetimeofday, вам доведеться наближати до довгого, інакше ви отримаєте переповнення і, таким чином, не реальну кількість мілісекунд з епохи: long int msint = tp.tv_sec * 1000 + tp.tv_usec / 1000; дасть вам таке число, як 767990892, яке відбудеться через 8 днів після епохи ;-).

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

-25

Включіть <ctime>і використовуйте timeфункцію.


30
Це повертає секунди з епохи. Не мілісекунд.
Прого
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.