https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45896
--- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> --- I noticed that time_get::_M_extract_via_format just ignores any O or E modifier: if (__c == 'E' || __c == 'O') __c = __ctype.narrow(__format[++__i], 0); So we treat %Ec exactly like %c and only use the D_T_FMT string, instead of ERA_D_T_FMT: case 'c': // Default time and date representation. const char_type* __dt[2]; __tp._M_date_time_formats(__dt); __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, __tm, __dt[0], __state); We should use __dt[1] when the modifier was 'E'. The commit msg for Jakub's patch mentions these other unfixed things: 1) seems %j, %r, %U, %w and %W aren't handled (not sure if all of them are already in POSIX 2009 or some are later) 2) I haven't touched the %y/%Y/%C and year handling stuff, that is definitely not matching what POSIX 2009 says: C All but the last two digits of the year {2}; leading zeros shall be permitted but shall not be required. A leading '+' or '−' character shall be permitted before any leading zeros but shall not be required. y The last two digits of the year. When format contains neither a C conversion specifier nor a Y conversion specifier, values in the range [69,99] shall refer to years 1969 to 1999 inclusive and values in the range [00,68] shall refer to years 2000 to 2068 inclusive; leading zeros shall be permitted but shall not be re‐ quired. A leading '+' or '−' character shall be permitted before any leading zeros but shall not be required. Note: It is expected that in a future version of this standard the default century inferred from a 2-digit year will change. (This would apply to all commands accepting a 2-digit year as input.) Y The full year {4}; leading zeros shall be permitted but shall not be required. A leading '+' or '−' character shall be permitted before any leading zeros but shall not be required. I've tried to avoid making changes to _M_extract_num for these as well to keep current status quo (the __len == 4 cases). One thing is what to do for things with %C %y and/or %Y in the formats, another thing is what to do in the methods that directly perform _M_extract_num for year 3) the above question what to do for leading whitespace of any numbers being parsed 4) the %p%I issue mentioned above and generally what to do if we pass state and have finalizers at the end of parsing 5) _M_extract_via_format is also inconsistent with its callers on handling the non-whitespace characters in between format specifiers, the caller follows https://eel.is/c++draft/locale.time.get#members-8.6 and does case insensitive comparison: // TODO real case-insensitive comparison else if (__ctype.tolower(*__s) == __ctype.tolower(*__fmt) || __ctype.toupper(*__s) == __ctype.toupper(*__fmt)) while _M_extract_via_format only compares exact characters: // Verify format and input match, extract and discard. if (__format[__i] == *__beg) ++__beg; (another question is if there is a better way how to do real case-insensitive comparison of 2 characters and whether we e.g. need to handle the Turkish i/İ and ı/I which have different number of bytes in UTF-8) 6) _M_extract_name does something weird for case-sensitivity, // NB: Some of the locale data is in the form of all lowercase // names, and some is in the form of initially-capitalized // names. Look for both. if (__beg != __end) and if (__c == __names[__i1][0] || __c == __ctype.toupper(__names[__i1][0])) for the first letter while just __name[__pos] == *__beg on all the following letters. strptime says: In case a text string (such as the name of a day of the week or a month name) is to be matched, the comparison is case insensitive. so supposedly all the _M_extract_name comparisons should be case insensitive.