In a testdir of nstrftime I see this failure regarding the %c specifier: * In the "C" locale (test-nstrftime-1.sh):
%c directive: 10/26/17 06:40:03 ../../gltests/test-nstrftime.h:449: assertion 'STREQ (buf, "Thu Oct 26 06:40:03 2017")' failed * In a French locale (test-nstrftime-2.sh): %c directive: 26/10/2017 06:40:03 ../../gltests/test-nstrftime.h:452: assertion 'STREQ (buf, "jeu. 26 oct. 2017 06:40:03") || STREQ (buf, "jeu. 26 oct. 06:40:03 2017") || STREQ (buf, "Jeu 26 oct 06:40:03 2017") || STREQ (buf, "26 octobre 2017 06:40:03") || STREQ (buf, "26 octobre 2017 à 06:40:03") || STREQ (buf, "26 octobre 2017 \340 06:40:03")' failed In order to avoid wrong interpretation of the output, it is useful to print a month name rather than the month number. This patch does it. 2024-05-27 Bruno Haible <br...@clisp.org> nstrftime, c-nstrftime: Make %c work on native Windows. * doc/posix-functions/strftime.texi: Mention the %c problem. * lib/strftime.c: Include <locale.h> always. Include hard-locale.h. (__strftime_internal): For %c, use a subformat that contains the weekday name (or abbrev.) and the month name (or abbrev.). * modules/nstrftime (Depends-on): Add hard-locale. (Link): New section. * modules/nstrftime-tests (Makefile.am): Link test-nstrftime with $(HARD_LOCALE_LIB). diff --git a/doc/posix-functions/strftime.texi b/doc/posix-functions/strftime.texi index 0c51c7ecdf..68af3224a4 100644 --- a/doc/posix-functions/strftime.texi +++ b/doc/posix-functions/strftime.texi @@ -21,6 +21,10 @@ on some platforms: glibc 2.30, NetBSD 10.0, Solaris 11.4. @item +The %c specifier produces no weekday name and no month name, only a +potentially ambiguous numerical output, on some platforms: +mingw, MSVC. +@item The %r specifier produces empty output, at least in a French locale, on some platforms: macOS 12.5, FreeBSD 14.0. diff --git a/lib/strftime.c b/lib/strftime.c index 834f3a79f4..069bab7095 100644 --- a/lib/strftime.c +++ b/lib/strftime.c @@ -92,14 +92,13 @@ extern char *tzname[]; #include <stdlib.h> #include <string.h> -#if USE_C_LOCALE && HAVE_STRFTIME_L -# include <locale.h> -#endif - +#include <locale.h> #if (defined __NetBSD__ || defined __sun) && REQUIRE_GNUISH_STRFTIME_AM_PM -# include <locale.h> # include "localename.h" #endif +#if !USE_C_LOCALE +# include "hard-locale.h" +#endif #include "attribute.h" #include <intprops.h> @@ -1288,6 +1287,12 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize) subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT)); #elif USE_C_LOCALE && !HAVE_STRFTIME_L subfmt = L_("%a %b %e %H:%M:%S %Y"); +#elif defined _WIN32 && !defined __CYGWIN__ + /* On native Windows, "%c" is "%d/%m/%Y %H:%M:%S" by default. */ + if (hard_locale (LC_TIME)) + subfmt = L_("%a %e %b %Y %H:%M:%S"); + else + subfmt = L_("%a %b %e %H:%M:%S %Y"); #else goto underlying_strftime; #endif diff --git a/modules/nstrftime b/modules/nstrftime index 69b9d84605..a9e86fb1f8 100644 --- a/modules/nstrftime +++ b/modules/nstrftime @@ -14,6 +14,7 @@ c99 errno extensions intprops +hard-locale libc-config localename-unsafe-limited stdbool @@ -29,6 +30,9 @@ lib_SOURCES += nstrftime.c Include: "strftime.h" +Link: +$(HARD_LOCALE_LIB) + License: LGPL diff --git a/modules/nstrftime-tests b/modules/nstrftime-tests index b5c6ac2fa5..40ea1bd199 100644 --- a/modules/nstrftime-tests +++ b/modules/nstrftime-tests @@ -26,4 +26,4 @@ TESTS_ENVIRONMENT += \ LOCALE_FR='@LOCALE_FR@' \ LOCALE_FR_UTF8='@LOCALE_FR_UTF8@' check_PROGRAMS += test-nstrftime -test_nstrftime_LDADD = $(LDADD) $(SETLOCALE_LIB) +test_nstrftime_LDADD = $(LDADD) $(SETLOCALE_LIB) $(HARD_LOCALE_LIB)