Closed tomaszkam closed 5 years ago
#include "date/date.h"
#include <iostream>
#include <sstream>
#include <string>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
{
// Case 1
// Parse %j as day-of-year combined with a year into a time_point
istringstream in{"2019 222"};
system_clock::time_point tp;
in >> parse("%Y %j", tp);
cout << tp << '\n';
}
{
// Case 2
// Parse %j as number of days into a duration
istringstream in{"222"};
system_clock::duration d;
in >> parse("%j", d);
cout << d << '\n';
}
}
Output:
2019-08-10 00:00:00.000000
19180800000000µs
Case 1 is what is in the spec now. And this issue is asking if we should add Case 2. It is implemented: https://github.com/HowardHinnant/date/blob/master/include/date/date.h#L7596-L7600 https://github.com/HowardHinnant/date/blob/master/include/date/date.h#L7486-L7498
And it was implemented because of a customer asking for the Case 2 functionality.
First stab at wording:
Table 88 — Meaning of parse flags
%j
If a year is successfully parsed, this represents tThe day of that the year as a decimal number. Jan 1 is 1. Otherwise this represents a duration specified as a number of days. The modified command %N j specifies the maximum number of characters to read. If N is not specified, the default is 3. Leading zeroes are permitted but not required.
The question I have is if this should be an LWG issue or an extension. If LWG issues, then what would be the motivation to address it, like POSIX consistency or unclear wording?
Good question. I don't think it is crystal clear. This program:
#include <iostream>
#include <time.h>
int
main()
{
tm t{};
auto r = strptime("222", "%j", &t);
if (r)
std::cout << r << '\n';
else
std::cout << "null\n";
std::cout << t.tm_yday << '\n';
}
Successfully parses into tm_yday
the value 221, which is correct (yes, even with the off-by-one). tm_yday
is the number of days since Jan 1. Whether the client interprets that as a duration or a partial time point is unknown.
Mailed to LWG chair.
Original comment: