Search code examples
windowsdatewinapicalendarlocale

kernel32.GetDateFormatEx and ar-SA dates


I am using GetDateFormatEx (more specifically, ctypes.windll.kernel32.GetDateFormatEx using Python), which is documented at

https://msdn.microsoft.com/en-us/library/windows/desktop/dd318088%28v=vs.85%29.aspx

And using today's date as the SYSTEMTIME input, and a NULL format string and 0 flags. however specifically for the ar-SA locale.

It is returning a value of "06/01/37", which is not what I expected. I expected to be in the ar-SA language (ie, what, in my English eyes, look like squibbles).

I also expected it would return an arabic short date string, specifically, for the gregorian calendar, however it seems to be using the Hijri calendar instead. How do I detect that a Hijri calendar is being used?

So, to re-iterate, what I want to know is:

  1. How do I get the arabic date, something more like: تشرين الأول أكتوبر ١٩ ١٥

  2. How do I detect the type of calendar that the user is expecting to be using?


Solution

  • Is it possible that you yourself has overridden the locale settings for date formatting on your testing PC? Maybe you need to use the LOCALE_NOUSEROVERRIDE flag.

    UPDATE

    I have tested this in C++

    GetDateFormatEx(L"ar-SA", LOCALE_NOUSEROVERRIDE | DATE_AUTOLAYOUT | DATE_LONGDATE, nullptr, nullptr, buf, _countof(buf), nullptr);
    

    The resulting date is

    ‏06/‏محرم/‏1437

    UPDATE 2

    This apparently depends on how Windows define the locale. I have tried different combination of the flags (DATE_AUTOLAYOUT | DATE_LONGDATE, DATE_AUTOLAYOUT | DATE_USE_ALT_CALENDAR | DATE_LONGDATE, DATE_AUTOLAYOUT | DATE_USE_ALT_CALENDAR). While for "ar-SA" this gives

    ‏06/‏محرم/‏1437

    ‏06/‏01/‏1437

    ‏06/‏01/‏37

    for "ja-JP" (Japanese) it gives

    2015‎年‎10‎月‎19‎日

    平成 ‎27‎年‎10‎月‎19‎日

    平成 ‎27/‎10/‎19

    I suspect (not knowing full Windows NLS capabilities), you will have to use either specific formatting string or some other library, like ICU, to get more squigly dates.

    UPDATE 3

    It probably does not get any more squigly than with DATE_AUTOLAYOUT | DATE_USE_ALT_CALENDAR flags and L"dddd, dd MMMM, yyyy gg" format:

    ‏الإثنين, ‏06 ‏محرم, ‏1437 ‏بعد الهجرة

    UPDATE 4

    Further search reveals this:

    Note: If you got the Gregorian date with Arabic names, then you probably forgot to set the calendar type to the Hijri calendar.

    So it seems your Windows would have to have the Hijri calendar selected in your locale for the numbers to get formatted with the traditional numerals.

    UPDATE 5

    Finally, how do I detect that the Hijri calendar is being used in that case?

    You can detect the calendar that is in use by calling GetLocaleInfoEx() with LOCALE_ICALENDARTYPE as its LCType parameter and comparing the returned number with constants defined in WinNls.h:

    #define CAL_HIJRI                      6      // Hijri (Arabic Lunar) calendar
    #define CAL_UMALQURA                   23     // UmAlQura Hijri (Arabic Lunar) calendar