web-dev-qa-db-fra.com

Comment obtenir un modèle de culture spécifique

Comment puis-je obtenir le modèle de devise pour une culture spécifique?

Par exemple:

À la place d'utiliser:

string.Format("{0:c}", 345.10)

Je veux utiliser ceci:

string.Format("#.##0,00 €;-#.##0,00 €", 345.10);

Mais comment puis-je obtenir la chaîne de motif (comme "#. ## 0,00 €; - #. ## 0,00 €") pour chaque culture dont mon application a besoin?

Je ne peux pas utiliser le modèle "{0: c}" car si l'utilisateur change de langue, la devise doit être la même.

18
naishx

Une CultureInfo contient une NumberFormatInfo et cette classe décrit (entre autres) comment formater la devise pour cette culture particulière.

En particulier, vous pouvez utiliser CurrencyPositivePattern et CurrencyNegativePattern pour déterminer si le symbole monétaire est placé avant ou après le montant et bien sûr CurrencySymbol pour obtenir le symbole monétaire correct. Toutes ces informations sont utilisées par .NET lorsque le spécificateur de format C est utilisé.

Vous pouvez en savoir plus sur la classe NumberFormatInfo sur MSDN.

Le code ci-dessous illustre certaines des étapes requises pour formater correctement la devise. Il utilise uniquement CurrencySymbol, CurrencyPositivePattern et CurrencyDecimalDigits et est donc incomplet:

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);

Bien sûr, vous pouvez simplement utiliser:

var amount = 123.45M;
var cultureInfo = CultureInfo.GetCultureInfo("da-DK");
var formattedAmount = String.Format(cultureInfo, "{0:C}", amount);
Console.WriteLine(formattedAmount);
20
Martin Liversage

Je pense que ce que vous demandez, c'est comment changer le symbole monétaire tout en conservant le formatage spécifique à la culture. Vous pouvez le faire en obtenant une copie de la NumberFormatInfo actuelle et en modifiant la propriété 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));

Cela produira:

345,10 $$$

Sans changer la CurrentCulture, il génère (pour moi):

$$$345.10
11
porges

Une approche rapide et incorrecte qui fonctionne pour tous les formats de nombres est la suivante:

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;

Dans ce cas, le motif est égal à "#. ## 0,00 €; - #. ## 0,00 €". Cela évite beaucoup de maux de tête en essayant de comprendre toutes les permutations. J'apprécie la question posée, car cela m'a aidé et m'a obligé à trouver une réponse plus facile.

3
Jamie Thomas

Avez-vous essayé d'utiliser string.Format("{0:N2} €", 345.10)? Cela devrait être formaté à deux décimales près dans la culture de l'utilisateur, suivi d'un espace et du symbole de l'euro.

2
detaylor

Le test ci-dessous montre comment vous pouvez y parvenir:

    [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));
    }

En utilisant la notation décimale standard de la culture actuellement sélectionnée, vous pouvez afficher toute valeur donnée en ignorant la devise, que vous pouvez traiter séparément.

1
Ioannis Karadimas

Vous devez formater votre devise/double en utilisant:

money.ToString("C", culture);

Le plus difficile est d’obtenir la bonne culture en fonction du code ISO. Je ne sais pas comment vous suivez la culture dont vous avez besoin. Gardez à l'esprit qu'il s'agit simplement du formatage de votre argent, pas conversion en différentes monnaies/cultures!

Plus de détails:

ISOCurrencySymbol fait partie de RegionInfo, que vous pouvez créer à partir de CultureInfo, que vous pouvez extraire des paramètres de culture de votre thread actuel. Vous devez créer un singleton qui implémente un dictionnaire pour convertir ISOCurrencyCode en CultureInfo.

0
Jaapjan