How to locale-free convert std::chrono::time_point to/from std::string of a predefined date-time format YYYY-mm-dd HH:MM:SS.zzzzzzzzz?
For me it turned out that the only way is to use std::get_time and std::put_time with std::itringstream and std::ostringstream, but:
std::tm and time_t (bearable)std::locale dependent (crucial).Any other alternatives?
Third party libraries can also be considered. I looked at boost::posix_time::ptime but seams it is also locale-dependent, plus it is slower and less generic than std::chrono::time_point.
Don't know if it is fast enough for you, but:
#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
std::cout << std::chrono::system_clock::now() << '\n';
}
Just output for me:
2017-03-02 17:04:26.813110
This is a library I've written. It is free, open-source, and the "date.h" part is header-only. There is full documentation, and even video tutorials, all linked off of the GitHub page.
There are fairly extensive formatting and parsing options, as well as many other features which make it safe and easy to do time and calendrical computations.
Additionally, if this formatting isn't fast enough for you, the library is flexibly layered so that you could interact with it at a lower-level and easily write your own I/O. For example here is how you can get all of the field types as int from a system_clock::time_point to microseconds precision:
#include "date.h"
int
main()
{
using namespace date;
using namespace std::chrono;
auto t = system_clock::now();
// Convert system_clock::time_point to days-precision time_point
auto sd = floor<days>(t);
// Create time_of_day
auto tod = make_time(t - sd);
// Create year_month_day
year_month_day ymd = sd;
// Extract field types as int
int y = int{ymd.year()}; // Note 1
int m = unsigned{ymd.month()};
int d = unsigned{ymd.day()};
int h = tod.hours().count();
int M = tod.minutes().count();
int s = tod.seconds().count();
int us = duration_cast<microseconds>(tod.subseconds()).count();
}
Now you can format these ints however you want.
Note 1: Prior to gcc-6.1 there's a compiler bug concerning {} here. Use () instead to workaround the compiler bug.
Going the reverse direction (from ints to system_clock::time_point) is even easier:
#include "date.h"
int
main()
{
using namespace date;
using namespace std::chrono;
int y = 2017;
int m = 3;
int d = 2;
int h = 15;
int M = 33;
int s = 55;
int us = 123456;
// Convert field values to system_clock::time_point
system_clock::time_point t = sys_days(year{y}/m/d) + hours{h} + minutes{M} +
seconds{s} + microseconds{us};
}
Parse your ints however you want and then you can form a system_clock::time_point in a single statement.
The library has an active user community which helps maintain it on several platforms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With