C++ Logo

std-proposals

Advanced search

Re: chrono system_clock to_time_t/from_time_t unexpected integer overflow

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Thu, 7 Oct 2021 18:32:02 +0100
On Thu, 7 Oct 2021 at 13:05, Igor Ingultsov via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Consider the code:
>
> // time_t for year 2500
> time_t t = 16756675140; // which is ok on many systems as time_t is
> usually now 64bit
> auto tp = std::chrono::system_clock::from_time_t(t);
> std::cout << std::chrono::system_clock::to_time_t(tp);
>
> I would naively expect identity
> t == to_time_t(from_time_t(t));
>
> but what happens in reality is, time_t as seconds is being put into the
> time_point with resolution (on Linux/libstdc++) of nanoseconds, which has
> an upper limit of around Year 2262.
>
> Is there any reason, why there would be an implicit conversion from time_t
> to time_point with nanoseconds duration?
>
> As far as I know, time_t is everywhere the amount of seconds since epoch
> (and in C++20 anyway since 1970).
>

No, you're confusing time_t with chrono::sys_time. chrono::system_clock is
required to use the Unix epoch (since C++20), but time_t isn't (though it
usually does).

The solution could be:
> *std::system_clock::from_time_t* should return *time_point* of the *same
> resolution as time_t* in current implementation.
>

That would break the contract that chrono::system_clock::from_time_t
returns chrono::system_clock::time_point. There is no guarantee that time_t
and chrono::system_clock::time_point have the same representation or epoch,
so your code should allow for the possibility of overflow when converting,
just as it allows for loss of precision.

Problem ist however, there would be no guard against:
> time_point<seconds> ts = from_time_t(t);
> time_point<nanoseconds> tns = ts; // ok from perspective of
> time_point/duration cast, as we don't loose precision, but we could still
> silently loose resolution.
>
> Do you have any ideas how this could be changed?
>

It might be possible to overload to_time_t and from_time_t with function
templates (on class Duration) accepting or returning
chrono::time_point<chrono::system_clock, Duration>. However, this would
pose a problem since chrono::system_clock would then have member functions
returning or accepting time points outside the range of the clock; it isn't
reasonable to expect a clock to handle time points outside its own range.

Received on 2021-10-07 12:32:15