Frage

Hier ist mein Problem (für en-US):

Decimal.Parse("1,2,3,4") kehrt 1234, anstatt eine InvalidFormatException werfen.

Die meisten Windows-Anwendungen (Excel en-US) nicht fallen die Tausendertrennzeichen und berücksichtigen nicht, dass Wert eine Dezimalzahl. Das gleiche Problem tritt für andere Sprachen (wenn auch mit unterschiedlichen Zeichen).

Gibt es andere Dezimal-Parsing-Bibliotheken gibt, die dieses Problem lösen?

Danke!

War es hilfreich?

Lösung 2

beenden ich den Code zu schreiben, um die Währung manuell zu überprüfen. Persönlich für einen Rahmen, der sich rühmt für die alle mit Globalisierung Sachen eingebaut, es ist erstaunlich, .NET nichts hat dies zu handhaben.

Meine Lösung ist unten. Es funktioniert für alle Gegenden im Rahmen. Dabei spielt es keine Negative Zahlen stützen, wie Orion wies unten aus, though. Was denkt ihr?

    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]+)*$";

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

Und hier ist ein Test, es zu zeigen Arbeiten (nUnit):

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

    }

Andere Tipps

Es ist erlaubt Tausende, da der Standard NumberStyles Wert von Decimal.Parse (NumberStyles.Number) verwendet wird, umfasst NumberStyles.AllowThousands.

Wenn Sie die Tausendertrennzeichen verbieten wollen, können Sie einfach die Flagge entfernen, wie folgt aus:

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

(der obige Code wird ein InvalidFormatException werfen, das ist, was Sie wollen, nicht wahr?)

könnten Sie in der Lage sein, diesen Prozess in einem Zwei-Phasen zu tun. Zunächst könnte man die Tausender-Trennzeichen unter Verwendung der Informationen in den CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator überprüfen und CultureInfo.CurrentCulture.NumberFormat.NumberGroupSizes eine Ausnahme werfen, wenn es nicht und dann die Nummer in die Decimal.Parse() passiert hindurchgeht;

Es ist ein weit verbreitetes Problem nie von Microsoft gelöst. Also, ich verstehe nicht, warum 1,2,3.00 (Englisch Kultur zum Beispiel) gültig! Sie benötigen einen algorith zu bauen Gruppengröße zu untersuchen und return false / Ausnahme (wie ein fehlgeschlagene double.parse), wenn der Test nicht bestanden wird. Ich hatte ein ähnliches Problem in einer MVC-Anwendung, die in Validator bauen akzeptiert keine thousands..so i mit einem benutzerdefinierten überschreiben hat, mit doppelseitigem / Dezimal / float.parse, aber dem Hinzufügen eines logischen Gruppengröße zu überprüfen.

Wenn Sie meine Lösung lesen möchten (ist es für meine Mvc benutzerdefinierten Validator verwendet, aber Sie können es verwenden, um eine bessere Doppel / dezimal haben / float.parse generic Validator) gehen hier https://stackoverflow.com/a/41916721/3930528

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top