Search code examples
c++c++14c++-chrono

Creating a `std::chrono::time_point` from a calendar date known at compile time


This answer shows how to parse a string to a std::chrono::time_point, as follows:

std::tm tm = {};
std::stringstream ss("Jan 9 2014 12:35:34");
ss >> std::get_time(&tm, "%b %d %Y %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));

If I want to create a std::chrono::time_point from a (Gregorian) calendar date whose year, month, and day-of-month are known at compile time, is there any simpler way than parsing it from a string as suggested above?


Solution

  • Yes, you can do the entire computation at compile time, creating a constexpr system_clock::time_point using Howard Hinnant's date/time library.

    #include "date/date.h"
    #include <chrono>
    
    int
    main()
    {
        using namespace date;
        using namespace std::chrono;
        constexpr system_clock::time_point tp = sys_days{January/9/2014} + 12h + 35min + 34s;
        static_assert(tp == system_clock::time_point{1389270934s}, "");
    }
    

    This is assuming that the date/time is UTC. If it isn't, you will have to manually add/subtract the UTC offset to make it so. As time zone rules are changed at the whim of politicians all the time, there is little hope in making them constexpr. Even historical time zone rules are updated when misunderstandings come to light.

    Also this program will port to C++20 by dropping #include "date/date.h" and using namespace date;. Also using Howard Hinnant's date/time library requires C++14 constexpr muscle. C++11 constexpr is not sufficient (but you can do it at run-time, dropping the constexpr and static_assert).