Вариант 1
Простое приведение не будет знать, что ему нужно сместить масштабирование числа с наноса до секунд (а секунды - это почти всегда приращение, используемое time_t
). Для компилятора это просто одно целое число, назначаемое другому целому числу, может быть, даже того же типа. если у вас есть время в наносекундах и вы хотите использовать time_t
, вам, вероятно, потребуется разделить на 1 000 000 000, чтобы преобразовать вашу печать в секунды.
#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <ctime>
constexpr long long int nanos_to_seconds = 1000000000; // conversion factor
constexpr long long int nanos_to_milis = 1000000;
int main()
{
time_t now = time(NULL);
long long int ts = 1561402947698860015;
time_t t = static_cast<time_t>(ts/nanos_to_seconds);
//^ change here
long long int milis = ts % nanos_to_seconds / nanos_to_millis; // compute milliseconds
std::cout << std::asctime(std::localtime(&t))
<< t << "." << std::setfill('0') << std::setw(3) << millis
<< " seconds since the Epoch\n";
std::cout<<"done"<<std::endl;
return 0;
}
Вариант 2
Начиная с C ++ 11, C ++ имеет встроенную поддержку наносекундных временных меток в библиотеке <chrono>
. Объедините это с библиотекой дат Говарда Хиннанта , и все ваши проблемы с форматированием будут решены вместе с подготовкой вашего кода для C ++ 20. Это стоит посмотреть. Это не решает вашу текущую проблему прямо из коробки, но может использоваться, чтобы заменить проблему так, чтобы это было менее раздражающим в будущем.
Примечание:
В наши дни time_t
обычно составляет 64-битное число секунд. 32-битный счетчик будет запущен через 20 лет или около того, поэтому вместо того, чтобы мириться с ошибкой Y2038 в последнюю минуту, переход на гораздо большее число был начат несколько десятилетий назад.