Title
`time_get::do_get_date` is problematic even after LWG 461
Status
new
Section
[locale.time.get.members]
Submitter
S. B. Tam

Created on 2025-06-27.00:00:00 last changed 1 month ago

Messages

Date: 2025-10-21.13:37:21

Proposed resolution:

This wording is relative to N5014.

  1. Modify [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"
Date: 2025-10-15.00:00:00

[ 2025-10-21; Jonathan adds wording ]

This restores the slashes lost by LWG 461 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.

Date: 2025-10-15.00:00:00

[ 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`!"

Date: 2025-06-27.00:00:00

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

LWG 461 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 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 [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()`.

History
Date User Action Args
2025-10-21 13:12:40adminsetmessages: + msg15305
2025-10-21 13:12:40adminsetmessages: + msg15304
2025-10-21 11:45:47adminsetmessages: + msg15300
2025-06-27 00:00:00admincreate