I need convert a dd-mmm-year
string to epoch days to do some simple math. Specifically, calculate the number of days from now()
to the date of the string.
I'm looking at <chrono>
and <ctime>
but am not seeing an obvious way to do that? How do you convert dd-mmm-year
and now()
to epoch days?
This can easily be done with this free, open-source, header-only preview of C++20 , which works with C++11/14/17:
#include "date/date.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
string s1 = "25-Mar-2021";
string s2 = "20-Jul-2021";
istringstream in{s1};
in.exceptions(ios::failbit);
sys_days t1;
in >> parse("%d-%b-%Y", t1);
in.str(s2);
in.clear();
sys_days t2;
in >> parse("%d-%b-%Y", t2);
cout << t2 - t1 << '\n';
}
sys_days
is a type alias for std::chrono::time_point<system_clock, duration<int, ratio<86400>>>
. But you can think of it as a count of days since since 1970-01-01.
The program above outputs:
117d
The type of the expression t2 - t1
is std::chrono::duration<int, ratio<86400>>
.
Here is a live example you can experiment with.
You can convert durations (such as t2 - t1
) to a signed integral type by using the .count()
member function:
auto i = (t2 - t1).count(); // 117
Another way to do it is to divide by days{1}
:
auto i = (t2 - t1)/days{1}; // 117
This latter technique gives those who know dimensional analysis a warm fuzzy feeling. :-)
You can convert std::chrono::system_clock::now()
to type sys_days
like this:
auto t2 = floor<days>(system_clock::now());
This gives the current date according to UTC. If you need the current date according to some other time zone (such as the computer's local time zone setting), then that involves an additional library (at the same link) which is not header-only and involves some installation. In that case one would work in terms of local_days
instead of sys_days
:
#include "date/tz.h"
#include <iostream>
#include <sstream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
string s1 = "25-Mar-2021";
istringstream in{s1};
in.exceptions(ios::failbit);
local_days t1;
in >> parse("%d-%b-%Y", t1);
auto t2 = floor<days>(current_zone()->to_local(system_clock::now()));
cout << t2 - t1 << '\n';
}
Output (currently):
1d