4

I want to format dates and numbers according to the "Regional format" setting the user configured in Windows 10. With WPF this was no problem. With UWP this seems to impossible without resorting to hacks.

Sample code to experiment with.

I stared a new question because the best similar one is 3 years old without an accepted answer.

The "Regional format" is a Windows setting the user can configure independent of the language and region. E.g. the user can have configured:

  • Languages: English (as Windows display language), French, German
  • Region: Thailand (to get regional information)
  • Regional format: German (to display dates and numbers in German format)

enter image description here

MS seems to want us using UserProfile.GlobalizationPreferences, but this does not expose the active "Regional format". There is an MS statement "It is intentional. Microsoft is moving away from forcing applications to be in the language of the OS..." in the question mentioned above. We never had a problem creating apps in a language different from the OS. And this does not explain how to honor the users choice in an UWP app.

  • UserProfile.GlobalizationPreferences.HomeGeographicRegion returns the region not the "Regional Format".
  • Windows.Globalization.Language.CurrentInputMethodLanguageTag depends on the keyboard selection.
  • Windows.System.UserProfile.GlobalizationPreferences.Languages(1) only works if the user accidentally configured a "Regional format"
    matching the second language.

I read all posts I could find about this and the only solution seems to be the following hack described here:

 var systemLanguage = GlobalizationPreferences.Languages.First();
 var regionInfo = new RegionInfo(systemLanguage);
 var dtf = new DateTimeFormatter("longdate", new[] { regionInfo.TwoLetterISORegionName });
 var regionInfoName = dtf.ResolvedLanguage;
 var regionFormatCultureInfo = new CultureInfo(regionInfoName);

What MS seems to suggest does not work for me and my customers complain about my apps not honoring their settings.

Can someone shed some light into this? If this is an SDK bug, it should have been fixed long ago.

The built-in Calendar UWP app does honor the regional format.

Community
  • 1
  • 1
Peter Meinl
  • 2,566
  • 25
  • 39
  • 2
    The WinRT/UWP concept here seems to be based on "language" (even the signatures of XAML ValueConverters changed from using culture to language) and does not take into account that users expect "Regional format" settings being independent of language choices. I hope someone can explain the rationale behind this and propose a clean solution for the scenario of my question. – Peter Meinl Jun 06 '16 at 10:56
  • 1
    You do not need the RegionInfo. Just use new DateTimeFormatter("longdate", new[] { "US" }); – Marcel Wolterbeek Jun 07 '16 at 20:33
  • This is indeed very annoying. Many of Microsofts own UWP apps such as Weather and Calculator do not take your regional settings into account, but rely on Display language. Many users prefer the UI to be in US Eng, but use another keyboard and region to get date/time formatting, decimal separators etc. correct according to their region. If you look in the Windows 10 Feedback Hub, with hundreds of items related to this, all ignored by MS, it seems clear that MS is probably by (incorrect) design. – vzczc Jan 31 '17 at 12:44

1 Answers1

0

Take a look at Pedro Lamas's post: CultureInfo changes in UWP - Part 2. I had the same problem, and it works.

using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;

public class CultureInfoHelper
{
    [DllImport("api-ms-win-core-localization-l1-2-0.dll", CharSet = CharSet.Unicode)]
    private static extern int GetLocaleInfoEx(string lpLocaleName, uint LCType, StringBuilder lpLCData, int cchData);

    private const uint LOCALE_SNAME = 0x0000005c;
    private const string LOCALE_NAME_USER_DEFAULT = null;
    private const string LOCALE_NAME_SYSTEM_DEFAULT = "!x-sys-default-locale";
    private const int BUFFER_SIZE = 530;

    public static CultureInfo GetCurrentCulture()
    {
        var name = InvokeGetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME);
        if (name == null)
        {
            name = InvokeGetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME);
            if (name == null)
            {
                // If system default doesn't work, use invariant
                return CultureInfo.InvariantCulture;
            }
        }
        return new CultureInfo(name);
    }

    private static string InvokeGetLocaleInfoEx(string lpLocaleName, uint LCType)
    {
        var buffer = new StringBuilder(BUFFER_SIZE);
        var resultCode = GetLocaleInfoEx(lpLocaleName, LCType, buffer, BUFFER_SIZE);
        if (resultCode > 0)
        {
            return buffer.ToString();
        }
        return null;
    }
}

As he says:

All you need is to copy the above to a file in your UWP project, and then call CultureInfoHelper.GetCurrentCulture().

Having said that, see these two examples.

For dates

For instance, to format a date using the short pattern, do this:
var cultureInfo = CultureInfoHelper.GetCurrentCulture();
string dateStr = DateTime.Now.ToString(cultureInfo.DateTimeFormat.ShortDatePattern, cultureInfo);

For numbers

And an example of formatting a number with a standard numeric format string:
double number = 12345.678;
string numberStr = number.ToString("N", cultureInfo);
Jess Rod
  • 190
  • 11