ctime(time_point::min()) throws exception

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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?

Thanks.
the example can be found online here: http://cppstdlib.com/code/util/chrono1.cpp.html

and it seems to run fine here: http://coliru.stacked-crooked.com/a/cad1bbe6ba9fe1d8 ...
... and here: http://cpp.sh/87nhz

have you tried running the program on another compiler and what compiler commands are you using?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <chrono>
#include <ctime>
#include <string>
#include <iostream>

std::string asString (const std::chrono::system_clock::time_point& tp)
{
    // convert to system time:
    const std::time_t t = std::chrono::system_clock::to_time_t(tp);
    std::string ts = std::ctime( std::addressof(t) ) ;    // convert to calendar time
    ts.pop_back() ;  // skip trailing newline
    return ts;
}

int main()
{
    // print the epoch of this system clock:
    std::chrono::system_clock::time_point tp;
    std::cout << "epoch: " << asString(tp) << '\n';

    // print current time:
    tp = std::chrono::system_clock::now();
    std::cout << "now:   " << asString(tp) << '\n';

    // print minimum time of this system clock:
    tp = std::chrono::system_clock::time_point::min();

    if( tp >= std::chrono::system_clock::time_point{} ) // sanity check
        std::cout << "min:   " << asString(tp) << '\n';
    else
        std::cout << "min: min time_point is is before epoch\n" ;

    // print maximum time of this system clock:
    tp = std::chrono::system_clock::time_point::max();
    std::cout << "max:   " << asString(tp) << '\n';
}

http://coliru.stacked-crooked.com/a/0f6ac7240c553d99
>> have you tried running the program on another compiler and what compiler commands are you using?

I'm using C::B's default commands.
OP: I can see under the 'General' tab that you've replied to my post beginning with quoting the following sentence:
have you tried running the program on another compiler and what compiler commands are you using?
but when I navigate to this thread I can't actually see the message from you. Quite bizarre! Anyways, if a reply is expected please re-post. thanks

edit: OK I can see your above post now, nothing further to add
Last edited on
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.

Thanks.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#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);

    const auto 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< long long, std::ratio<(3*365+366)*24LL*60*60/4> > ;
    const auto 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

http://coliru.stacked-crooked.com/a/a545ff065aa1e2d2


msvcrt (microsoft):
min:   about 29227 years before epoch
max:   about 29227 years after epoch

http://rextester.com/DWAG32619


libstdc++ (GNU, MinGW 64)
min:   about 292 years before epoch
max:   Saturday, April 12 05:17:16 2262
Topic archived. No new replies allowed.