Reputation: 451
I have an long long integer that represents an epoch timestamp with nanosecond precision, I would like to convert it into human readable timestamp such as date-hh:mm:ss
I tried to use static cast and directly cast this integer to time_t format, and is intended to use localtime to format it, but does not success.
From documentation it appears that time_ts is a 32 bit integer, which means is not large enough to read my timestamp. What's best way to format my timestamp to human readable format ?
#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <ctime>
int main()
{
time_t now = time(NULL);
long long int ts = 1561402947698860015;
time_t t = static_cast<time_t>(ts);
std::cout << std::asctime(std::localtime(&t))
<< t << " seconds since the Epoch\n";
std::cout<<"done"<<std::endl;
return 0;
}
Upvotes: 0
Views: 5801
Reputation: 33932
A simple cast won't know it needs to shift the number's scaling from nanos to seconds (as seconds are what's almost always the increment used by time_t
). To the compiler it's just one integer being assigned to another integer, maybe even the same type. if you have a time in nanoseconds and you want to use time_t
you'll probably need to divide by 1,000,000,000 to convert your stamp into seconds.
#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;
}
As of C++11, C++ has built in support for nanosecond timestamps in the <chrono>
library. Combine this with Howard Hinnant's date library and all of your formatting concerns are taken care of along with getting your code ready for C++20. This is worth looking into. It does not solve your current problem right out of the box, but can be used to replace the problem so that it is less annoying in the future.
These days time_t
is usually a 64 bit count of seconds. The 32 bit counter is going to roll in another 20 years or so, so rather than have to put up with a Y2038 bug at the last minute, a move to a much larger number was started a few decades ago.
Upvotes: 1
Reputation: 666
Your code will work if you divide to convert into seconds (as commented by user4581301):
long long int ts = 1561402947698860015 / 1000000000;
But also, instead of using:
std::asctime(std::localtime(&t))
you can just use the following to get the same result:
ctime(&t)
Upvotes: 1