Home > Enterprise >  Parse time-of-day using C 20's chrono facilities / HH's date library
Parse time-of-day using C 20's chrono facilities / HH's date library

Time:01-10

I am trying to parse a time-of-day string in the form of "HH:MM", and receive back the nanoseconds since midnight.

So long as I provide a date and a time I can successfully parse it, eg:

(I am using Howard Hinnant's date library in lieu of C 20's chrono, as my std library (gcc 11.2) doesn't support this yet)

#include <iostream>
#include <chrono>
#include <date/date.h>

int main()
{
    std::string str = "1970-01-01 08:00";
    std::string format = "%Y-%m-%d %H:%M";
    std::istringstream ss(str);

    std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> t;
    ss >> date::parse(format, t);

    if (ss.fail()) [[unlikely]]
        std::cerr << "parse failed\n";

    std::cout << "ns=" << t.time_since_epoch().count() << '\n';

    return 0;
}

I see that chrono has a "time of day" class, hh_mm_ss, but I don't see any associated parsing functionality.

Is it possible to parse a time-of-day string using a format, eg, "%H:%M"?

CodePudding user response:

The way to do this is to parse a duration such as nanoseconds and interpret that as "time duration since midnight":

#include <iostream>
#include <chrono>
#include <date/date.h>

int main()
{
    std::string str = "08:00";
    std::string format = "%H:%M";
    std::istringstream ss(str);

    std::chrono::nanoseconds t;
    ss >> date::parse(format, t);

    if (ss.fail()) [[unlikely]]
        std::cerr << "parse failed\n";

    using date::operator<<;
    std::cout << "time of day = " << t << '\n';
}

This involves:

  • Truncate your string inputs to the desired information.
  • Change the type of t to nanoseconds.

I used the streaming operator for nanoseconds and changed the formatting so that the output is:

time of day = 28800000000000ns

If you would rather get your original output without the ns suffix, then you can print out t.count(), and in that case there is no need for the using date::operator<<;.


If you want to get really fancy you can create your own custom chrono::time_point that has the semantics of "time of day". That's usually overkill. But if you would like to head that direction, here's some thoughts on it: https://stackoverflow.com/a/56727183/576911.

  • Related