Hi we are seeing a difference in strftime x format specifier behavior on Windows 11 when the locale is set to "la" or "la-VA" (Latin). The problem can be observed with either Visual Studio 2019 or 2022. See the following testcase
#if defined(_WIN32)
# include <windows.h>
#else
# include <locale.h>
#endif
#include <iostream>
int main()
{
setlocale( LC_ALL, "la" );
char outstr[200];
struct tm t = {0, 0, 0, 1, 0, 0, 0};
t.tm_mon = 1;
t.tm_mday = 6;
t.tm_year = 70;
mktime(&t);
if (strftime(outstr, sizeof(outstr), "%x", &t) == 0) {
fprintf(stderr, "strftime returned 0");
exit(EXIT_FAILURE);
}
std::cout << outstr << std::endl;
return 0;
};
On Windows 10 the output is:
C:\dev>cl /EHsc test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30038.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
Microsoft (R) Incremental Linker Version 14.29.30038.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
C:\dev>test.exe
06/02/1970
On Windows 11 the output is:
C:\dev>cl /EHsc test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30038.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
Microsoft (R) Incremental Linker Version 14.29.30038.1
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
C:\dev>test.exe
6 2 1970 gg
Using GetLocaleInfoEx to query the LOCALE_SSHORTDATE of the locale showed on Windows 10 has the format "dd/MM/yyyy" and Windows 11 has "d M yyyy gg"
#include <windows.h>
#include <iostream>
int main()
{
int ret;
wchar_t buf[200];
wchar_t loc_name[] = L"la-VA";
ret = GetLocaleInfoEx((LPCWSTR)&loc_name,
LOCALE_SSHORTDATE,
(LPWSTR)&buf,
sizeof(buf) / sizeof(*buf) );
printf("locale: %ls\n", loc_name);
printf("LOCALE_SSHORTDATE: %ls\n", buf);
return 0;
}
I didn't find the "gg" datetime specifier in strftime documentation, however, I did find it in C# documentation noted here https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings#gSpecifier
strftime appears to not have the period and era information but instead of ignoring the specifier as documented in C#, it outputs the specifier. I think this is the core of my question, should "gg" be printed?