Пример #1
0
        public void Parse_NotAPattern()
        {
            var locale = Locale.Create("en");
            var path   = $"ldml/numbers/decimalFormats[@numberSystem='latn']/decimalFormatLength[@type='long']/decimalFormat";

            ExceptionAssert.Throws <Exception>(() => NumberPattern.Parse(locale.Find(path)));
        }
Пример #2
0
        public void Parse_Simple()
        {
            var locale  = Locale.Create("en");
            var path    = $"ldml/numbers/decimalFormats[@numberSystem='latn']/decimalFormatLength[not(@type)]/decimalFormat/pattern";
            var pattern = NumberPattern.Parse(locale.Find(path));

            Assert.AreEqual("", pattern.Count);
            Assert.IsFalse(pattern.MinValue.HasValue);
            Assert.AreEqual("#,##0.###", pattern.FormatString);
        }
Пример #3
0
        public void Parse_ValueRange()
        {
            var locale  = Locale.Create("en");
            var path    = $"ldml/numbers/decimalFormats[@numberSystem='latn']/decimalFormatLength[@type='long']/decimalFormat/pattern";
            var pattern = NumberPattern.Parse(locale.Find(path));

            Assert.AreEqual("one", pattern.Count);
            Assert.IsTrue(pattern.MinValue.HasValue);
            Assert.AreEqual(1000L, pattern.MinValue.Value);
            Assert.AreEqual("0 thousand", pattern.FormatString);
        }
Пример #4
0
        NumberPattern FindPattern(decimal value, NumberLength?nl = null)
        {
            if (!nl.HasValue)
            {
                nl = Options.Length;
            }
            value = Math.Abs(value);

            // Determine the format length type.
            var flt = nl == NumberLength.Default
                ? "[not(@type)]"
                : $"[@type='{nl.ToString().ToLowerInvariant()}']";

            // Determine the path in the ldml to the pattern(s)
            var path = String.Empty;

            if (Options.Style == NumberStyle.Decimal)
            {
                path = $"ldml/numbers/decimalFormats[@numberSystem='{NumberingSystem.Id}']/decimalFormatLength{flt}/decimalFormat";
            }
            else if (Options.Style == NumberStyle.Percent)
            {
                path = $"ldml/numbers/percentFormats[@numberSystem='{NumberingSystem.Id}']/percentFormatLength{flt}/percentFormat";
            }
            else if (Options.Style == NumberStyle.Scientific)
            {
                path = $"ldml/numbers/scientificFormats[@numberSystem='{NumberingSystem.Id}']/scientificFormatLength{flt}/scientificFormat";
            }
            else if (Options.Style == NumberStyle.CurrencyStandard)
            {
                path = $"ldml/numbers/currencyFormats[@numberSystem='{NumberingSystem.Id}']/currencyFormatLength{flt}/currencyFormat[@type='standard']";
            }
            else if (Options.Style == NumberStyle.CurrencyAccounting)
            {
                path = $"ldml/numbers/currencyFormats[@numberSystem='{NumberingSystem.Id}']/currencyFormatLength{flt}/currencyFormat[@type='accounting']";
            }
            else
            {
                throw new NotImplementedException($"Unknown NumberStyle '{Options.Style}'.");
            }

            var xml = Locale.FindOrDefault(path);

            // Fall back to default number length;
            if (xml == null && nl != NumberLength.Default)
            {
                return(FindPattern(value, NumberLength.Default));
            }

            // Should not happen.
            if (xml == null)
            {
                throw new KeyNotFoundException($"Cannot find CLDR '{path}'.");
            }

            // Get the best pattern.
            var           category = Plural.Create(Locale).Category(value);
            NumberPattern best     = null;
            NumberPattern previous = null;
            var           pattern  = xml.SelectChildren("pattern", "");

            while (pattern.MoveNext())
            {
                var p = NumberPattern.Parse(pattern.Current);

                // If not a value range, then this is the best pattern.
                if (!p.MinValue.HasValue)
                {
                    best = p;
                    break;
                }

                // Only consider a pattern with the correct count.
                if (p.Count != category)
                {
                    continue;
                }

                // Get closest value in the range.
                if (p.MinValue.Value > value)
                {
                    best = previous;
                    break;
                }

                previous = p;
            }
            best = best ?? previous ?? new NumberPattern {
                FormatString = "0"
            };

            return(best);
        }