Reputation: 378
Sample string:
2018-10-31T14:45:21.778952-07:00
I would like to convert it to int64_t representing milliseconds (or even microseconds) since epoch. The timezone can vary. The code will be executing on a linux box, but I only have access to std and folly (cannot use any arbitrary 3P libraries).
I searched for this and found a few different ways that do not work for me:
Is there some easy way to do this?
Upvotes: 2
Views: 1741
Reputation: 218860
From the comments above:
I am looking into using Howard's library. However, that it makes a web call gives me pause. I assume that if the call fails it will just use the locally stored timezone name data? We won't be dealing with timezone names, so I don't care about those. However, making a network call might be an issue.
Howard's library is layered:
A foundational layer that does not need the IANA time zone database and thus never makes networking calls. This is a single header, header-only library.
A time zone layer that is aware of the IANA time zone database. This layer can be configured to make network calls or not (depending on build flags), or even use your OS's time zone database (except on Windows).
Your application does not require the time zone layer as it only deals with UTC offsets, and not time zone names or rules.
Here is a function that converts a std::string
with your sample format into a std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>
. That type is a big verbose mouthful for a system_clock::time_point
except guaranteed to have microseconds
precision. The foundational layer has a type alias for this type called date::sys_time<std::chrono::microseconds>
.
#include "date/date.h"
#include <chrono>
#include <iostream>
#include <sstream>
auto
to_sys_time(std::string s)
{
using namespace date;
using namespace std;
using namespace std::chrono;
istringstream in{move(s)};
in.exceptions(ios::failbit);
sys_time<microseconds> tp;
in >> parse("%FT%T%z", tp);
return tp;
}
string
into a istringstream
.istringstream
to throw an exception if it fails to parse something (you may choose to handle errors differently).time_point
with the desired precision.You can exercise this function like so:
int
main()
{
auto tp = to_sys_time("2018-10-31T14:45:21.778952-07:00");
using date::operator<<;
std::cout << tp << " UTC\n";
std::cout << tp.time_since_epoch() << '\n';
}
to_sys_time
with the desired input string.namespace date
available.time_point
(this is a UTC time_point
).duration
of the time_point
.The output of this program is:
2018-10-31 21:45:21.778952 UTC
1541022321778952µs
This program will port to C++20 by removing #include "date/date.h"
, using namespace date;
and using date::operator<<;
.
Upvotes: 4