8

通常我会string.Format()用来获取格式化的字符串。

但我要求所有金额都应打印为文本而不是数字。

即类似的东西:

Format(3000, "us"); // => Resulting text: "three thousand dollars"

是否有可以处理的 .NET 库(俄语是强制性的)?

4

5 回答 5

2

是否有可以处理的 .NET 库(俄语是强制性的)?

简短的回答:没有。

您必须自己编写,但我建议您看一下以下内容: 将数字转换为单词 C#如何将整数转换为其口头表示?正如其中之一所说,查看项目 Euler 问题编号 17并将其用于更广泛的谷歌搜索。

除此之外,您还有货币名称的问题,应该'us'表示货币或语言,甚至两者兼而有之?加元和美元有区别吗?

例如这是内置的:

// Gives USD
var ISOCode = System.Globalization.RegionInfo.RegionInfo("US").ISOCurrencySymbol
// Gives $
var symbol = System.Globalization.RegionInfo.RegionInfo("US").CurrencySymbol
// Gives USD Dollar (i believe :))
var nameUSDENG = System.Globalization.RegionInfo.RegionInfo("US").CurrencyEnglishName
// Gives Svensk Krona
var nameSEKSWE = System.Globalization.RegionInfo.RegionInfo("SE").CurrencyNativeName
// Gives Swedish Krona
var nameSEKENG = System.Globalization.RegionInfo.RegionInfo("SE").CurrencyEnglishName

我建议你从那里开始,看看这条路会把你带到哪里。

于 2012-11-01T14:03:23.783 回答
2

有一个成熟的库可以满足您的需要。这叫人性化。

你可以在这里看到它的内容:NuGet 本周包:Humanizer 使 .NET 数据类型更人性化

开源项目在 GitHub

如您所见,它可以满足您的需要以及更多功能。它有很多本地化。

一些例子:

1.ToWords() => "one"
10.ToWords() => "ten"
11.ToWords() => "eleven"
122.ToWords() => "one hundred and twenty-two"
3501.ToWords() => "three thousand five hundred and one"

您还可以将第二个参数 GrammaticalGender 传递给 ToWords,以指定数字应以哪种性别输出。

1.ToWords(GrammaticalGender.Masculine) => "один"
1.ToWords(GrammaticalGender.Feminine) => "одна"
1.ToWords(GrammaticalGender.Neuter) => "одно"
于 2015-10-05T08:39:53.080 回答
1

我环顾四周,但找不到合适的版本来转换为英语货币,因此我将一些合并到此解决方案中:

public static class NumberExtensions
{
    public static String toCurrency(this double number, String major, String minor, String endStr, int minorLength)
    {
        return ((decimal)number).toCurrency(major, minor, endStr, minorLength);
    }

    public static String toCurrency(this decimal number, String major, String minor, String endStr, int minorLength)
    {

        if (String.IsNullOrWhiteSpace(major)) throw new Exception("Must specify major currency");
        if (String.IsNullOrWhiteSpace(minor)) throw new Exception("Must specify minor currency");

        String numb = number.ToString();
        String val = "", wholeNo = numb, points = "", andStr = major, pointStr = "";
        int decimalPlace = numb.IndexOf(".");
        if (decimalPlace > 0)
        {
            wholeNo = numb.Substring(0, decimalPlace);
            points = numb.Substring(decimalPlace + 1);
            if (points.Length > minorLength) throw new Exception("Incorrect format");
            if (Convert.ToInt32(points) > 0)
            {
                andStr = major + " and";
                endStr = minor + " " + endStr;
                pointStr = Int32.Parse(points.Length == 1 ? points + "0" : points).toWords();
            }
        }
        if (String.IsNullOrWhiteSpace(pointStr))
        {
            if (endStr == minor + " " || endStr == null)
            {
                val = String.Format("{0} {1}", Int32.Parse(wholeNo).toWords().Trim(), andStr.Trim());
            }
            else
            {
                val = String.Format("{0} {1} {2}", Int32.Parse(wholeNo).toWords().Trim(), andStr.Trim(), endStr.Trim());
            }
        }
        else
        {
            val = String.Format("{0} {1} {2} {3}", Int32.Parse(wholeNo).toWords().Trim(), andStr.Trim(), pointStr.Trim(), endStr.Trim());
        }
        return val;
    }

