Как узнать количество наносекунд, прошедших с 01 января 1970 года, 00:00:00 (UTC)? - PullRequest
0 голосов
/ 03 мая 2019

Я пытаюсь понять, как найти число наносекунд, прошедшее с 01 января 1970 года, 00:00:00.

Я не нахожу в Интернете ни одного примера того, как это сделать (или объяснить, как это можно рассчитать без ссылки на код) Я работаю на C ++ 11 на Windows.

Ответы [ 3 ]

3 голосов
/ 03 мая 2019

Вы можете преобразовать time_point в duration с помощью метода time_since_epoch(), который даст количество единиц времени с начала эпохи, которая наступает 1 января 1970 года.

Затем вынужно только привести продолжительность в наносекунды.Я смог сделать это с помощью относительно простого кода:

#include<iostream>
#include<chrono>

int main() {
    //Use system_clock, not steady_clock, or you will not get correct values!
    auto now = std::chrono::system_clock::now().time_since_epoch();
    auto now_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(now);
    //Also valid, but doesn't convey programmer intent:
    //std::chrono::nanoseconds now_ns = now;
    std::cout << now_ns.count() << "ns" << std::endl;
}

На тестируемом компьютере я получаю следующий вывод:

1556833575688789496ns

Обратите внимание на две потенциальные проблемы:

  • system_clock не обладает особо высокой точностью.Таким образом, вы, скорее всего, не сможете получить результаты, которые более точны, чем несколько миллисекунд.
  • system_clock гарантированно установит для своей эпохи 1 января, если вы компилируете с C ++ 20,В предыдущих версиях это было , обычно реализуемое как таковое, но некоторые соответствующие компиляторы C ++ могут не использовать эту эпоху, и вам необходимо проверить как таковую.
1 голос
/ 03 мая 2019

Вот специфичный для Windows простой математический подход, о котором я упоминал в своих предыдущих комментариях:

#include <windows.h>
#include <iostream>

int main() {
  FILETIME now;
  FILETIME epoch_ft;
  SYSTEMTIME epoch_st = { 1970, 1, 4, 1, 0, 0, 0, 0 }; 
  GetSystemTimeAsFileTime(&now);
  SystemTimeToFileTime(&epoch_st, &epoch_ft);

  ULARGE_INTEGER nsecs, epoch_nsecs;
  nsecs.LowPart = now.dwLowDateTime;
  nsecs.HighPart = now.dwHighDateTime;
  epoch_nsecs.LowPart = epoch_ft.dwLowDateTime;
  epoch_nsecs.HighPart = epoch_ft.dwHighDateTime;
  nsecs.QuadPart -= epoch_nsecs.QuadPart;

  std::cout << "100-nsec periods since epoch: " << nsecs.QuadPart << '\n';
  return 0;
}

Вышеуказанное получает текущее системное время как время файла и время файла эпохи, и вычитает их, чтобы получить число интервалов в 100 наносекунд с начала эпохи.

Windows FILETIME - это число интервалов в 100 наносекунд с 1 января 1601 . У него нет фактического разрешения наносекунды, и я думаю разрешение, используемое GetSystemTimeAsFileTime(), равно миллисекунде, как GetSystemTime(), но это, вероятно, такой же точный подход, как вы собираетесь получить. Если вы используете Windows 8, Server 2012 или выше, существует также GetSystemTimePreciseAsFileTime () , который можно использовать вместо этого для получения максимальной поддерживаемой точности.

1 голос
/ 03 мая 2019

Вы можете использовать std::chrono::system_clock - см. https://en.cppreference.com/w/cpp/chrono/system_clock. До C ++ 20 фактически не указывалось, были ли запущены эти часы (иначе, «эпоха») в 1970 году или в другое время, но C ++ 20 гарантирует, что это действительно эпоха, и вам следует проверить, уже ли установлен компилятор Windows. соответствует этому требованию (я предполагаю, что это так, но у меня нет Windows для подтверждения).

Чтобы получить количество наносекунд, вы можете использовать std::chrono::duration_cast - https://en.cppreference.com/w/cpp/chrono/duration/duration_cast - для установки часов в std :: chrono :: наносекунды, а затем использовать .time_since_epoch().count() для получения фактического количества наносекунд , Тем не менее, нет никакой гарантии, каким будет это разрешение ... Вероятно, вы не сможете измерить единичные наносекунды с этим - разрешение может составлять всего лишь микросекунды, миллисекунды или что угодно, даже если указано в наносекундах. Вам нужно будет проверить.

...