Search code examples
.netlocalizationcurrency

Why does .NET currency format include a currency symbol?


This code: Console.Out.WriteLine(string.Format(CultureInfo.GetCultureInfo("hu-HU"), "{0:C}", 1234.56M)) will produce the following output: 1 234,56 Ft, which is technically correct, but how does it come to guess the currency??

This behaviour means that simply changing display culture from hu-HU to en-US will multiply the value with more than 200, depending on the current rates. You would never make the mistake of billing 500 HUF insted of 500 USD. Obvious.

The only "nice" way of setting the currency is cloning the desired culture and setting the currency symbol:

var format = NumberFormatInfo.GetInstance(CultureInfo.GetCultureInfo("en-US")).Clone() as NumberFormatInfo;
format.CurrencySymbol = "asd";
Console.Out.WriteLine(string.Format(format, "{0:C}", 1234.56M));

This works correct producing asd1,234.56, but so much cumbersome.

My questions are:

  1. What is the ratio behind defaulting to a national currency in this global world we have been living in for decades?
  2. How come there is no way of specifying the amount and the currency in a more related manner since they are so much coupled?
  3. Bonus: if I use sk-SK for culture, I get euros for "default" currency. If I change to Framework 2.0 I should get Sk (for Slovak koruna) since in 2005 it was the national currency. (Well, it does not happen. But I haven't tried it on any system that has no later than 2.0.)

UPDATE: Conclusions:

  1. Defaulting currency from culture is all normal for some, strange for others (including me)
  2. There is no 'money amount' type as there are no types for length, weight, and so on, where is the limit? Virtlink created a library for this: M42 Financial

Solution

  • I changed my mind: I agree with you that it is strange that the currency is part of the culture.

    It is not common in .NET and Java to specify the unit with a value. You generally don't specify a temperature, a distance or a currency with a unit. For most intents and purposes the unit is assumed by the developer: meters for distance and Celsius for temperature. There is no default unit of distance or unit of temperature specified in .NET for a given culture.

    To be consistent, the .NET Framework should also not have added currency information to a culture. Most people deal with more than one currency, and some countries even accept multiple currencies. Not everyone of a given culture will use one and only one currency.

    The .NET framework contains a System.Currency class but it is hidden (internal), and only used for the Decimal.ToOACurrency() method. It isn't really useful either. Java contains a Currency class since 2002, but as the .NET Framework was created in 2000 and many design mistakes were copied from Java, this may be one of them. However, I couldn't find information on whether the Java Locale class contains (or contained) any currency information, and I'm not psychic.

    Well, continuing from the idea that units are never specified in .NET and there should not have been a default currency for a culture, then where should they have put the currency unit of a monetary value? They should have created a Currency class, of course.