Как получить текущую временную метку в миллисекундах с 1970 года так же, как получает Java


135

В Java мы можем использовать System.currentTimeMillis() текущую временную метку в миллисекундах с того времени, которое

разница, измеренная в миллисекундах, между текущим временем и полуночью 1 января 1970 года по Гринвичу.

В С ++ как получить то же самое?

В настоящее время я использую это, чтобы получить текущую метку времени -

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:

#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, библиотека chrono может предоставить вам более высокое разрешение (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;

передайте это .


хорошее решение, тоже думаю, должно быть gettimeofday (& tp, NULL);
Адем

4
Прежде всего, это C, а не C ++. Во- вторых, есть проблемы с gettimeofday см это , например.
rustyx

18

Ответ на этот вопрос очень похож на Оз. По , используя<chrono> для C ++ - я не взял его из страны Оз. хотя...

Я взял исходный фрагмент внизу этой страницы и немного изменил его, сделав его полноценным консольным приложением. Я люблю использовать эту маленькую штуку. Это замечательно, если вы много пишете сценарии и нуждаетесь в надежном инструменте в 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.
SS Anne,

__int64в стандартном C ++ типа нет . std::int64_tВместо этого можно использовать .
jaskmar

15

Начиная с 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

Почему unsigned long longвместо uint64_t? Я от природы предпочитаю печатать более коротким шрифтом
Джавад

13

Если вы используете gettimeofday, вам нужно использовать long long, иначе вы получите переполнение и, следовательно, не реальное количество миллисекунд с эпохи: 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функцию.


31
Это возвращает секунды с эпохи. Не миллисекунды.
Progo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.