I read about NSLocaleCurrencySymbol, but where would I find the variable used to determine the "number of decimal places" used in a country's currency?
I.E. In the USA, it's common to see dollar amounts written with 2 decimal places: $1.23
What about many other countries?
There are a number of other countries that display a different number of decimal places. 2 is the majority, 0 (no cents in their currency, e.g., Japan) is the largest minority, 3 is used in just a few. No other number that I know off. When exchange rates are quoted, more decimals are typically used. The currencies with 0 and 3 that I'm aware of are shown below.
The ISO currency codes can be found at: http://www.iso.org/iso/support/currency_codes_list-1.htm http://en.wikipedia.org/wiki/ISO_4217 or http://www.currency-iso.org/en/home/tables/table-a1.html.
ISO Code Currency Decimal places
ADP Andoran Peseta 0
AFA Afghani Afghani 0
BEF Belgian franc 0
BHD Bahraini dinar 3
BIF Burundi franc 0
BYB Belorussian rubel (old) 0
BYR Belorussian rubel (new) 0
CLP Chilean peso 0
COP Colombian peso 0
DJF Djibouti franc 0
ECS Ecuadorian sucre 0
ESP Spanish peseta 0
GNF Guinea franc 0
GRD Greek drachma 0
HUF Hungarian forint 0
IDR Indonesian rupiah 0
IQD Iraqui dinar 3
ITL Italian lira 0
JOD Jordan dinar 3
JPY Japanese yen 0
KMF Comoros franc 0
KRW South Korean won 0
KWD Kuwaiti dinar 3
LAK Laos new kip 0
LUF Luxembourg franc 0
LYD Libyan dinar 3
MGF Madagascan franc 0
MZM Mozambique metical 0
OMR Omani rial 3
PTE Portugese escudo 0
PYG Paraguay guarani 0
ROL Roumanian Lei 0
RWF Rwanda franc 0
TJR Tadzhikistani rubel 0
TMM Turkmenistani manat 0
TND Tunesian dinar 3
TPE Timor escudo 0
TRL Turkish lira 0
TWD New Taiwan dollar 0
UGX Uganda shilling 0
VND Vietnamese dong 0
VUV Vanuata vatu 0
XAF CFA Franc BEAC 0
XOF CFA Franc BCEAO 0
XPF CFP Franc 0
In iOS 6 (and possibly earlier) you can find out the number of digits after the decimal place of a currency from the minimumFractionDigits property of an NSNumberFormatter set to the correct locale:
void (^currency_test)(NSString *) = ^(NSString *locale) { NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:locale]]; [formatter setNumberStyle:NSNumberFormatterCurrencyStyle]; NSLog(@"%@: %@ (minimumFractionDigits = %d)", locale, [formatter stringFromNumber:@(1000)], [formatter minimumFractionDigits]); }; currency_test(@"en_US"); currency_test(@"nl_NL"); currency_test(@"de_DE"); currency_test(@"fr_FR"); currency_test(@"jp_JP"); currency_test(@"ar_JO"); en_US: $1,000.00 (minimumFractionDigits = 2) nl_NL: € 1.000,00 (minimumFractionDigits = 2) de_DE: 1.000,00 € (minimumFractionDigits = 2) jp_JP: ¥ 1000 (minimumFractionDigits = 0) ar_JO: ١٠٠٠٫٠٠٠ د.أ. (minimumFractionDigits = 3)
Note that you must call [formatter setNumberStyle:NSNumberFormatterCurrencyStyle] before the minimumFractionDigits property is populated with the correct value (that one only took me half an hour to work out!)
This has much of what you're looking for.
Bulding on Robert Atkins' answer, it is possible to do the same thing on .NET. To test this code, create a Console App project and replace Program.cs with this:
using System;
using System.Globalization;
using System.Linq;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
decimal amount = 100.123M;
Console.WriteLine(GetNumberOfDecimales("USD", 2)); // 2
Console.WriteLine(GetNumberOfDecimales("EUR", 2)); // 2
Console.WriteLine(GetNumberOfDecimales("JPY", 2)); // 0
Console.WriteLine(GetNumberOfDecimales("BHD", 2)); // 3
Console.WriteLine(GetNumberOfDecimales("___", 2)); // 2
Console.WriteLine(LocalizeAmount(amount, "USD")); // 100.12
Console.WriteLine(LocalizeAmount(amount, "EUR")); // 100.12
Console.WriteLine(LocalizeAmount(amount, "JPY")); // 100
Console.WriteLine(LocalizeAmount(amount, "BHD")); // 100.123
Console.WriteLine(LocalizeAmount(amount, "___")); // 100.12
}
/// <summary>
///
/// Returns an amount with the correct number of decimals for the given currency.
/// The amount is rounded.
///
/// Ex.:
/// 100.555 JPY => 101
/// 100.555 USD => 100.56
///
/// </summary>
static public string LocalizeAmount(decimal amount, string currencyCode)
{
var formatString = String.Concat("{0:F", GetNumberOfDecimales(currencyCode, 2), "}"); // {0:F2} for example
return String.Format(formatString, amount);
}
/// <summary>
///
/// Returns the number of decimal places for a currency.
///
/// Ex.:
/// JPY => 0
/// USD => 2
///
/// </summary>
static public int GetNumberOfDecimales(string currencyCode, int defaultValue = 2)
{
var cultureInfo = GetFirstCultureInfoByCurrencySymbol(currencyCode);
return cultureInfo?.NumberFormat?.CurrencyDecimalDigits ?? defaultValue;
}
static private CultureInfo GetFirstCultureInfoByCurrencySymbol(string currencySymbol)
{
if (string.IsNullOrWhiteSpace(currencySymbol))
throw new ArgumentNullException("A valid currency must be provided.");
return CultureInfo.GetCultures(CultureTypes.SpecificCultures)
.FirstOrDefault(x => new RegionInfo(x.LCID).ISOCurrencySymbol == currencySymbol);
}
}
}
来源:https://stackoverflow.com/questions/2701301/various-countrys-currency-decimal-places-width-in-the-iphone-sdk