user422005
user422005

Reputation: 2031

std::chrono::system_clock and C time

I am using the following time point definition universally in my project:

using time_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long, std::ratio<1,1000>>>

With this definition I get a reasonable tradeoff between precision and range, unfortunately the default with nanosecond resolution gives me a too short range.

Unfortunately it seems I can not use the chrono::system_clock::from_time_t() and chrono::system_clock::to_time_t functions to convert between std::time_t and the time point with non default resolution. Is there a way I can use the to_time_t and from_time_t functions with "my" time_point class?

Upvotes: 1

Views: 2109

Answers (1)

Alan Birtles
Alan Birtles

Reputation: 36379

If you assume that std::chrono::system_clock has the same epoch as time_t (it usually does) then to_time_t and from_time_t are essentially just a std::duration_cast.

For example this code should print the same values twice (note that whether to_time_t rounds or truncates is unspecified and duration_cast always truncates so there might be a 1 second difference):

const auto now = std::chrono::system_clock::now();
time_t time = std::chrono::system_clock::to_time_t(now);
std::cout << time << "\n";
std::cout << std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count() << "\n";
std::cout << std::chrono::system_clock::from_time_t(time).time_since_epoch().count() << "\n";
std::cout << std::chrono::system_clock::time_point(std::chrono::seconds(time)).time_since_epoch().count() << "\n";

You can therefore write your own to/from_time_t functions fairly easily:

constexpr time_point  my_point_from_time_t(time_t value)
{
    return time_point(std::chrono::seconds(value));
}

constexpr time_t my_point_to_time_t(const time_point & value)
{
    return std::chrono::duration_cast<std::chrono::seconds>(value.time_since_epoch()).count();
}

If system_clock doesn't use the same epoch as time_t then you can simply adjust the values:

const time_t system_clock_epoch = std::chrono::system_clock::to_time_t({});

time_point  my_point_from_time_t(time_t value)
{
    return time_point(std::chrono::seconds(value - system_clock_epoch));
}

time_t my_point_to_time_t(const time_point & value)
{
    return std::chrono::duration_cast<std::chrono::seconds>(value.time_since_epoch()).count() + system_clock_epoch;
}

Upvotes: 1

Related Questions