3

I have this method to set the locale to Polish:

void CMeetingScheduleAssistantApp::SetLocale()
{
    // https://www.microsoft.com/resources/msdn/goglobal/default.mspx#ISO2
    CString strLang[NUM_LANGUAGES] =
    {
        _T("plk")
        // Add more languages here
    };

    _tsetlocale(LC_ALL, strLang[m_eLanguage - LANGUAGE_ENGLISH]);
}

I have cut the other languages out for brevity. Now, when I format a COleDateTime object and display the month, say January, it shows as:

styczeń

But i want to show it as:

stycznia

Is there a locale setting to adjust the month values returned by the COleDateTime::Format method or locale?

Otherwise I will have to add something manual to override.

The months I would like returned are:

  1. stycznia
  2. lutego
  3. marca
  4. kwietnia
  5. maja
  6. czerwca
  7. lipca
  8. sierpnia
  9. września
  10. października
  11. listopada
  12. grudnia

Update

According to here it states:

Some languages, such as Finnish, German, Polish, and Russian, have several noun forms. If you plan to use localized names provided by the system, have a linguist check to make sure you are using them in the right context. Windows carries both the nominative and genitive forms of Polish and Russian month names; the form changes depending on the month name's position in the string relative to the day name. Windows returns both forms in a single string separated by a null value. The system carries only one form of each month name or day name for all other languages.

