Code:
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de");
string text = string.Format("{0:c}", 100);
Expected value for text variable: "100,00 €"
but in .net 5 runtime we see "100,00 ¤".
.NETCore 5 - text[7] | 164 '¤'
.NET 4.8 - text[7] | 8364 '€'
.NETCore 3.1 - text[7] | 8364 '€'
5.0.100-preview.5.20279.10
OS Version: 10.0.18362 N/A Build 18362
For netcoreapp3.1 / .NET 4.8:
Code:
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de");
string text = string.Format("{0:c}", 100);
Text - "100,00 €"
Tagging subscribers to this area: @tarekgh, @safern, @krwq
Notify danmosemsft if you want to be subscribed.
Repros on my box as well running Win10 19041. Also confirmed that setting the environment variable DOTNET_SYSTEM_GLOBALIZATION_USENLS=1 fixes the regression. So it's definitely related to the NLS / ICU conversion.
This is by design. CLDR data having the international currency symbol associated to "de" culture. that makes sense because this is a parent culture to other cultures that have currency different than the euro. Windows data looks not updated to that for compatibility reason.
de, German, ¤
de-AT, German (Austria), €
de-BE, German (Belgium), €
de-CH, German (Switzerland), CHF
de-DE, German (Germany), €
de-IT, German (Italy), €
de-LI, German (Liechtenstein), CHF
de-LU, German (Luxembourg), €
if you want to get back to Windows behavior you have the option to use the config switch to do that.
CC @@jefgen
https://github.com/dotnet/runtime/issues/37743
Thanks for the CC @tarekgh!
I just wanted to add a bit and/or expand on what Tarek has already said.
In both CLDR and ICU the design is that a "currency" is a property of a country or region, not a language. Thus, if there is no country/region in the locale name or locale tag, the design is to give back an empty string in many cases. For example, the API ucurr_forLocale will give empty string.
(Another way to look at this design is to consider asking the question "What is the currency for 'English'?". There isn't really any "good" answer so the design is to give back empty string to indicate as such.)
Regarding this:
Windows data looks not updated to that
Note that there isn't really anything that can be done in terms of patching or changing the data for ICU on Windows for this though.
It might be possible to try and make code changes to individual ICU APIs (in Windows) in order to add some special case logic (for example, ucurr_forLocale).
However, there are many problems with this idea. First is that this would be error prone and would be at best ad-hoc. There are a number of APIs that might need changing and some aren't easy to change. We'd also need to decide which currency to give back for each language (and keep it updated). However, what's worse though, is that this would also be changing the overall design of the APIs in ICU on Windows (compared to other platforms) -- which is something that we want to very much avoid.
[CC @daniel-ju and @axelandrejs as FYI].
Most helpful comment
Thanks for the CC @tarekgh!
I just wanted to add a bit and/or expand on what Tarek has already said.
In both CLDR and ICU the design is that a "currency" is a property of a country or region, not a language. Thus, if there is no country/region in the locale name or locale tag, the design is to give back an empty string in many cases. For example, the API
ucurr_forLocalewill give empty string.(Another way to look at this design is to consider asking the question "What is the currency for 'English'?". There isn't really any "good" answer so the design is to give back empty string to indicate as such.)
Regarding this:
Note that there isn't really anything that can be done in terms of patching or changing the data for ICU on Windows for this though.
It might be possible to try and make code changes to individual ICU APIs (in Windows) in order to add some special case logic (for example,
ucurr_forLocale).However, there are many problems with this idea. First is that this would be error prone and would be at best ad-hoc. There are a number of APIs that might need changing and some aren't easy to change. We'd also need to decide which currency to give back for each language (and keep it updated). However, what's worse though, is that this would also be changing the overall design of the APIs in ICU on Windows (compared to other platforms) -- which is something that we want to very much avoid.
[CC @daniel-ju and @axelandrejs as FYI].