question

ScottZhong-5398 avatar image
0 Votes"
ScottZhong-5398 asked MinxinYu-MSFT commented

Windows 11 Latin locale strftime x format specifier behavior different than Windows 10

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://docs.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?



windows-11c++
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I had missed the fact that locale "la" and "la-VA" doesn't exists on Linux. Please disregard the Linux portion from this question.

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://docs.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?

0 Votes 0 ·

Is your problem solved?

0 Votes 0 ·
MinxinYu-MSFT avatar image
0 Votes"
MinxinYu-MSFT answered MinxinYu-MSFT edited

Hi, @ScottZhong-5398

For your reference: LOCALE_SSHORTDATE and Day, Month, Year, and Era Format Pictures

g, gg Period/era string formatted as specified by the CAL_SERASTRING value. The "g" and "gg" format pictures in a date string are ignored if there is no associated era or period string.

It doesn't look like an expected behavior. You can report the issue to Developer Community and post the link in the comment.
Best regards,

Minxin Yu


If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

LimitlessTechnology-2700 avatar image
0 Votes"
LimitlessTechnology-2700 answered

Hi there,

strftime returns the number of characters placed in strDest and wcsftime returns the corresponding number of wide characters.

If the total number of characters, including the terminating null, is more than maxsize, both strftime and wcsftime return 0 and the contents of strDest are indeterminate.

As this is not the expected output you can try to raise this via the feedback hub so that the team can have a look and come out with a solution in upcoming builds.



--If the reply is helpful, please Upvote and Accept it as an answer–

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.