C++ Logo

std-proposals

Advanced search

Re: chrono system_clock to_time_t/from_time_t unexpected integer overflow

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Thu, 7 Oct 2021 13:39:31 -0400
On Thu, Oct 7, 2021 at 1:32 PM Edward Catmur via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> 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.

`time_point` for a clock is already not restricted to "time points
outside its own range". There are even type aliases specifically for
creating `time_point<system_clock>` of different duration: `sys_days`
and `sys_seconds`.

There is absolutely nothing problematic about having a time point with
a different duration from the clock's natural duration.

Received on 2021-10-07 12:39:44