This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4285. time_get::do_get_date is problematic even after LWG 461

Section: 28.3.4.6.2.2 [locale.time.get.members] Status: New Submitter: S. B. Tam Opened: 2025-06-27 Last modified: 2025-10-21

Priority: 3

View all issues with New status.

Discussion:

Background: https://github.com/cplusplus/draft/pull/8009

LWG 461(i) changed time_get::do_get_date to parse a set of fixed formats. For example, if time_get::date_order() is no_order or mdy, the format parsed by do_get_date is %m/%d/%y.

This has several problems:

  1. When the resolution of LWG 461(i) was applied to the draft standard, the slashes were lost. This could mislead people into implementing do_get_date using the incorrect formats. Fortunately, none of the standard library implementations are affected by this mistake.

  2. Only 2-digit years are accepted due to the use of %y. This could lead to incorrect parse if strftime uses %Y for the locale's date format.

  3. date_order() might need additional locale facets to find out the date order, but it doesn't have an ios_base& argument from which to get the locale.

  4. Many locales do not use any of the specified formats. For example, de_DE uses %d.%m.%Y, zh_CN uses %Y年%m月%d日. Although 28.3.4.6.2.3 [locale.time.get.virtuals]/5 gives an implementation the latitude to accept additional formats, ambiguity could arise if the locale's format disagrees with date_order().

On POSIX systems, it is possible to query the locale's date format using nl_langinfo(D_FMT). Maybe an implementation should be allowed to use that format instead of the one indicated by date_order().

[2025-10-21; Reflector poll.]

Set priority to 3 after reflector poll.

"The current wording of do_date_order() suggests it should return one of the dmy, mdy, ymd, ymd, or ydm enumerators as long as the date format specified by %x has no components except day, month, and year. But that fails to consider alternative separators between the components. The kok_IN locale uses `"%d-%m-%y" which does not contain "other variable components" but still doesn't match any of the fixed formats in Table 102. We need normative wording allowing no_order, instead of just a footnoote, and we need to say do_get_date only has to use the formats in the table when do_date_order() != no_order. It should not default to the mdy format when do_date_order() returns no_order, because if the mdy format is correct then it should have returned mdy!"

[2025-10-21; Jonathan adds wording]

This restores the slashes lost by LWG 461(i) and attempts to make the use and effects of no_order more useful. It does not attempt to address the problem that do_date_order() has no access to an ios_base object.

Proposed resolution:

This wording is relative to N5014.

  1. Modify 28.3.4.6.2.3 [locale.time.get.virtuals] as indicated:

    dateorder do_date_order() const;

    -1- Returns: An enumeration value indicating the preferred order of components for those date formats that are composed of day, month, and year.228 Returns no_order if the date format specified by 'x' contains other variable components (e.g., Julian day, week number, week day) does not match one of the formats in Table [tab:locale.time.get.dogetdate] .

    228) This function is intended as a convenience only, for common formats, and can return no_order in valid locales.
    iter_type do_get_time(iter_type s, iter_type end, ios_base& str,
                          ios_base::iostate& err, tm* t) const;
    
    [...]
    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 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 shown in Table 102. When do_date_order() returns no_order, it is unspecified whether the format shown in the table is used, or whether additional implementation-defined formats are accepted.

    [Note ?: For example, an implementation can accept dates in the format specified by 'x' as well as, or instead of, the format "%m/%d/%y". — end note

    -5- An implementation may also accept additional implementation-defined formats.

    -6- Returns: An iterator pointing immediately beyond the last character recognized as possibly part of a valid date.

    Table 102 — do_get_date effects [tab:locale.time.get.dogetdate]

    date_order() Format
    no_order "%m/%d/%y"
    dmy "%d/%m/%y"
    mdy "%m/%d/%y"
    ymd "%y/%m/%d"
    ydm "%y/%d/%m"