date
date copied to clipboard
Does the library support to convert a std::string to epoch without using std::istringstream
https://stackoverflow.com/questions/4137748/c-converting-a-time-string-to-seconds-from-the-epoch
#include "tz.h"
#include <iostream>
#include <sstream>
int
main()
{
std::istringstream is("2010-11-04T23:23:01Z");
is.exceptions(std::ios::failbit);
date::sys_seconds tp;
date::parse(is, "%FT%TZ", tp);
std::cout << "seconds from epoch is " << tp.time_since_epoch().count() << "s\n";
}
Question> Does the library offer an interface where I can use std::string
directly without passing it through a std::istringstream
Thank you
No, not directly. However there are lots of existing ways to parse int
. Here is an example of using C++17's from_chars
to parse the int
s from a string
and then turn the int
s into a sys_seconds
:
#include "date/date.h"
#include <charconv>
#include <iostream>
#include <string>
#include <system_error>
int
main()
{
std::string is("2010-11-04T23:23:01Z");
// 01234567890123456789
int y, m, d, h, M, s;
auto r = std::from_chars(&is[0], &is[4], y);
if (static_cast<bool>(r.ec))
throw std::runtime_error("error parsing year");
if (*r.ptr++ != '-')
throw std::runtime_error("error parsing first '-'");
r = std::from_chars(r.ptr, &is[7], m);
if (static_cast<bool>(r.ec))
throw std::runtime_error("error parsing month");
if (*r.ptr++ != '-')
throw std::runtime_error("error parsing second '-'");
r = std::from_chars(r.ptr, &is[10], d);
if (static_cast<bool>(r.ec))
throw std::runtime_error("error parsing day");
if (*r.ptr++ != 'T')
throw std::runtime_error("error parsing 'T'");
r = std::from_chars(r.ptr, &is[13], h);
if (static_cast<bool>(r.ec))
throw std::runtime_error("error parsing hour");
if (*r.ptr++ != ':')
throw std::runtime_error("error parsing first ':'");
r = std::from_chars(r.ptr, &is[16], M);
if (static_cast<bool>(r.ec))
throw std::runtime_error("error parsing minute");
if (*r.ptr++ != ':')
throw std::runtime_error("error parsing second ':'");
r = std::from_chars(r.ptr, &is[19], s);
if (static_cast<bool>(r.ec))
throw std::runtime_error("error parsing second");
if (*r.ptr++ != 'Z')
throw std::runtime_error("error parsing 'Z'");
auto tp = date::sys_days{date::year{y}/m/d} + std::chrono::hours{h} +
std::chrono::minutes{M} + std::chrono::seconds{s};
std::cout << "seconds from epoch is " << tp.time_since_epoch().count() << "s\n";
}
The output is:
seconds from epoch is 1288912981s
https://howardhinnant.github.io/date/date.html#to_stream_formatting
%z The offset from UTC in the ISO 8601 format. For example -0430 refers to 4 hours 30 minutes behind UTC. If the offset is zero, +0000 is used. The modified commands %Ez and %Oz insert a : between the hours and minutes: -04:30. If the offset information is not available, failbit will be set.
This is how I currently use the function to convert time string to epoch seconds.
std::chrono::system_clock::time_point tp;
std::istringstream is("2022-04-10T03:10:02.551112+00:00");
is >> date::parse("%FT%T%Oz", tp);
auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(
tp.time_since_epoch())
.count();
Question> Is there a difference between %Ez and %Oz? I tested the output and didn't see any difference.
Thank you again for this awesome date library!
There is no difference between %Ez
and %Oz
.
Thanks for the feedback!