parsing durations using %q or %Q??

cannot parse durations using %q or %Q...e.g.

1
2
3
4
5
6
7
8
		std::chrono::duration<long long, std::milli> dur{ 1200 };

		std::istringstream  sm{ "1000ms" };

		auto str = std::format("{:%Q%q}", dur);    // works perfect

		std::chrono::from_stream(sm, "%Q%q", dur);  // parse failed!!


Why?
How can I parse a duration? It is supposed to work...(Josuttis, C++ 20 The Complete Guide, pg 373)


Regards,
Juan
Last edited on
That book doesn't have any example using %Q.

However on page 373


As another example, you can parse a year_month from a sequence of characters specifying the full month
name and the year, among other things, as follows:

std::chrono::year_month m;
std::istringstream sstrm{"Monday, April 5, 2021"};
std::chrono::from_stream(sstrm, "%A, %B %d, %Y", m);
if (sstrm) {
    std::cout << "month: " << m << '\n'; // prints: month: 2021/Apr
}

The format string accepts all conversion specifiers of formatted output except %q and %Q with improved flexibility

is there a way to parse durations?

The allowed conversion specifiers are detailed at:
https://en.cppreference.com/w/cpp/chrono/duration/from_stream
Last edited on
Maybe something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <chrono>
#include <iostream>
#include <string>
#include <unordered_map>
#include <cmath>

std::chrono::milliseconds parseDuration(std::istream& is) {
	using namespace std::chrono_literals;

	static const std::unordered_map<std::string, std::chrono::milliseconds> suffix {
		{"ms", 1ms}, {"s", 1s}, {"m", 1min}, {"h", 1h}};

		unsigned n {};
		std::string unit;

		if (is >> n >> unit) {
			try {
				return std::chrono::duration_cast<std::chrono::milliseconds>(n * suffix.at(unit));
			} catch (const std::out_of_range&) {
				std::cerr << "ERROR: Invalid unit specified\n";
			}
		} else
			std::cerr << "ERROR: Could not convert to numeric value\n";

	return {};
}

int main() {
	std::istringstream sm { "1234ms" };

	const auto dur { parseDuration(sm) };

	std::cout << dur << '\n';

}



1234ms

Last edited on
Topic archived. No new replies allowed.