Question

Voici mon problème (pour en-US):

Decimal.Parse ("1,2,3,4") renvoie 1234 au lieu de générer une exception InvalidFormatException.

La plupart des applications Windows (Excel en-US) ne suppriment pas les séparateurs de milliers et ne considèrent pas cette valeur comme un nombre décimal. Le même problème se produit pour d'autres langues (bien qu'avec des caractères différents).

Existe-t-il d'autres bibliothèques d'analyse décimale permettant de résoudre ce problème?

Merci!

Était-ce utile?

La solution 2

J'ai fini par écrire le code pour vérifier la devise manuellement. Personnellement, pour un framework qui se targue d’avoir intégré tous les éléments de la mondialisation, il est étonnant que .NET n’ait rien à faire.

Ma solution est ci-dessous. Cela fonctionne pour tous les paramètres régionaux du framework. Il ne prend pas en charge les nombres négatifs, comme Orion l’a souligné ci-dessous. Qu'en pensez-vous?

    public static bool TryParseCurrency(string value, out decimal result)
    {
        result = 0;
        const int maxCount = 100;
        if (String.IsNullOrEmpty(value))
            return false;

        const string decimalNumberPattern = @"^\-?[0-9]{{1,{4}}}(\{0}[0-9]{{{2}}})*(\{0}[0-9]{{{3}}})*(\{1}[0-9]+)*
    [Test]
    public void TestCurrencyStrictParsingInAllLocales()
    {
        var originalCulture = CultureInfo.CurrentCulture;
        var cultures = CultureInfo.GetCultures(CultureTypes.SpecificCultures);
        const decimal originalNumber = 12345678.98m;
        foreach(var culture in cultures)
        {
            var stringValue = originalNumber.ToCurrencyWithoutSymbolFormat();
            decimal resultNumber = 0;
            Assert.IsTrue(DecimalUtils.TryParseCurrency(stringValue, out resultNumber));
            Assert.AreEqual(originalNumber, resultNumber);
        }
        System.Threading.Thread.CurrentThread.CurrentCulture = originalCulture;

    }
quot;; NumberFormatInfo format = CultureInfo.CurrentCulture.NumberFormat; int secondaryGroupSize = format.CurrencyGroupSizes.Length > 1 ? format.CurrencyGroupSizes[1] : format.CurrencyGroupSizes[0]; var r = new Regex(String.Format(decimalNumberPattern , format.CurrencyGroupSeparator==" " ? "s" : format.CurrencyGroupSeparator , format.CurrencyDecimalSeparator , secondaryGroupSize , format.CurrencyGroupSizes[0] , maxCount), RegexOptions.Compiled | RegexOptions.CultureInvariant); return !r.IsMatch(value.Trim()) ? false : Decimal.TryParse(value, NumberStyles.Any, CultureInfo.CurrentCulture, out result); }

Et voici un test pour le voir fonctionner (nUnit):

<*>

Autres conseils

Cela autorise des milliers de dollars, car la valeur par défaut NumberStyles utilisée par Decimal.Parse ( NumberStyles.Number ) inclut NumberStyles.AllowThousands. .

Si vous souhaitez interdire les séparateurs de milliers, vous pouvez simplement supprimer cet indicateur, comme ceci:

Decimal.Parse("1,2,3,4", NumberStyles.Number ^ NumberStyles.AllowThousands)

(le code ci-dessus lève une InvalidFormatException , ce que vous voulez, n'est-ce pas?)

Vous pourrez peut-être le faire en deux temps. Tout d'abord, vous pouvez vérifier le séparateur de milliers à l'aide des informations du CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator et du CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes en lançant une exception si elle ne passe pas. puis passez le numéro dans Decimal.Parse () ;

C’est un problème courant qui n’a jamais été résolu par Microsoft. Donc, je ne comprends pas pourquoi 1,2,3.00 (culture anglaise par exemple) est valable! Vous devez créer un algorithme pour examiner la taille du groupe et renvoyer false / exception (comme un double.parse en échec) si le test n'est pas réussi. J'ai eu un problème similaire dans une application MVC, qui construit dans le validateur n'accepte pas les milliers, donc je l'ai écrasé avec une personnalisation, en utilisant double / decimal / float.parse, mais en ajoutant une logique pour valider la taille du groupe.

Si vous voulez lire ma solution (elle est utilisée pour mon validateur personnalisé mvc, mais vous pouvez l’utiliser pour obtenir un meilleur validateur générique double / décimal / float.parse), cliquez ici https://stackoverflow.com/a/41916721/3930528

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top