C#格式为货币,没有尾随零的十进制数字,请考虑负数,并且使用不同的区域性 [英] C# format as currency with no trailing zero decimal numbers, consider negative, and different culture

查看:160
本文介绍了C#格式为货币,没有尾随零的十进制数字,请考虑负数,并且使用不同的区域性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将数字格式化为货币而不尾随零小数?基本上,它应该表现为,但不带尾随零.下面是测试用例.

How can we format a number to currency without trailing zero decimal numbers? Basically it should behave as the "C" format specifier but without trailing zeroes. Below are the test cases.

value   | en-US  | fr-FR
1       | $1     | 1 €
1.0     | $1     | 1 €
1.1     | $1.1   | 1,1 €
1.10    | $1.1   | 1,1 €
-1      | ($1)   | -1 €
-1.0    | ($1)   | -1 €
-1.1    | ($1.1) | -1,1 €
1000    | $1,000 | 1 000 €
1000.0  | $1,000 | 1 000 €

是否有一种方法可以通过利用"C"格式说明符来实现此功能?

Is there a way to achieve this behavior by leveraging the "C" format specifier?

旁注:我从继续wpf问题,但重点是格式部分和更详尽的测试用例.

side note: I am continuing from this related wpf question but focusing on the formatting part and with more exhaustive test cases.

推荐答案

我认为我可以通过以下方式回答我的问题:

I think I was able to answer my question with the following:

public static class DecimalExtensions
{
    /// <summary>
    ///     Converts a numeric value to its equivalent currency string representation using the specified culture-specific format information.
    /// </summary>
    /// <param name="value">The value to be converted.</param>
    /// <param name="provider">An object that supplies culture-specific formatting information.</param>
    /// <returns>The currency string representation of the value as specified by <paramref name="provider" />.</returns>
    public static string ToCurrency(this decimal value, IFormatProvider provider) =>
        /// Use "1" (or "-1" if value is negative)
        /// as a placeholder for the actual value.
        (value < 0 ? -1 : 1)

        /// Format as a currency using the "C" format specifier.
        .ToString("C0", provider)

        /// Convert the absolute value to its string representation
        /// then replace the placeholder "1".
        /// We used absolute value since the negative sign
        /// is already converted to its string representation
        /// using the "C" format specifier.
        .Replace("1", Math.Abs(value).ToString("#,0.############################", provider));
}


测试

public class ToCurrencyTests
{
    private string ToCurrency(decimal value, string cultureName) =>
        value.ToCurrency(CultureInfo.GetCultureInfo(cultureName));

    [Theory]
    [MemberData(nameof(enUS))]
    public void ToCurrency_enUS(decimal value, string expected) =>
    Assert.Equal(expected, ToCurrency(value, "en-US"));

    [Theory]
    [MemberData(nameof(frFR))]
    public void ToCurrency_frFR(decimal value, string expected) =>
        Assert.Equal(expected, ToCurrency(value, "fr-FR"));

    public static TheoryData<decimal, string> enUS =>
        new TheoryData<decimal, string>
        {
            { 1m, "$1" },
            { 1.0m, "$1" },
            { 1.1m, "$1.1" },
            { 1.10m, "$1.1" },
            { -1m, "($1)" },
            { -1.0m, "($1)" },
            { -1.1m, "($1.1)" },
            { 1000m, "$1,000" },
            { 1000.0m, "$1,000" },
            { 123456789.123456789m, "$123,456,789.123456789" },
            { .0000000000000000000000000001m, "$0.0000000000000000000000000001" }
        };

    /// <remarks>
    ///     Note that the group separator used here is a non-breaking space ' ' (i.e. &nbsp; or char 160)
    /// </remarks>
    public static TheoryData<decimal, string> frFR =>
        new TheoryData<decimal, string>
        {
            { 1m, "1 €" },
            { 1.0m, "1 €" },
            { 1.1m, "1,1 €" },
            { 1.10m, "1,1 €" },
            { -1m, "-1 €" },
            { -1.0m, "-1 €" },
            { -1.1m, "-1,1 €" },
            { 1000m, "1 000 €" },
            { 1000.0m, "1 000 €" },
            { 123456789.123456789m, "123 456 789,123456789 €" },
            { .0000000000000000000000000001m, "0,0000000000000000000000000001 €" }
        };
}

在此处复制不间断空格 http://www.unicode-symbol .com/u/00A0.html

copy non-breaking space here http://www.unicode-symbol.com/u/00A0.html

这篇关于C#格式为货币,没有尾随零的十进制数字,请考虑负数,并且使用不同的区域性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