Bug beim Parsen eines Währungsstring der tzm-CultureInfo in .NET

Beim Testen der Konvertierung numerischer Werte in einen Währungsstring und umgekehrt ist mir ein Fall aufgefallen, den man als Bug einstufen kann. Das Parsen von Währungsstrings, unter Verwendung der CultureInfo als FormatProvider, funktioniert bis auf die tzm-CultureInfo problemlos. Der Versuch einen mit der tzm-CultrueInfo formatierten Währungsstring zu parsen verursacht eine FormatException.

Ergebnis Meldung:    System.FormatException : Die Eingabezeichenfolge hat das falsche Format.
Ergebnis StackTrace:
bei System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
bei System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
bei System.Decimal.Parse(String s, NumberStyles style, IFormatProvider provider)
bei Currency.Test.CurrencyTest.TestCurrency(CultureInfo cultureInfo) in CurrencyTest.cs:Zeile 29.

Bei der tzm-CultureInfo ist der CurrencyDecimalSeparator = "." und der CurrencyGroupSeparator = ",". Tauscht man jedoch die Werte, wird der Währungsstring korrekt geparsed. Das Problem besteht in den .NET Framworks 2.0 bis 4.5.1. Eine Lösung für das Problem habe ich leider nicht gefunden. Die einzige Möglichkeit bei dynamischen Unit Tests besteht darin diese CultureInfos rauszufiltern.

Eine weitere Besonderheit ist mir auch beim Testen mit dem Framework 3.5 aufgefallen. Das Parsen eines Währungsstrings mit einer neutralen CultureInfo wird mit einer NotSupportedException quitiert. Andere Frameworkversionen sind davon nicht betroffen.

Ergebnis Meldung:    System.NotSupportedException : Die Kultur "af" ist neutral. Sie kann nicht als die aktuelle Threadkultur festgelegt werden, da sie nicht zum Formatieren und Analysieren verwendet werden kann.
Ergebnis StackTrace:
bei System.Globalization.CultureInfo.CheckNeutral(CultureInfo culture)
bei System.Globalization.CultureInfo.get_NumberFormat()
bei Currency.Test.CurrencyTest.TestCurrency(CultureInfo cultureInfo) in CurrencyTest.cs:Zeile 21.

Die tzm-CultureInfo steht für Tamazight, Berbersprachen und -dialekte. Nun wird man wohl selten in die Verlegenheit kommen diese CultureInfo direkt zu verwenden, aber im Hinblick auf dynamische Unit Tests ist es vorteilhaft von diesen Einschränkungen zu wissen.

Wer gerne das Problem selbst nachvollziehen möchte, hier der UnitTest für NUnit.

using NUnit.Framework;
using System.Collections.Generic;
using System.Globalization;

namespace Currency.Test
{
    [TestFixture]
    public class CurrencyTest
    {
        private static List<CultureInfo> cultureInfos
        {
            get
            {
                return new List<CultureInfo>(CultureInfo.GetCultures(CultureTypes.AllCultures));
            }
        }
        
        [Test]
        public void TestCurrency([ValueSource("cultureInfos")] CultureInfo cultureInfo)
        {
            cultureInfo.NumberFormat.CurrencyDecimalDigits = 2;
            
            decimal expected = 1234567.89m;
            string str = string.Format(cultureInfo, "{0:C}", expected);
            decimal actual = decimal.Parse(str, NumberStyles.Currency, cultureInfo);

            Assert.AreEqual(expected, actual);
        }
    }
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.