Now, this is how I am actually formatting my date strings (since I am supporting over 40 languages it is a bit tricky. So, (for English) I start with this format string:

%1 %2!d!-%3!d!
  1. %1 is the month.
  2. %2!d! is the first day value.
  3. %3!d! is the second day value.

If my date needs to cater for crossing over two months, I have:

%1 %2!d!–%3 %4!d!
  1. %1 is the month value.
  2. %2!d! is the first day value.
  3. %3 is the second month value.
  4. %3!d! is the second day value.

The above is used like this:

if (datThisMonday.GetMonth() == datEndOfWeek.GetMonth())
{
    strDate.FormatMessage(IDS_STR_TPL_OCLM_WEEK,
            datThisMonday.Format(_T("%B")), datThisMonday.GetDay(), datEndOfWeek.GetDay());
}
else
{
    strDate.FormatMessage(IDS_STR_TPL_OCLM_WEEK2,
            datThisMonday.Format(_T("%B")), datThisMonday.GetDay(),
            datEndOfWeek.Format(_T("%B")), datEndOfWeek.GetDay());
}

For Polish, my respective format strings are:

%2!d!-%3!d! %1
%2!d! %1–%4!d! %3

So, I can see that because I am formatting the the date string using FormatMessage and only using the COleDateTime::Format method to parse just the month that it is potentially the cause of the issue.

Since I have two dates in the date string I can't just use a single Date formatting API call (since my date string is representing a week span).

So I checked:

strDate = datThisMonday.Format(_T("%d %B"));

And it made no difference. So I tried this instead:

SYSTEMTIME sTime;
datThisMonday.GetAsSystemTime(sTime);
GetDateFormat(GetThreadLocale(), 
              DATE_LONGDATE, 
              &sTime, _T("d MMMM"), 
              strDate.GetBuffer(_MAX_PATH), _MAX_PATH);

It made no difference. It still shows the date the same way as before. Even if it did display the date correctly it doesn't factor for a date range from two COleDateTime objects.

Confused.

Update 2:

Also tried:

TCHAR szDate[100] = _T("");
GetDateFormatEx(_T("pl"), NULL, &sTime, _T("ddd MMMM"), szDate, 100, NULL);
AfxMessageBox(szDate);

Just will not show the variant.

Update 3

The only way I can get it to show the right date is like this:

GetDateFormatEx(_T("pl"), DATE_LONGDATE, &sTime, NULL, szDate, 100, NULL);

Then the month is correct. Now in the article I referred to it states:

Windows returns both forms in a single string separated by a null value.

I can't even work out how to access that.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
  • Google result for "translate january to polish" gives me `"styczeń"`, Windows seems to have it right. Is it supposed to be `"stycznia"`? – Barmak Shemirani Dec 09 '18 at 23:46
  • @BarmakShemirani I am not an expert, but it can be either. Try translating in reverse, using the second way. Look here: https://www.ics.uci.edu/~dan/genealogy/Miller/resource/polmonth.htm. The alternative way is what is being used in a resource that I am trying to replicate. – Andrew Truckle Dec 10 '18 at 05:44
  • 1
    I think "styczeń" is the correct one. I think this is from Windows resources in `GetLocaleInfo` (these settings can be changed but it will affect all applications, not recommended). I would just take the input and replace the wrong month names with the right month names. – Barmak Shemirani Dec 10 '18 at 06:18
  • 2
    It's a bit more complicated. when You enumerate months "styczeń" is the correct value. but when You specify the date, like 15.01.2019, correct is "15 stycznia 2019 " it's a bit similar like in English You would say 15 - fifteen, but the date would be 15-th fifteenth. I will search a bit in polish resources, when I find answer I will answer. – CAD Developer Dec 10 '18 at 07:09
  • @CADDeveloper See updated question. – Andrew Truckle Dec 10 '18 at 10:05
  • 1
    "Styczeń" and "Stycznia" can both be used, in Polish when you say it in your head it makes sense. Stycznia would be 100% grammatically correct but even if Styczeń was used no one would really notice the difference since its a minuscule detail which when reading out still makes sense In other words "stycznia" is valid a "styczneń" is correct I tried to find someting, but need to spend more time than I have today. – CAD Developer Dec 10 '18 at 11:58
  • @CADDeveloper OK, since a user has picked up on this I have decided to add my own text file and replace the date specifiers manually. I take your point that this is a minor matter. Thank you. – Andrew Truckle Dec 10 '18 at 12:00
  • @CADDeveloper I found an article https://rluzynski.fedorapeople.org/slides/2017-01-27-DevConf.cz/GenitiveMonths-updated.pdf and I will provide my answer later today. I have it working. – Andrew Truckle Dec 10 '18 at 14:22

2 Answers2

1

I have encountered other issues but they are distinct from this question, so I will still provide my answer here.

Firstly, I found a document which states that you must have d in the date for it to show the correct version of the month.

Since, I am wanting to display a date range, I start with this:

Polish

Template: %1-%2 Date 1: d Date 2: d MMMM

Then I format the date:

SYSTEMTIME sysTime;
ENSURE(rDate.GetAsSystemTime(sysTime));
GetDateFormatEx(_T("pl"),
    NULL,
    &sysTime, 
    strDateFormat, 
    strDate.GetBuffer(_MAX_PATH), _MAX_PATH, nullptr);

That displays it correctly. And if the date range spans two months I have:

Template: %1-%2 Date 1: d MMMM Date 2: d MMMM

It works well.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
1

Since Windows 7, you can also use the LOCALE_RETURN_GENITIVE_NAMES to return the genitive name of a month. Running this :

const wchar_t localeName[] = L"pl-PL";
for (LCTYPE m = LOCALE_SMONTHNAME1; m <= LOCALE_SMONTHNAME12; ++m) {
  wchar_t buf[1024];
  GetLocaleInfoEx(localeName, m | LOCALE_RETURN_GENITIVE_NAMES, buf, sizeof(buf) / sizeof(*buf));
  std::cout << to_utf8(buf) << '\n';
}

Gives the following result :

stycznia
lutego
marca
kwietnia
maja
czerwca
lipca
sierpnia
września
października
listopada
grudnia

which are indeed proper genitive names for months in Polish.

Daniel Kamil Kozar
  • 18,476
  • 5
  • 50
  • 64
  • 1
    Thanks for this info. Although, I am trying to format an actual date / date range and not obtain a specific month name. So my code has to cater for both types of month names. – Andrew Truckle Apr 11 '21 at 06:47