Skip to content

iOS Numeric Format setting not respected #110430

Open

Description

@LiamMorrow

Description

When using decimal.Parse using the default CultureInfo (or not specifying one), MAUI does not respect the user's decimal separator options in iOS. Instead, it simply uses the language's default. What this means is that when a user is prompted for numerical, decimal input, the iOS keyboard presents them with a comma separator (as they have configured), but decimal.Parse treats it as a grouping separator.

Note that if the user specifies a LANGUAGE which uses commas as a decimal separator, everything works as expected and decimal parse treats commas as decimal separators.

Screenshot showing how the default culture parses a decimal, and the correct parsing

Image

Screenshot showing that the keyboard only allows entering decimals with commas

Image

Code driving the parsing logic
 if (decimal.TryParse(e.NewTextValue, out decimal result))
        {
            resultLabel.Text = $"Parsed value with default culture: {result}";
        }
        else
        {
            resultLabel.Text = "Invalid input";
        }
#if IOS
        var correctedCulture = CultureInfo.CurrentCulture.Clone() as CultureInfo;
        correctedCulture.NumberFormat.NumberDecimalSeparator = NSLocale
            .CurrentLocale
            .DecimalSeparator;
        correctedCulture.NumberFormat.NumberGroupSeparator = NSLocale
            .CurrentLocale
            .GroupingSeparator;

        if (decimal.TryParse(e.NewTextValue, correctedCulture, out decimal result2))
        {
            resultLabel2.Text = $"Parsed value with culture from IOS settings: {result2}";
        }
        else
        {
            resultLabel2.Text = "Invalid input";
        }
#endif
Video showing off behaviour
Screen.Recording.2024-12-04.at.12.14.58.mov

Steps to Reproduce

  1. Open iOS settings -> General -> Language
  2. Set language to English
  3. Set Number Format to 1.234.234,83 (the one which uses comma as a decimal separator)
  4. In a Maui app type in a numeric editor (notice iOS presents only a comma as the decimal separator)
  5. Notice that decimal.Parse treats the comma as a grouping separator

An example repo for parsing can be found here:
https://github.com/LiamMorrow/maui-decimal-repro

Link to public reproduction project repository

https://github.com/LiamMorrow/maui-decimal-repro

Version with bug

9.0.12 SR1.2

Is this a regression from previous behavior?

No, this is something new

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 18

Did you find any workaround?

Cloning the current culture, then using the proper separators in the clone, and setting it as the current culture on app startup does fix this. See this PR for an example.

Relevant log output

