tomaszkam / date

A date and time library based on the C++11/14/17 <chrono> header
Other
0 stars 0 forks source link

[LWG73270] Should %j parse for duration? #27

Closed tomaszkam closed 5 years ago

tomaszkam commented 5 years ago

Original comment:

Should %j parse for duration? Yes. If year data is not parsed, %j is interpreted as a duration of days. If formatting %j interprets day of year (Jan 1 == 1) for time_points and days for durations

HowardHinnant commented 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.

tomaszkam commented 5 years ago

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?

HowardHinnant commented 5 years ago

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.

HowardHinnant commented 5 years ago

Mailed to LWG chair.