HowardHinnant / date

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

Can the library parse durations in ISO8601 format? #666

Open anthonylouisbsb opened 3 years ago

anthonylouisbsb commented 3 years ago

The date library can parse durations in ISO8601 format in a similar way that already exists for dates?

Example: The user sents an input string in a P[n]Y[n]M[n]DT[n]H[n]M[n]S or P[n]W format and the library extracts the quantity of each value in period(the number of passed days, the number of passed years..), in a similar way of the java Joda Time library already does.

I checked in the wiki that is possible to create some structures related to periods, but I have to parse the input string with the period in ISO8601 format using regex.

anthonylouisbsb commented 3 years ago

I found an answer in StackOverflow that tells that this library does not parse periods,

HowardHinnant commented 3 years ago

That answer is correct. You'll have to use some other tool (such as regex) for a parse in this format. But once you get the information into arithmetic types, then you can use this library to build the duration from the arithmetic types.

ecorm commented 3 years ago

The C++ standard library does not have all the data structures necessary to store the information parsed from an ISO 8601 period. std::chrono::year_month_day and std::chrono::hh_mm_ss would not be suitable to store arbitrary years, months, days, hours, minutes, and seconds. It would need something like a Luxon Duration that can differentiate between what they call "calendar math" and "time math". std::tm would not be able to store non-integral values.

Another example is how Java has both Duration and Period that parse ISO 8601 periods differently.

I think it would be possible for this library (or a future std::chrono library) to parse a subset of ISO 8601 periods in the same way as Java's Period, limited to days, hours, minutes, and seconds into a std::chrono::duration without ambiguity. I don't know why Javs's Period can't parse from weeks; I don't see the ambiguity. EDIT: It's because of ISO 8601 itself.

HowardHinnant commented 3 years ago

Once parsed, this library can do both calendrical math and chronological math (time math as they call it). But yes, the parsing is pretty much limited to strptime parsing (with a few extensions).

ecorm commented 3 years ago

@HowardHinnant Do you have any idea why Java's Duration.parse does not accept ISO 8601 weeks? Sorry, there's no direct link to the method's documentation, but you can CTRL+F "parse".

HowardHinnant commented 3 years ago

No idea really. My best guess is that they didn't want to venture too close to months (calendrical arithmetic). :-)

ecorm commented 3 years ago

It turns out it's the ISO 8601 standard itself that constrains it to either PnW or PnYnMnDTnHnMnS. See 4.4.3.2 in this draft of the 2016 version of the standard.

I cannot seem to find a rationale for the exclusion of the W in the PnYnMnDTnHnMnS expression. Perhaps it's due to human factors (i.e. avoid confusion).