If you are selling goods in multiple markets which same currency but with different languages, such as EuroZone, you might notice that while everything looks quite good, except that the thousand separator might be off from time to time: it is always the same and does not change to match with the language, so sometimes it’s correct, sometimes it’s not.
Let’s take a step back to see how to properly show the thousand delimiter
In the United States, this character is a comma (,). In Germany, it is a period (.). Thus one thousand and twenty-five is displayed as 1,025 in the United States and 1.025 in Germany. In Sweden, the thousands separator is a space.https://docs.microsoft.com/en-us/globalization/locale/number-formatting
You might ask why the problem happens with Episerver Commerce. In Commerce, each currency has an attached
NumberFormatInfo which let the framework knows how to format the currency. During startup, the system will loop through the available
CultureInfo and assign its
.NumberFormat to the currency.
The problem is there might be multiple
CultureInfo that can handle same currency, for example,
EUR which is used across Eurozone, can be handled by multiple (20? ) cultures. However, the first matching
CultureInfo to handle the format of the currency will be used. In most of the cases, it will be
br-FR (because the
CultureInfo(s) are sorted by name, and this
CultureInfo is the first in the list to handle
br-FR does not have a thousand separator, but a whitespace. That’s why even if your language is
de-DE, the amount in
EUR will not be properly formatted as
How to fix that problem?
Luckily, we can set the
NumberFormatInfo attached for each currency. If you are only selling in Germany, you can make sure that
EUR is always formatted in German style, by adding this to one of your initialization modules:
var culture = CultureInfo.GetCultureInfo("de-DE");
But if you have multiple languages for one currency, this will simply not work (because it’s static, so it will affect all customer). Your only option is to avoid using
Money.ToString(), but to use
Money.ToString(IFormatProvider), for example
CultureInfo.CurrentUiCulture is set to correct one.
This, however, does not resolve the problem with merchandisers using Commerce Manager. They might have to work with orders from multiple markets, and for example, if your site is selling good stuffs in Europe, there are chances that merchandisers see the prices without correct thousand separator. Most of places in Commerce Manager uses
Money.ToString(), and there is a reason for that: it’s too risky to use
Money.ToString(CultureInfo.CurrentUICulture), because if a merchandiser uses English, he or she is likely gonna see money formatted as “$” instead of “€”, and that is a much bigger problem of itself.
Moral of the story: localization is hard, and sometimes a compromise is needed.