特定の文化の通貨パターンを取得するにはどうすればよいですか?
例えば:
代わりに:
string.Format("{0:c}", 345.10)
これを使いたい:
string.Format("#.##0,00 €;-#.##0,00 €", 345.10);
しかし、アプリケーションが必要とする各カルチャのパターン文字列( "#。## 0,00€;-#。## 0,00€"など)を取得するにはどうすればよいですか?
「{0:c}」パターンは使用できません。ユーザーが言語を切り替えた場合、通貨は同じになるはずです。
CultureInfo
にはNumberFormatInfo
が含まれており、このクラスは(特に)特定のカルチャの通貨をフォーマットする方法を記述します。
特に、CurrencyPositivePattern
とCurrencyNegativePattern
を使用して、通貨記号が金額の前または後に配置されているかどうかを判断し、もちろんCurrencySymbol
を使用して正しい通貨記号を取得できます。このすべての情報は、C
形式指定子が使用されているときに.NETによって使用されます。
MSDNで NumberFormatInfoクラス の詳細を読むことができます。
以下のコードは、通貨を適切にフォーマットするために必要な手順の一部を示しています。 CurrencySymbol
、CurrencyPositivePattern
およびCurrencyDecimalDigits
のみを使用するため、不完全です。
var amount = 123.45M;
var cultureInfo = CultureInfo.GetCultureInfo("da-DK");
var numberFormat = cultureInfo.NumberFormat;
String formattedAmount = null;
if (amount >= Decimal.Zero) {
String pattern = null;
switch (numberFormat.CurrencyPositivePattern) {
case 0:
pattern = "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 1:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}";
break;
case 2:
pattern = "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 3:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}";
break;
}
formattedAmount = String.Format(cultureInfo, pattern, numberFormat.CurrencySymbol, amount);
}
else {
// ...
}
Console.WriteLine(formattedAmount);
もちろん、次のように簡単に使用できます。
var amount = 123.45M;
var cultureInfo = CultureInfo.GetCultureInfo("da-DK");
var formattedAmount = String.Format(cultureInfo, "{0:C}", amount);
Console.WriteLine(formattedAmount);
私はあなたが求めているのは、通貨記号を変更する方法ですが、文化固有のフォーマットを維持することだと思います。これを行うには、現在のNumberFormatInfo
のコピーを取得し、CurrencySymbol
プロパティを変更します。
Thread.CurrentThread.CurrentCulture = new CultureInfo("de");
// pretend we are german
var nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
nfi.CurrencySymbol = "$$$";
Console.WriteLine(string.Format(nfi,"{0:c}",345.10));
これは出力します:
345,10 $$$
CurrentCulture
を変更せずに出力します(私にとって):
$$$345.10
すべての数値形式で機能する迅速で汚いアプローチは次のとおりです。
var culture = CultureInfo.GetCultureInfo("el-GR");
var numberFormat = (NumberFormatInfo)culture.NumberFormat.Clone();
numberFormat.CurrencySymbol = "€"; // Force the currency symbol regardless of culture
var specifier = "C"; // Or any other format specifier
var positivePattern = 1110.ToString(specifier, numberFormat).Replace('1', '#');
var negativePattern = (-1110).ToString(specifier, numberFormat).Replace('1', '#');
var pattern = positivePattern + ";" + negativePattern;
この場合、パターンは「#。## 0,00€;-#。## 0,00€」に等しくなります。これにより、すべての順列を把握しようとする多くの頭痛の種が回避されます。質問のおかげで、より簡単な答えを見つけるのに役立ち、強制されました。
string.Format("{0:N2} €", 345.10)
を使用してみましたか?これは、ユーザーカルチャの小数点以下2桁にフォーマットされ、その後にスペースとユーロ記号が続きます。
あなたはあなたの通貨/ダブルをフォーマットする必要があります:
money.ToString("C", culture);
難しいのは、実際にはISOコードに基づいて適切なカルチャを取得することです。必要な文化をどのように追跡しているかはわかりません。これは単にあなたのお金のformattingであり、異なる通貨/文化へのconversionではないことに注意してください!
もっと詳しく:
ISOCurrencySymbolは、現在のスレッドのカルチャ設定から取得できるCultureInfoに基づいて作成できるRegionInfoの一部です。 ISOCurrencyCodeからCultureInfoに変換するディクショナリを実装するシングルトンを作成する必要があります。
以下のテストは、これを実現する方法を示しています。
[Test]
public void DisplayEurosInGreeceAndEngland()
{
var val = 125.22m;
Thread.CurrentThread.CurrentCulture
= Thread.CurrentThread.CurrentUICulture
= new CultureInfo("el-GR");
Console.WriteLine(string.Format("{0:n} €", val));
Thread.CurrentThread.CurrentCulture
= Thread.CurrentThread.CurrentUICulture
= new CultureInfo("en-GB");
Console.WriteLine(string.Format("{0:n} €", val));
}
現在選択されているカルチャからの標準の10進表記を使用することにより、通貨をスキップして任意の値を表示できます。これは個別に処理できます。
正と負の数の場合、文化のコードスニペットの下を使用できます
class Program
{
static void Main(string[] args)
{
List<string> cultures = new List<string> { "ca-ES", "co-FR", "cs-CZ", "cy-GB", "da-DK", "de-AT", "de-CH", "de-DE", "de-LI", "de-LU", "dsb-DE", "en-US", "en-GB" };
var amount = -16.34M;
foreach (var c in cultures)
{
var cultureInfo = CultureInfo.GetCultureInfo(c);
var numberFormat = cultureInfo.NumberFormat;
String formattedAmount = null;
if (amount >= Decimal.Zero)
{
String pattern = null;
switch (numberFormat.CurrencyPositivePattern)
{
case 0:
pattern = "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 1:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}";
break;
case 2:
pattern = "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 3:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}";
break;
}
formattedAmount = String.Format(cultureInfo, pattern, numberFormat.CurrencySymbol, amount);
}
else if (amount < Decimal.Zero)
{
String pattern = null;
switch (numberFormat.CurrencyNegativePattern)
{
case 0:
pattern = "({0}{1:N" + numberFormat.CurrencyDecimalDigits + "})";
break;
case 1:
pattern = numberFormat.NegativeSign + "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 2:
pattern = "{0}" + numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 3:
pattern = "{0}{1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign;
break;
case 4:
pattern = "({1:N" + numberFormat.CurrencyDecimalDigits + "}{0})";
break;
case 5:
pattern = numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}";
break;
case 6:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign + "{0}";
break;
case 7:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}{0}" + numberFormat.NegativeSign;
break;
case 8:
pattern = numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}";
break;
case 9:
pattern = numberFormat.NegativeSign + "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 10:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "} {0}" + numberFormat.NegativeSign;
break;
case 11:
pattern = "{0} {1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign;
break;
case 12:
pattern = "{0}" + " " + numberFormat.NegativeSign + "{1:N" + numberFormat.CurrencyDecimalDigits + "}";
break;
case 13:
pattern = "{1:N" + numberFormat.CurrencyDecimalDigits + "}" + numberFormat.NegativeSign + " " + "{0}";
break;
case 14:
pattern = "({0} {1:N" + numberFormat.CurrencyDecimalDigits + "})";
break;
case 15:
pattern = "({1:N" + numberFormat.CurrencyDecimalDigits + "} {0})";
break;
}
formattedAmount = String.Format(cultureInfo, pattern, numberFormat.CurrencySymbol, amount * -1);
}
Console.WriteLine(formattedAmount);
}
Console.ReadKey();
}
}