Nicolai Josuttis has given an example in his book "The C++ Standard Library", to print 4 special timepoints of a clock, as calendar time (pgs 152-153):
1) a clock's epoch
2) current time
3) a clock's minimum time_point
4) a clock's maximum time_point
string asString (const system_clock::time_point& tp)
{
// convert to system time:
time_t t = system_clock::to_time_t(tp);
string ts = std::ctime(&t); // convert to calendar time
ts.resize(ts.size()-1); // skip trailing newline
return ts;
}
int main()
{
// print the epoch of this system clock:
system_clock::time_point tp;
cout << "epoch: " << asString(tp) << endl;
// print current time:
tp = system_clock::now();
cout << "now: " << asString(tp) << endl;
// print minimum time of this system clock:
tp = system_clock::time_point::min();
cout << "min: " << asString(tp) << endl;
// print maximum time of this system clock:
tp = system_clock::time_point::max();
cout << "max: " << asString(tp) << endl;
}
This code works perfectly for the epoch, current time and maximum time_point. However, it throws an exception for a clock's minimum time_point. This exception is thrown in the asString() function, when the ctime() function is invoked:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
What is the reason for this problem and how can it be solved?
Sorry, That wasn't the full post. My system crashed while posting and then I wasn't able to log on later to the forum, as it kept displaying a "database error".
Here's what I wanted to say:
gunner is right.
This problem is localized to the version of g++ I am using which is somewhat old.
I've tried the code on an online compiler (codingground) and it runs perfectly there.
#include <chrono>
#include <ctime>
#include <string>
#include <iostream>
std::string as_string( const std::chrono::system_clock::time_point& tp )
{
const std::time_t t = std::chrono::system_clock::to_time_t(tp);
constauto ptm = std::localtime( std::addressof(t) ) ;
if(ptm) // if the c library supports this value for time_t
{
char buffer[1024] {} ;
if( std::strftime( buffer, sizeof(buffer), "%A, %B %d %H:%M:%S %Y", ptm ) )
return buffer ;
}
// this time point is outside the range of what the C library can handle gracefully
using years = std::chrono::duration< longlong, std::ratio<(3*365+366)*24LL*60*60/4> > ;
constauto nyears = std::chrono::duration_cast<years>( tp.time_since_epoch() ).count() ;
return nyears < 0 ? "about " + std::to_string(-nyears) + " years before epoch" :
"about " + std::to_string(nyears) + " years after epoch" ;
}
int main()
{
using time_point_t = std::chrono::system_clock::time_point ;
// print the epoch of this system clock:
std::cout << "epoch: " << as_string( time_point_t{} ) << '\n';
// print current time:
std::cout << "now: " << as_string( std::chrono::system_clock::now() ) << '\n';
// print minimum time of this system clock:
std::cout << "min: " << as_string( time_point_t::min() ) << '\n';
// print maximum time of this system clock:
std::cout << "max: " << as_string( time_point_t::max() ) << '\n';
}
libc++ (LLVM)
min: Sunday, December 21 19:59:06 -290308
max: Sunday, January 10 04:00:54 294247
libstdc++ (GNU, Linux)
min: Tuesday, September 21 00:12:44 1677
max: Friday, April 11 23:47:16 2262