Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Ne jamais, jamais bricoler son parseur de valeurs monétaires

Poster un commentaire

Je viens de déboguer chez un client cette étrange méthode:

  1. private string CleanPriceInput(string target)
  2. {
  3.  if (string.IsNullOrWhiteSpace(target))
  4.  {
  5.          return string.Empty;
  6.  }
  7.  string retour = target.Split(‘,’)[0].Split(‘.’)[0].Replace(« € », «  »).Trim();
  8.  return retour;

Qui est un nid de bugs.

D’abord vous remarquez qu’elle ne « marche » que pour les euros et les pays où le séparateur décimal monétaire est un point ou une virgule. C’est tout de même mieux de faire des choses génériques lorsque ça tourne pas à l’usine.

Et puis de toute façon ça ne marche pas parce que même dans les bons pays, les décimales disparaissent systématiquement.

Alors mettons de l’ordre dans tout cela et découvrons ensemble que cette procédure qui ne marche pas est de toute façon largement inutile.

conversion numérique vers string

// culture: fr-FR

double prix = 49.5639;

string px = string.Format(« {0:C} », prix);

Affichage: 49,56 €

Notre valeur numérique est formatée correctement comme l’attend la culture en cours (ici la France). Les 4 décimales sont arrondies à deux en particulier.

Regardez le format passé à Format: {0:C}. On reconnaît notre placeholder habituel, mais il est en outre décoré de C. Cette syntaxe est celle d’un expression builder. Il est possible de créer des expressions personnalisées.

En attendant retenez une deuxième qui peut être utile:

string px = string.Format(« {0:N} », prix);

Qui affiche 49,56 (sans le symbole monétaire, mais avec le formatage).

D’un point de vue du code il est préférable de manipuler les valeurs numériques sous la forme d’un décimal. La précision sera meilleure et c’est justement fait pour celà:

// culture: fr-FR

decimal prix = 49.5639m;

string px = string.Format(« {0:C} », prix);

Conversion string vers numérique

D’abord si vous avez besoin de retrouver le symbole monétaire: CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol

Quand au séparateur décimal dans une expression monétaire: CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator

Mais on ne va pas avoir besoin de tout cela. En fait je déconseille fortement de bricoler soi même un parseur, c’est inutile car .Net le fournit déjà.

Regardez cette situation:

  1. // culture: fr-FR
  2. string prix = « 49,56 € »;
  3. decimal val;
  4. bool test = decimal.TryParse(prix, NumberStyles.Number | NumberStyles.AllowCurrencySymbol, CultureInfo.CurrentCulture, out val);

val contient 49.56 comme prévu. Comme on le voit la suppression par code du symbole monétaire est sans intérêt.

Oui mais allez vous me dire, en France des tas de gens utilisent le point là où la virgule est demandée. Evidemment, pas de méthodes miracles, on devra bien transformer le point en virgule.

La façon générique et correcte de faire cela est:

// culture: fr-FR

string prix = « 49.56 € »; prix = prix.Replace(« . », CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator);

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s