Using this free, open source C++11/14 library, here is another way to deal with parsing fractional seconds:
#include "tz.h"
#include <iostream>
#include <sstream>
int main()
{
using namespace date;
using namespace std::chrono;
std::istringstream str("20:48:01.469 UTC MAR 31 2016");
sys_time<milliseconds> tp;
parse(str, "%T %Z %b %d %Y", tp);
std::cout << tp << '
';
}
Output:
2016-03-31 20:48:01.469
I.e., with this tool %S
and %T
just work. The precision is controlled not with flags, but with the precision of the std::chrono::time_point
.
If you want to find out what timezone abbreviation you parsed, that is also possible:
std::istringstream str("20:48:01.469 UTC MAR 31 2016");
sys_time<milliseconds> tp;
std::string abbrev;
parse(str, "%T %Z %b %d %Y", tp, abbrev);
std::cout << tp << ' ' << abbrev << '
';
Output:
2016-03-31 20:48:01.469 UTC
This being said, this library is built on top of std::get_time
and thus has the same portability problem that Jonathan's excellent (and upvoted) answer alludes to: Only libc++ currently parses month names in a case-insensitive manner. Hopefully that will change in the not-too-distant future.
libstdc++ bug report.
VSO#232129 bug report.
If you have to deal with timezones other than UTC, in general, there is no sure-fire method to do that, because at any one time, more than one timezone can be using the same abbreviation. So the UTC offset can be ambiguous. However here is a short article on how to use this library to narrow down an abbreviation to a list of candidate timezones from which you might have some ad hoc logic for choosing a unique timezone.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…