Activity

  1. changed the title [-]iOS Numeric Format not Respected[/-] [+]iOS `Numeric Format` setting not respected[/+] on Dec 4, 2024
  2. jfversluis commented on Dec 4, 2024

    @jfversluis
  3. locked and limited conversation to collaborators on Dec 4, 2024
  4. rolfbjarne commented on Dec 5, 2024

    @rolfbjarne
    Member

    This sounds like the default CultureInfo isn't instantiated correctly, which is an issue for dotnet/runtime.

  5. unlocked this conversation on Dec 5, 2024
  6. transferred this issue fromdotnet/mauion Dec 5, 2024
  7. dotnet-policy-service commented on Dec 5, 2024

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @dotnet/area-system-numerics
    See info in area-owners.md if you want to be subscribed.

  8. dotnet-policy-service commented on Dec 5, 2024

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @dotnet/area-system-globalization
    See info in area-owners.md if you want to be subscribed.

  9. 3 remaining items

  10. removed
    untriagedNew issue has not been triaged by the area owner
    on Dec 9, 2024
  11. self-assigned this
    on Dec 9, 2024
  12. added this to the 10.0.0 milestone on Dec 9, 2024
  13. matouskozak commented on Dec 9, 2024

    @matouskozak
    Member

    @LiamMorrow Thanks a lot for the great issue description with concrete examples. I'm able to reproduce the issue, on both .net 8 and .net 9 MAUI apps.

    Do you with which version of .NET it used used to work correctly?

    Anyways, I'll investigate why the CurrentCulture is not set properly with the iOS number format setting.

  14. LiamMorrow commented on Dec 9, 2024

    @LiamMorrow
    Author

    Thanks @matouskozak for looking into it!

    Do you know when was the last time this used to work correctly?

    I have a feeling it has never worked correctly, however iOS 18 has released new keyboards which allow for multi locale keyboards which has probably made it much easier for it to happen. I don't think many users would stray from their default locale's number format otherwise. The user who reported it to me says it started occuring when they switched to the Swedish/English keyboard.

  15. jmacmullin commented on Feb 17, 2025

    @jmacmullin

    Any update on this?

  16. matouskozak commented on Feb 17, 2025

    @matouskozak
    Member

    Any update on this?

    I did an investigation to figure out what the issue is.

    The root cause is that we are using a string locale identifier

    _sWindowsName = GetLocaleNameNative(realNameBuffer);

    to construct the current locale used to retrieve the groupingSeparator and decimalSeparator:

    NSString *locName = [[NSString alloc] initWithUTF8String:localeName];
    NSLocale *currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:locName];

    as such it will always default to the default groupingSeparator and decimalSeparator for the given locale. We would have to always query the device for [NSLocale currentLocale] before retrieving the separators.

    However, I see that very similar approach is used on other ICU platforms

    GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &status);

    and based on my local testing (on macOS), we don't respect the device's setting and instead we use the locale's default. Do you know if this is expected @tarekgh ?

  17. jmacmullin commented on Feb 19, 2025

    @jmacmullin

    @matouskozak where are you getting the value that you use for the string locale identifier? And has this changed recently?

    I was directed at this issue by @jfversluis who closed an issue I opened in the MAUI project where we're observing a change in behaviour between the previous version of MAUI/.net and the latest:
    dotnet/maui#27793

    In that issue I describe (and include a sample project that reproduces the issue) the fact that when running on a device's with the region set to Australia we'd expect MAUI/.net to respect the device's locale and use Australian date formats (dd/mm/yyyy) - and this is what used to happen prior to .net9 and the latest version of MAUI. Now it looks like System.Globalization.CultureInfo.CurrentCulture doesn't reflect the device's settings on iOS - though it does seem to in a console app running on macOS.

    Is this the same underlying issue?

  18. matouskozak commented on Feb 20, 2025

    @matouskozak
    Member

    Is this the same underlying issue?

    The issue you're describing is more likely related to #110704 and the fix will likely be part of the next .NET 9 servicing release. This issue is related specifically to numeric formatting and is present on older MAUI/.net versions as well.

  19. modified the milestones: 10.0.0, 11.0.0 on Jul 8, 2025
  20. matouskozak commented on Jul 13, 2026

    @matouskozak
    Member

    @tarekgh I took a look again at this issue and it appears that on Unix systems we do not respect user overrides and use the default culture setting. Is this an intentional decision? I could add a dedicated apple mobile code to handle this but that would create an inconsistency with macOS. (Note: on Android we don't hit this issue as it doesn't allow to change the decimal separator).

  21. tarekgh commented on Jul 13, 2026

    @tarekgh
    Member

    Right, this isn't really a general "Unix" decision, it's specific to how each OS exposes locale data.

    On Linux (Ubuntu and friends) there is no per-field user override to respect. The locale is selected as a whole through the POSIX environment variables (LC_ALL, LC_NUMERIC, LANG, ...). Even the GNOME "Region & Language -> Formats" option just points those variables at a different complete locale, it does not let a user override an individual field like the decimal separator while keeping the language. ICU then resolves formatting from CLDR for that locale, so there is nothing extra to pick up.

    Apple is different. On iOS/macOS the OS does have real per-field overrides (the "Number Format" setting here maps to NSLocale.DecimalSeparator, NSLocale.GroupingSeparator, etc.), and those are independent of the chosen language. Our ICU based path just doesn't consult them today, which is what this bug is about.

    So adding Apple specific handling would not create an inconsistency with Linux, because Linux has no such setting. It would need to be done for macOS as well so iOS and macOS stay aligned. macOS has the same class of problem tracked in #61148, so we should treat these together rather than special casing iOS on its own.

  22. modified the milestones: 11.0.0, Future on Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions