2012-09-24 38 views
21

我在Windows 8 Metro应用程序(XAML & C#)中遇到了有关用户区域设置的问题。看来,应用程序将不会尊重用户的区域设置,所以即使你的Windows 8被设置为显示日期和时间格式芬兰的应用仍然会使用美国格式显示。但是,这是一个很大的问题,我一定有一些东西丢失了?WinRT应用程序和区域设置。根据用户的区域设置格式化日期和数字的正确方法是什么?

为了验证这一点,我开始通过创建一个WPF应用程序。该应用程序会打印出的CurrentCulture和格式化DateTime.Now:

private void Culture_Loaded_1(object sender, RoutedEventArgs e) 
    { 
     this.Culture.Text = System.Globalization.CultureInfo.CurrentCulture.DisplayName; 
    } 

    private void Date_Loaded_1(object sender, RoutedEventArgs e) 
    { 
     this.Date.Text = DateTime.Now.ToString(); 
    } 

这里是我的默认区域设置: Regional settings

运行时,应用程序显示在芬兰格式的日期:

Finnish formatting

然后我将区域设置更改为美国: US Regional settings

而当应用程序被再次运行,文化和格式更改: US wpf formatting

这是如我所料一切工作,这也是我没有料到的WinRT应用工作。

因此,下一步,我创建了一个具有相同代码的WinRT(XAML & C#)应用程序,并将区域设置恢复为芬兰语。问题:

Winrt formatting

即使我已经通过区域设置该格式应该是“芬兰”定义的,WinRT的应用程序将显示美国格式化的日期时间。然后我修改了应用程序的项目文件并提出FI-FI的默认语言

Default language

这一变化也修改了应用程序的文化:

Finnish winrt formatting

奇怪。我将默认语言更改回默认值,并将格式恢复为美国。然后,我在项目内创建了文件夹“Strings-fi-FI”,并在项目中添加了一个空的“Resources.resw”。这个空文件似乎是不够的,因为我现在越来越芬兰格式:当我删除空资源文件

Resource file Finnish formatting

,将打印格式返回到美国:

Resource file removed US formatting winrt

很奇怪。

这导致了几个问题,但我认为的主要问题是:WinRT应用程序是否不像WPF应用程序那样遵循用户的区域设置?

回答

14

已经有一段时间了,但问题还没有完全解答,所以让我分享一下我的小研究。 Depechie大多数都是对的,但他只提供了一个链接,并不确定。

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

为了获得当前区域我们可以使用:

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

但正如我注意到它仅包含区域的信息,没有语言代码。为了获得语言,我们可以使用:

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) 

他们返回格式语言地区BCP47语言标签,如“EN-US”,如果语言都有方言,或只是语言如“PL”,如果语言没有大的方言。

我们还可以设置一个主要语言,这将覆盖所有的休息:

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

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

也有新的API日期,时间和数字:

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的多很多,但我认为,这给我们的总体思路。进一步阅读:

您还可以找到一些关于windo问题的主题ws 8开发中心论坛与一些微软员工的答案,但他们主要向您发送文档。

+3

所以,实际上可以如何获取/尊重用户分区格式设置? 我开始使用以下配置的windows phone 8.1仿真器进行测试: UI语言:德语,地区:美国,格式设置:爱尔兰语 我找不到信息,用户已将其格式设置爱尔兰人。我唯一的愿望是像用户想要看到的那样格式化日期时间。和区域格式不会自动意味着它的区域我将设备设置为或我选择的用户界面语言。在我的设备上,我将用户界面设置为英文,但希望以德文格式查看所有时间戳记和日期... – Kornelis

+0

谢谢,以下内容非常棒,因为我需要ISO 3166-1 alpha2 https://en.wikipedia.org/ wiki/ISO_3166-1_alpha-2 GeographicRegion userRegion = new GeographicRegion(); string regionCode = userRegion.CodeTwoLetter; – Quincy

+0

这对我有效,但现在我需要大数字和'CurrencyFormatter'不支持小数,所以我需要一个解决方法... –

4

这是故意的。微软正在摆脱强迫应用程序成为操作系统的语言。相反,每个应用程序使用由应用程序声明的信息(清单语言,可在Windows.Globalization.ApplicationLanguages.ManifestLanguages中观察到)并由用户声明(用户语言,可在Windows.System.UserProfile.GlobalizationPreferences.Languages中观察到)来确定如何显示资源和全球化的日期和时间。这组语言被称为应用程序语言(可在Windows.Globalization.ApplicationLanguages.Languages中观察到)。你所看到的行为是因为你在摆弄用户语言和清单语言,你会得到不同的应用程序语言。

+4

有趣的方法,虽然作为一个葡萄牙生活在英国(目前为微软工作),我couldn对此不再不同意!这是我的看法:我的Win10手机的语言设置为“英语美国”,国家为“英国”,地区格式为“葡萄牙语(葡萄牙)”。 Outlook以正确的pt-PT格式显示日期,但所有其他应用程序坚持使用en-US,这是恕我直言的错误,而不是我预期的! –

0

即使两年前被问到,这篇文章似乎仍然相关。 我刚刚遇到它,因为我正在寻找关于同样事情的答案。 我也想在我的WP8.1 WinRT应用程序中以区域格式显示日期。 这里发布的信息有帮助,但将它拼凑在一起很困难。

这是我想出了,它似乎为我工作,因为我需要答案:

using Windows.Globalization; 
using Windows.Globalization.DateTimeFormatting; 

private string FormatDate(int year, int month, int day) 
{ 
    GeographicRegion userRegion = new GeographicRegion(); 
    string regionCode = userRegion.CodeTwoLetter; 
    var formatter = new DateTimeFormatter("year month day", new[] { regionCode }); 
    DateTime dateToFormat = new DateTime(year, month, day); 
    var formattedDate = formatter.Format(dateToFormat); 
    return formattedDate; 
} 
相关问题