-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[iOS] Set CurrentCulture locale to specific format based on system default when possible #111032
base: main
Are you sure you want to change the base?
Conversation
Tagging subscribers to this area: @dotnet/area-system-globalization |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 1 out of 2 changed files in this pull request and generated no comments.
Files not reviewed (1)
- src/native/libs/System.Globalization.Native/pal_locale.m: Language not supported
/azp run runtime-ioslike,runtime-ioslikesimulator,runtime-maccatalyst |
Azure Pipelines successfully started running 3 pipeline(s). |
static NSString* GetBaseName(NSString *localeIdentifier) | ||
{ | ||
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier]; | ||
NSString *languageCode = [locale objectForKey:NSLocaleLanguageCode]; | ||
return languageCode; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know what this was done before?
The PR description should be updated to describe this - what we did before (has that) and why, and what we're changing it to (and why it's OK to change given the previous reasoning).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, I was trying this PR to see which test suit breaks if we switch to specific name because there are other dependencies such as SqlStrings
that were previously affected. I'll update the issue description when I finalize the code changes.
Brief history what I found:
- The switch to neutral locale names was done in [ios][HybridGlobalization] Fix default culture #104071
- In that PR, there was an assumption that our ICU also returns just neutral locale name. However, that isn't true as the ICU
uloc_getBaseName
uloc_getBaseName(defaultLocale, localeNameBuffer, ULOC_FULLNAME_CAPACITY, &status); - The problem with using Apple's system default locale is that if it's not part of https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Globalization/IcuLocaleData.cs (e.g., en-CZ), the culture LCID number is 0x1000 (
LOCALE_CUSTOM_UNSPECIFIED
). While it seems that using LCID number to create new cultures is not recommended and using culture name is preferred, e.g.,SqlString
implementation still relies on using it, thus when LCID doesn't match with valid culture it causes failures when using someCultureInfo
APIs, e.g.,runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs
Line 993 in 94c356d
public static CultureInfo GetCultureInfo(int culture)
I'll try to make a middle way out of this, where we use system locale if it's recognized by .NET, otherwise we use parent culture which is neutral.
/azp run runtime-ioslike,runtime-ioslikesimulator,runtime-maccatalyst |
Azure Pipelines successfully started running 3 pipeline(s). |
/azp run runtime-ioslike,runtime-ioslikesimulator,runtime-maccatalyst |
Azure Pipelines successfully started running 3 pipeline(s). |
I don't think we need to fix this. We encourage users to move away from LCIDs. Any users still using LCID should start migrating to use culture names instead. The change here is trying to work around the issue of using the parent which may benefit using the LCID but it can cause other issues when requesting any region-specific data from current culture. This issue is not specific to iOS or mobile platforms. This can occur on Windows for example doing Last, if |
@tarekgh I know that using LCID is not recommended. What I was trying to work around here by using the parent is that any default culture set by .NET would be compatible with all .NET libraries code. We are currently relying on LCID inside Note, this PR not only does the fallback to parent culture but also fixes the behavior that we didn't return specific system culture. I can remove the parent culture workaround and disable the failing tests until the affected library code migrates from LCID. However, because we need to backport this fix to .NET 9, we could be risking a breaking change to some customers using e.g., |
I think the right thing to do is have SqlString get fixed. Either they migrate to use the culture name or to be tolerant to do the fallback themselves. As I mentioned, this issue is not specific to iOS. What happens if someone sets
I am fine with the change in |
Problem Description
On iOS (and other apple mobile platforms), we are taking the system default culture and using it inside .NET as
CultureInfo.CurrentCulture
.Currently, the system default culture is truncated into neutral culture format (only language). This behavior was set in #104071, where we had an incorrect assumption that other ICU platforms also return just neutral locale name. However, that isn't true because the ICU
uloc_getBaseName
runtime/src/native/libs/System.Globalization.Native/pal_locale.c
Line 232 in 117c4ab
The problem of using all Apple's system default locales is that some of the retrieved identifiers are not part of https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Globalization/IcuLocaleData.cs (e.g., en-CZ), causing the culture LCID number to be 0x1000 (
LOCALE_CUSTOM_UNSPECIFIED
). This can cause issues where the defaultCultureInfo.CurrentCulture
causes crashes when using certainCultureInfo
APIs that accept LCID instead of culture name, such as,runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs
Line 993 in 94c356d
used by e.g.
SqlString
.Proposed Change
This PR reverts the previous change and preserves the full (specific = language-region) culture locale format when the retrieved locale is part of
IcuLocaleData.cs
. Upon retrieving the system locale name, we verify that the culture name is part of the ICU data and if not, we use the parent culture (neutral) instead.A test was added to
CurrentCultureTests
to assert that the defaultCultureInfo.CurrentCulture
is never a custom type.Previous behavior (.net 9):
CurrentCulture
en-US
en
en-CZ
en
New behavior:
CurrentCulture
en-US
en-US
en-CZ
en
This PR addresses the following issues: