Repository navigation
iOS Numeric Format setting not respected #110430
Description
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.
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
- Open iOS settings -> General -> Language
- Set language to English
- Set Number Format to 1.234.234,83 (the one which uses comma as a decimal separator)
- In a Maui app type in a numeric editor (notice iOS presents only a comma as the decimal separator)
- 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.


Activity
[-]iOS Numeric Format not Respected[/-][+]iOS `Numeric Format` setting not respected[/+]jfversluis commentedon Dec 4, 2024
rolfbjarne commentedon Dec 5, 2024
This sounds like the default CultureInfo isn't instantiated correctly, which is an issue for dotnet/runtime.
dotnet-policy-service commentedon Dec 5, 2024
Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.
dotnet-policy-service commentedon Dec 5, 2024
Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.
3 remaining items
matouskozak commentedon Dec 9, 2024
@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
CurrentCultureis not set properly with the iOS number format setting.LiamMorrow commentedon Dec 9, 2024
Thanks @matouskozak for looking into it!
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.
jmacmullin commentedon Feb 17, 2025
Any update on this?
matouskozak commentedon Feb 17, 2025
I did an investigation to figure out what the issue is.
The root cause is that we are using a string locale identifier
runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Icu.cs
Line 126 in 69c8a1d
to construct the current locale used to retrieve the
groupingSeparatoranddecimalSeparator:runtime/src/native/libs/System.Globalization.Native/pal_locale.m
Lines 142 to 143 in ea63985
as such it will always default to the default
groupingSeparatoranddecimalSeparatorfor 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
runtime/src/native/libs/System.Globalization.Native/pal_localeStringData.c
Line 224 in eafd523
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 ?
jmacmullin commentedon Feb 19, 2025
@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.CurrentCulturedoesn'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?
matouskozak commentedon Feb 20, 2025
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.
matouskozak commentedon Jul 13, 2026
@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).
tarekgh commentedon Jul 13, 2026
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.