3

我有这种方法可以将语言环境设置为波兰语:

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]);
}

为简洁起见,我已经删掉了其他语言。现在,当我格式化一个COleDateTime对象并显示月份时,比如一月,它显示为:

斯蒂琴

但我想将其显示为:

石竹

是否有区域设置来调整COleDateTime::Format方法或区域返回的月份值?

否则我将不得不手动添加一些东西来覆盖。

我希望返回的月份是:

  1. 石竹
  2. 卢特戈
  3. 马卡
  4. 桂花
  5. 玛雅
  6. 切尔瓦卡
  7. 利普卡
  8. 癔症
  9. 仙人掌
  10. 帕兹杰尔尼卡
  11. 列表小册子
  12. 格鲁德尼亚

更新

根据here它指出:

某些语言,例如芬兰语、德语、波兰语和俄语,有多种名词形式。如果您打算使用系统提供的本地化名称,请进行语言学家检查以确保您在正确的上下文中使用它们。Windows 带有波兰语和俄语月份名称的主格和属格形式;形式根据月份名称在字符串中相对于日期名称的位置而变化。Windows 在由空值分隔的单个字符串中返回这两种形式。对于所有其他语言,系统仅携带一种形式的每月名称或日期名称

现在,这就是我实际格式化日期字符串的方式(因为我支持 40 多种语言,这有点棘手。所以,(对于英语)我从这个格式字符串开始:

%1 %2!d!-%3!d!
  1. %1月份
  2. %2!d!第一天的价值。
  3. %3!d!第二天的值。

如果我的约会需要跨越两个月,我有:

%1 %2!d!–%3 %4!d!
  1. %1月份值。
  2. %2!d!第一天的价值。
  3. %3第二个月的值。
  4. %3!d!第二天的值。

上面是这样使用的:

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());
}

对于Polish,我各自的格式字符串是:

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

所以,我可以看到,因为我正在格式化日期字符串,FormatMessage并且仅使用该COleDateTime::Format方法来解析它可能是问题原因的月份

由于我在日期字符串中有两个日期,我不能只使用一个日期格式 API 调用(因为我的日期字符串代表一周跨度)。

所以我检查了:

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

它没有任何区别。所以我尝试了这个:

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

它没有任何区别。它仍然以与以前相同的方式显示日期。即使它确实正确显示了日期,它也不会考虑来自两个 COleDateTime 对象的日期范围。

使困惑。

更新 2:

也试过:

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

只是不会显示变体。

更新 3

我可以让它显示正确日期的唯一方法是这样的:

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

那么月份是正确的。现在在我提到的文章中指出:

Windows 在由空值分隔的单个字符串中返回这两种形式。

我什至无法弄清楚如何访问它。

4

2 回答 2

1

我遇到了其他问题,但它们与这个问题不同,所以我仍然会在这里提供我的答案。

首先,我找到了一份文件,其中指出您必须d在日期中显示正确的月份版本。

因为,我想显示一个日期范围,我从这个开始:

抛光

模板:%1-%2 日期 1:d 日期 2:d MMMM

然后我格式化日期:

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

正确显示它。如果日期范围跨越两个月,我有:

模板:%1-%2 日期 1:d MMMM 日期 2:d MMMM

它运作良好。

于 2018-12-10T17:17:56.810 回答
1

从 Windows 7 开始,您还可以使用LOCALE_RETURN_GENITIVE_NAMES来返回月份的属格名称。运行这个:

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';
}

给出以下结果:

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

这在波兰语中确实是几个月的专有名词。

于 2021-04-10T21:43:00.547 回答