NumberFormat.parse() échoue pour certains des chaînes de devise
J'ai un simple EditText
, qui permet à l'utilisateur d'entrer un nombre tel que 45.60
(exemple pour le Dollar Américain). J'ai ensuite formater ce nombre à l'aide de la méthode suivante:
public String format() {
NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.getDefault());
return formatter.format(amount.doubleValue());
}
Et sur mon téléphone Android, la langue est l'anglais (États-unis) - d'où le Locale.getDefault()
doit renvoyer le NOUS locale (et il le fait).
Maintenant l'édition de texte est correctement mis à jour à: $45.60
(d'où le formatage du numéro entré œuvres).
Cependant, si je tente d'analyser la au-dessus de la Chaîne de "$45.60"
à l'aide de la méthode suivante:
NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
Number result = numberFormat.parse("$45.60");
Il échoue avec:
java.lang.IllegalArgumentException: Failed to parse amount $45.60 using locale en_US.
Si j'ai mis mon téléphone en anglais/royaume-UNI, la mise en forme de cette "45.60"
à "£45.60"
fonctionne correctement (comme pour NOUS), cependant l'analyse "£45.60"
échoue, comme il le fait pour le dessus de l'échantillon.
Cependant, si j'ai mis mon téléphone à l'allemand (Allemagne), la mise en forme "45,60"
à "45,60€"
fonctionne correctement, ET l'analyse "45,60€"
fonctionne correctement!
La seule différence que je vois entre ces trois devises: L'Euro est ajouté à la quantité, tandis que le Dollar et la Livre sterling sont ajoutés au montant.
Quelqu'un a une idée, pourquoi le même code fonctionne pour l'Euro, mais pas pour la Livre et le Dollar? Ai-je raté quelque chose?
J'ai également créé une unité de test, pour reproduire le problème:
public void testCreateStringBased() throws Exception {
//For German locale
CurrencyAmount amount = new CurrencyAmount("25,46€", Locale.GERMANY);
assertEquals(25.46, amount.getAsDouble());
//For French locale
amount = new CurrencyAmount("25,46€", Locale.FRANCE);
assertEquals(25.46, amount.getAsDouble());
//For US locale
amount = new CurrencyAmount("$25.46", Locale.US);
assertEquals(25.46, amount.getAsDouble());
//For UK locale
amount = new CurrencyAmount("£25.46", Locale.UK);
assertEquals(25.46, amount.getAsDouble());
}
CurrencyAmount
fondamentalement encapsule le code que j'ai posté pour l'analyse des chaînes de devise, sauf qu'il prend la donnée locale au lieu de la locale par défaut. Dans l'exemple ci-dessus, le test réussit pour l'ALLEMAGNE et la FRANCE locale, mais ne parvient pas pour NOUS et le royaume-UNI locale.
OriginalL'auteur AgentKnopf | 2013-03-23
Vous devez vous connecter pour publier un commentaire.
Puisque les réponses qui ont été proposées jusqu'à présent, n'a pas de résoudre complètement le problème, j'ai pris un douloureusement amateur approche:
Alors maintenant, j'ai simplement bande de la Chaîne de valeur à l'arrêt, elle est le symbole de la monnaie " de Cette façon, je peux processus de tout ce que je veux, tels que: 45.78 ou 45,78 ou $45.78 ou 45,78€ ....
Quelle que soit l'entrée, le symbole de la devise est tout simplement dépouillé et je me retrouve avec la plaine numéro. Mon unittests (voir OP) terminer maintenant.
Si quelqu'un arrive avec quelque chose de mieux, s'il vous plaît laissez-moi savoir.
OriginalL'auteur AgentKnopf
Essayer suivantes:
¤ - monnaie signe, s'attend à des matchs avec le symbole de la monnaie Locale.
autre motif de symboles vous pouvez le voir en suivant le lien http://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html
encore une approche: String valeur = "123.5678€".remplacer(nouveau DecimalFormatSymbols(paramètres Régionaux.L'ALLEMAGNE).getCurrencySymbol(), ""); BigDecimal bigDecimal = new BigDecimal(valeur); il est de vous aider à vous ne se soucient pas de la monnaie actuelle symbole
Hey, merci pour cette proposition, c'est à peu près ce que j'ai posté hier 😉 (voir ma propre réponse ci-dessous) et que je suis en train de faire maintenant.
OriginalL'auteur mokshino
Essayer NumberFormat.getCurrencyInstance().parse() au lieu de NumberFormat.getInstance().parse().
C'est une limitation de la Java des routines d'analyse. Pour vos besoins, vous devriez essayer les deux.
Merci pour ces éclaircissements. Néanmoins, dans ce cas, je pense que je suis mieux avec mon simple remplacement du symbole de la devise 🙂 - parce que c'est une chose qui fonctionne pour chacun des cas. Et je trouve ça un peu lourd, si j'ai besoin de deux approches différentes de faire la même chose (analyser une chaîne de devise), juste parce que certaines devises ont précédées du symbole de la monnaie, tandis que d'autres l'ont annexé :/ . Logiquement, il devrait être simple: Une routine pour chaque type de monnaie de l'analyse. Puisque c'est en fonction des paramètres régionaux, qui devrait poser aucun problème, mais malheureusement il n'est pas simple.
OriginalL'auteur Philip Sheard
Vous devez connaître les paramètres régionaux de la chaîne que vous souhaitez analyser dans le but d'avoir un jeu de paramètres régionaux analyseur conscient. Le GBP chaîne analyser numérique UNIQUEMENT lorsque le NumberFormat de la locale fr_fr; il n'y a pas une telle chose comme un "universel" de l'analyseur.
Par exemple, comment fonctionne la chaîne "12.000" parse? Pour fr-us, la réponse est de douze; pour de-de, la réponse est de douze mille.
Toujours utiliser NumberFormat.getCurrencyInstance( java.util.Paramètres régionaux ) pour analyser les montants en devise.
OriginalL'auteur Delfino
Je suis aide-dessous adapté de https://dzone.com/articles/currency-format-validation-and
Si vous avez besoin de s'assurer de la bonne localisation est utilisé par l'utilisateur de regarder
Modifier les paramètres régionaux sur login
OriginalL'auteur melutovich