    public static string toWords(this int number)
    {
        if (number == 0)
            return "Zero";

        if (number < 0)
            return "minus " + Math.Abs(number).toWords();

        string words = "";

        if ((number / 1000000) > 0)
        {
            words += (number / 1000000).toWords().TrimEnd() + " Million ";
            number %= 1000000;
        }

        if ((number / 1000) > 0)
        {
            words += (number / 1000).toWords().TrimEnd() + " Thousand ";
            number %= 1000;
        }

        if ((number / 100) > 0)
        {
            words += (number / 100).toWords().TrimEnd() + " Hundred ";
            number %= 100;
        }

        if (number > 0)
        {
            if (words != "")
                words += "and ";

            var unitsMap = new[] { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" };
            var tensMap = new[] { "Zero", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" };

            if (number < 20)
                words += unitsMap[number];
            else
            {
                words += tensMap[number / 10];
                if ((number % 10) > 0)
                    words += "-" + unitsMap[number % 10];
            }
        }

        return words;
    }
}

这是单元测试:

[TestFixture]
public class NumbericExtensionMethodsTests
    : TestBase
{
    [Test]
    [TestCase(0.0, null, null, null, 2, ExpectedException = typeof(Exception))]
    [TestCase(0.0, "", null, null, 2, ExpectedException = typeof(Exception))]
    [TestCase(0.0, null, "", null, 2, ExpectedException = typeof(Exception))]
    [TestCase(0.0, "", "", null, 2, ExpectedException = typeof(Exception))]
    [TestCase(0.001, "Rand", "Cent", null, 2, ExpectedException = typeof(Exception))]
    [TestCase(0.001, "Rand", "Cent", null, 3, Result = "Zero Rand and One Cent")]
    [TestCase(0, "Rand", "Cent", null, 2, Result = "Zero Rand")]
    [TestCase(0.0, "Rand", "Cent", null, 2, Result = "Zero Rand")]
    [TestCase(0.01, "Rand", "Cent", null, 2, Result = "Zero Rand and One Cent")]
    [TestCase(0.1, "Rand", "Cent", null, 2, Result = "Zero Rand and Ten Cent")]
    [TestCase(0.10, "Rand", "Cent", null, 2, Result = "Zero Rand and Ten Cent")]
    [TestCase(0.10, "Rand", "Cent", "only", 2, Result = "Zero Rand and Ten Cent only")]
    [TestCase(1.10, "Rand", "Cent", "only", 2, Result = "One Rand and Ten Cent only")]
    [TestCase(1.0, "Rand", "Cent", "only", 2, Result = "One Rand only")]
    [TestCase(123312.32, "Rand", "Cent", null, 2, Result = "One Hundred and Twenty-Three Thousand Three Hundred and Twelve Rand and Thirty-Two Cent")]
    public string NumberToCurrency(decimal number, string major, string minor, string endStr, int minorLength)
    {
        return number.toCurrency(major, minor, endStr, minorLength);
    }
    
    [Test]
    [TestCase(0, Result = "Zero")]
    [TestCase(1, Result = "One")]
    [TestCase(2, Result = "Two")]
    [TestCase(3, Result = "Three")]
    [TestCase(4, Result = "Four")]
    [TestCase(5, Result = "Five")]
    [TestCase(6, Result = "Six")]
    [TestCase(7, Result = "Seven")]
    [TestCase(8, Result = "Eight")]
    [TestCase(9, Result = "Nine")]

    [TestCase(10, Result = "Ten")]
    [TestCase(11, Result = "Eleven")]
    [TestCase(12, Result = "Twelve")]
    [TestCase(13, Result = "Thirteen")]
    [TestCase(14, Result = "Fourteen")]
    [TestCase(15, Result = "Fifteen")]
    [TestCase(16, Result = "Sixteen")]
    [TestCase(17, Result = "Seventeen")]
    [TestCase(18, Result = "Eighteen")]
    [TestCase(19, Result = "Nineteen")]
    [TestCase(20, Result = "Twenty")]
    [TestCase(30, Result = "Thirty")]
    [TestCase(40, Result = "Forty")]
    [TestCase(50, Result = "Fifty")]
    [TestCase(60, Result = "Sixty")]
    [TestCase(70, Result = "Seventy")]
    [TestCase(80, Result = "Eighty")]
    [TestCase(90, Result = "Ninety")]
    [TestCase(99, Result = "Ninety-Nine")]

    [TestCase(100, Result = "One Hundred")]
    [TestCase(101, Result = "One Hundred and One")]
    [TestCase(111, Result = "One Hundred and Eleven")]
    [TestCase(121, Result = "One Hundred and Twenty-One")]

    [TestCase(1000, Result = "One Thousand")]
    [TestCase(1001, Result = "One Thousand and One")]
    [TestCase(1011, Result = "One Thousand and Eleven")]
    [TestCase(1021, Result = "One Thousand and Twenty-One")]
    [TestCase(1100, Result = "One Thousand One Hundred")]
    [TestCase(1101, Result = "One Thousand One Hundred and One")]
    [TestCase(1111, Result = "One Thousand One Hundred and Eleven")]
    [TestCase(1121, Result = "One Thousand One Hundred and Twenty-One")]

    [TestCase(12000, Result = "Twelve Thousand")]
    [TestCase(12001, Result = "Twelve Thousand and One")]
    [TestCase(12011, Result = "Twelve Thousand and Eleven")]
    [TestCase(12021, Result = "Twelve Thousand and Twenty-One")]
    [TestCase(12100, Result = "Twelve Thousand One Hundred")]
    [TestCase(12101, Result = "Twelve Thousand One Hundred and One")]
    [TestCase(12111, Result = "Twelve Thousand One Hundred and Eleven")]
    [TestCase(12121, Result = "Twelve Thousand One Hundred and Twenty-One")]
    [TestCase(60000, Result = "Sixty Thousand")]
    [TestCase(60001, Result = "Sixty Thousand and One")]
    [TestCase(60011, Result = "Sixty Thousand and Eleven")]
    [TestCase(60021, Result = "Sixty Thousand and Twenty-One")]
    [TestCase(60100, Result = "Sixty Thousand One Hundred")]
    [TestCase(60101, Result = "Sixty Thousand One Hundred and One")]
    [TestCase(60111, Result = "Sixty Thousand One Hundred and Eleven")]
    [TestCase(60121, Result = "Sixty Thousand One Hundred and Twenty-One")]
    [TestCase(61000, Result = "Sixty-One Thousand")]
    [TestCase(61001, Result = "Sixty-One Thousand and One")]
    [TestCase(61011, Result = "Sixty-One Thousand and Eleven")]
    [TestCase(61021, Result = "Sixty-One Thousand and Twenty-One")]
    [TestCase(61100, Result = "Sixty-One Thousand One Hundred")]
    [TestCase(61101, Result = "Sixty-One Thousand One Hundred and One")]
    [TestCase(61111, Result = "Sixty-One Thousand One Hundred and Eleven")]
    [TestCase(61121, Result = "Sixty-One Thousand One Hundred and Twenty-One")]
    
    [TestCase(100000, Result = "One Hundred Thousand")]
    [TestCase(100001, Result = "One Hundred Thousand and One")]
    [TestCase(100011, Result = "One Hundred Thousand and Eleven")]
    [TestCase(100021, Result = "One Hundred Thousand and Twenty-One")]
    [TestCase(100100, Result = "One Hundred Thousand One Hundred")]
    [TestCase(100101, Result = "One Hundred Thousand One Hundred and One")]
    [TestCase(100111, Result = "One Hundred Thousand One Hundred and Eleven")]
    [TestCase(100121, Result = "One Hundred Thousand One Hundred and Twenty-One")]
    [TestCase(101000, Result = "One Hundred and One Thousand")]
    [TestCase(101001, Result = "One Hundred and One Thousand and One")]
    [TestCase(101011, Result = "One Hundred and One Thousand and Eleven")]
    [TestCase(101021, Result = "One Hundred and One Thousand and Twenty-One")]
    [TestCase(101100, Result = "One Hundred and One Thousand One Hundred")]
    [TestCase(101101, Result = "One Hundred and One Thousand One Hundred and One")]
    [TestCase(101111, Result = "One Hundred and One Thousand One Hundred and Eleven")]
    [TestCase(101121, Result = "One Hundred and One Thousand One Hundred and Twenty-One")]
    [TestCase(112000, Result = "One Hundred and Twelve Thousand")]
    [TestCase(112001, Result = "One Hundred and Twelve Thousand and One")]
    [TestCase(112011, Result = "One Hundred and Twelve Thousand and Eleven")]
    [TestCase(112021, Result = "One Hundred and Twelve Thousand and Twenty-One")]
    [TestCase(112100, Result = "One Hundred and Twelve Thousand One Hundred")]
    [TestCase(112101, Result = "One Hundred and Twelve Thousand One Hundred and One")]
    [TestCase(112111, Result = "One Hundred and Twelve Thousand One Hundred and Eleven")]
    [TestCase(112121, Result = "One Hundred and Twelve Thousand One Hundred and Twenty-One")]
    [TestCase(160000, Result = "One Hundred and Sixty Thousand")]
    [TestCase(160001, Result = "One Hundred and Sixty Thousand and One")]
    [TestCase(160011, Result = "One Hundred and Sixty Thousand and Eleven")]
    [TestCase(160021, Result = "One Hundred and Sixty Thousand and Twenty-One")]
    [TestCase(160100, Result = "One Hundred and Sixty Thousand One Hundred")]
    [TestCase(160101, Result = "One Hundred and Sixty Thousand One Hundred and One")]
    [TestCase(160111, Result = "One Hundred and Sixty Thousand One Hundred and Eleven")]
    [TestCase(160121, Result = "One Hundred and Sixty Thousand One Hundred and Twenty-One")]
    [TestCase(161000, Result = "One Hundred and Sixty-One Thousand")]
    [TestCase(161001, Result = "One Hundred and Sixty-One Thousand and One")]
    [TestCase(161011, Result = "One Hundred and Sixty-One Thousand and Eleven")]
    [TestCase(161021, Result = "One Hundred and Sixty-One Thousand and Twenty-One")]
    [TestCase(161100, Result = "One Hundred and Sixty-One Thousand One Hundred")]
    [TestCase(161101, Result = "One Hundred and Sixty-One Thousand One Hundred and One")]
    [TestCase(161111, Result = "One Hundred and Sixty-One Thousand One Hundred and Eleven")]
    [TestCase(161121, Result = "One Hundred and Sixty-One Thousand One Hundred and Twenty-One")]
    [TestCase(1000000, Result = "One Million")]
    [TestCase(Int32.MaxValue, Result = "Two Thousand One Hundred and Forty-Seven Million Four Hundred and Eighty-Three Thousand Six Hundred and Forty-Seven")]
    /*Assuming Millions will work if Thousands worked*/
    public string IntToWords(int number)
    {
        return number.toWords().Trim();
    }
}

享受这个完美的作品:D

学分

于 2015-09-30T14:35:13.253 回答
1

我还没有测试过,但也许这会解决你的问题?

Nuget 包

它说它也支持俄语。

从包装描述:

数字到文本转换器。支持的语言 英语 俄语 西班牙语 土耳其语

用法:

var number = 123456.78
var moneyText = number.ToText("usd", "en");

var number = 123456.78;
var moneyText = number.ToText(Nut.Currency.USD, Nut.Language.English);

var number = 123456.78;
var options = new Nut.Options {
    MainUnitNotConvertedToText = true,
    SubUnitNotConvertedToText = true,
    MainUnitFirstCharUpper = true,
    SubUnitFirstCharUpper = true,
    CurrencyFirstCharUpper = true,
    SubUnitZeroNotDisplayed = true
}
var moneyText = number.ToText(Nut.Currency.USD, Nut.Language.English, options);
于 2015-10-05T08:07:27.390 回答
0

对于俄语,您可以使用我的库:https
://github.com/nick-buhro/NumToWords 它也可以在 nuget 上获得:https ://www.nuget.org/packages/NickBuhro.NumToWords

例子:

var unit = new UnitOfMeasure(Gender.Masculine, "доллар", "доллара", "долларов");
var text = RussianConverter.Format(3000, unit);
Console.WriteLine(text);
// Output: три тысячи долларов
于 2016-03-26T19:35:50.547 回答