461. time_get hard or impossible to implement

Section: 25.4.5.1.2 [locale.time.get.virtuals] Status: CD1 Submitter: Bill Plauger Opened: 2004-03-23 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [locale.time.get.virtuals].

View all issues with CD1 status.

Discussion:

Template time_get currently contains difficult, if not impossible, requirements for do_date_order, do_get_time, and do_get_date. All require the implementation to scan a field generated by the %x or %X conversion specifier in strftime. Yes, do_date_order can always return no_order, but that doesn't help the other functions. The problem is that %x can be nearly anything, and it can vary widely with locales. It's horribly onerous to have to parse "third sunday after Michaelmas in the year of our Lord two thousand and three," but that's what we currently ask of do_get_date. More practically, it leads some people to think that if %x produces 10.2.04, we should know to look for dots as separators. Still not easy.

Note that this is the opposite effect from the intent stated in the footnote earlier in this subclause:

"In other words, user confirmation is required for reliable parsing of user-entered dates and times, but machine-generated formats can be parsed reliably. This allows parsers to be aggressive about interpreting user variations on standard formats."

We should give both implementers and users an easier and more reliable alternative: provide a (short) list of alternative delimiters and say what the default date order is for no_order. For backward compatibility, and maximum latitude, we can permit an implementation to parse whatever %x or %X generates, but we shouldn't require it.

Proposed resolution:

In the description:

iter_type do_get_time(iter_type s, iter_type end, ios_base& str,
        ios_base::iostate& err, tm* t) const;

2 Effects: Reads characters starting at suntil it has extracted those struct tm members, and remaining format characters, used by time_put<>::put to produce the format specified by 'X', or until it encounters an error or end of sequence.

change: 'X'

to: "%H:%M:%S"

Change

iter_type do_get_date(iter_type s, iter_type end, ios_base& str,
        ios_base::iostate& err, tm* t) const;

4 Effects: Reads characters starting at s until it has extracted those
struct tm members, and remaining format characters, used by
time_put<>::put to produce the format specified by 'x', or until it
encounters an error.

to

iter_type do_get_date(iter_type s, iter_type end, ios_base& str,
        ios_base::iostate& err, tm* t) const;

4 Effects: Reads characters starting at s until it has extracted those struct tm members, and remaining format characters, used by time_put<>::put to produce one of the following formats, or until it encounters an error. The format depends on the value returned by date_order() as follows:

        date_order()  format

        no_order      "%m/%d/%y"
        dmy           "%d/%m/%y"
        mdy           "%m/%d/%y"
        ymd           "%y/%m/%d"
        ydm           "%y/%d/%m"

An implementation may also accept additional implementation-defined formats.

[Redmond: agreed that this is a real problem. The solution is probably to match C99's parsing rules. Bill provided wording. ]