且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WinRT 应用程序和区域设置.根据用户的区域设置格式化日期和数字的正确方法?

更新时间:2023-10-03 23:24:28

已经有一段时间了,但问题没有完全回答,所以让我分享我的一点研究.Depechie 大部分是对的,但他只提供了一个链接,并不确定.

It's been a while, but the question is not fully answered, so let me share my little research. Depechie is mostly right, but he provided only a link and wasn't really sure.

是的,这种意外的变化是有意为之.我们不应再使用 CultureInfo,因为它包含遗留代码,而且 Microsoft 希望我们改用 Windows.Globalization API.

Yes, this unexpected change is intentional. We shouldn't use CultureInfo anymore as it contains legacy codes and Microsoft want us to use Windows.Globalization APIs instead.

要获取当前区域,我们可以使用:

To obtain current region we can use:

GeographicRegion userRegion = new GeographicRegion();
string regionCode = userRegion.CodeTwoLetter;

但我注意到它只包含区域信息,没有语言代码.要获得我们可以使用的语言:

But as I noticed it contains only region information, there's no language code. To obtain language we can use:

string langRegionCode = Windows.Globalization.Language.CurrentInputMethodLanguageTag; // depends on keyboard settings
List<string> langs = Windows.System.UserProfile.GlobalizationPreferences.Languages; // all user  languages, like in languages control panel
List<string> applicationlangs = Windows.Globalization.ApplicationLanguages.Languages; // application languages (user languages resolved against languages declared as supported by application)

如果语言有方言,它们会以 language-REGION 格式返回 BCP47 语言标签,如en-US";如果语言没有主要方言,则返回pl"之类的语言.

They return BCP47 language tags in format language-REGION like "en-US" if language has dialects or just language like "pl" if the language doesn't have major dialects.

我们还可以设置一种主要语言来覆盖所有其他语言:

We can also set one primary language which will override all the rest:

Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "en-US";

(这是一个持久化设置,应该在用户请求时使用)

(This is a persisted setting and is supposed to be used at user request)

还有用于日期、时间和数字的新 API:

There is also new API for date, time and numbers:

Windows.Globalization.DateTimeFormatting.DateTimeFormatter dtf = new DateTimeFormatter("longdate", new[] { "en-US" }, "US", CalendarIdentifiers.Gregorian, ClockIdentifiers.TwentyFourHour);
string longDate = dtf.Format(DateTime.Now);

Windows.Globalization.NumberFormatting.DecimalFormatter deciamlFormatter = new DecimalFormatter(new string[] { "PL" }, "PL");
double d1 = (double)deciamlFormatter.ParseDouble("2,5"); // ParseDouble returns double?, not double

Windows.Globalization API 确实有很多,但我认为这为我们提供了总体思路.进一步阅读:

There's really a lot more in Windows.Globalization APIs, but I think that this gives us the general idea. For further reading:

您还可以在 Windows 8 开发中心论坛上找到一些有关该问题的主题以及一些 Microsoft 员工的回答,但他们主要将您发送给文档.

You can also find some topics about the issue on windows 8 dev center forum with some Microsoft employee answers, but they mainly send you to the documentation.