使用千位分隔符进行.NET常规数字格式化

时间:2015-04-13 07:01:06

标签: c# .net decimal number-formatting

在.NET中是否可以使用最紧凑的数字格式,例如"G"eneral Number formatting具有额外的千位分隔符

我无法使用以下

String.Format("{0:#,###.###}",32445.324777M)

因为我得到"32,445.325",而我想要的结果应该是"32.445,325777"。也应该在小数部分使用任意数量的有效数字。

PS:我只需要decimal s。

3 个答案:

答案 0 :(得分:5)

格式化文化的来源。您需要获得符合要求的格式说明符。您拥有的默认值通常是当前的文化,UI文化或不变文化。您的结果意味着您正在使用美国文化。

如果您想要输入特定文化,请使用该文件。如果没有,您可以创建自己的:

var nfi = 
  new NumberFormatInfo 
  { 
    NumberDecimalSeparator = ",", 
    NumberGroupSeparator = "." 
  };

var ci = 
  new CultureInfo(CultureInfo.InvariantCulture.LCID) { NumberFormat = nfi };

return string.Format(ci, "{0:#,###.########}", 32445.324777M)

如果您还希望获得最紧凑的数字,则必须使用自己的代码。最简单的方法是尝试两者,并返回较小的结果字符串。

如果您愿意,您仍然可以使用string.Format语法 - 您可以编写自己的ICustomFormatter代码来处理:

void Main()
{
    var number = 32445.324777M;

    string.Format(new MyNumberFormatter(),  "{0:MyG}", number).Dump();
}

class MyNumberFormatter : IFormatProvider, ICustomFormatter
{
  public object GetFormat(Type type)
  {
    return this;
  }

  public string Format(string fmt, object arg, IFormatProvider formatProvider)
  {
    if (fmt != "MyG" || !(arg is decimal)) return string.Format(CultureInfo.CurrentCulture, "{0:" + fmt + "}", arg);

    return "Hi";
  }
}

这种实施有些笨拙,当然,我确信你能找到更好的例子。但它确实有效。在Format方法中,您可以选择更适合给定数字的格式,或者甚至尝试执行通常的ToString("G", CultureInfo.InvariantCulture)并将小数分隔符添加到该字符串。无论什么漂浮你的船:)

答案 1 :(得分:2)

来自.NET documentation

  

"#"自定义格式说明符用作数字占位符符号。   如果正在格式化的值在其中的位置有一个数字   "#"符号出现在格式字符串中,该数字被复制到   结果字符串。

     

否则,该位置不会存储任何内容   结果字符串。请注意,此说明符从不显示零   即使零是唯一的数字,也不是一个重要的数字   串。只有当它是一个重要的数字时它才会显示零   正在显示的号码。

     

" ##"格式字符串导致   值四舍五入到小数点前面的最近数字,其中   总是使用从零开始的舍入。例如,格式化34.5   用" ##"会得到值35。

使用默认格式化可能性无法格式化未指定数量的小数位。因此,如果需要,您应该考虑编写自己的实现。

关于小数和千位分隔符,它取决于您的系统设置,但您可以使用不同的文化覆盖它们,如@Luaan在其答案中所述。

你也应该考虑this answer

答案 2 :(得分:1)

如果您想要完全控制,请在下方创建自己的格式化程序链接。请参阅案例“U”表示您的格式。

public class CustomerFormatter : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
            return this;
        else
            return null;
    }

    public string Format(string format,
                          object arg,
                          IFormatProvider formatProvider)
    {
        if (!this.Equals(formatProvider))
        {
            return null;
        }
        else
        {
            // generic formatter if no formater specified
            if (String.IsNullOrEmpty(format))
                format = "G";

            // not a decimal type object
            if (!(arg is decimal))
                return null;

            // get value
            decimal val = (decimal)arg;

            // convert value into generic culture string for control of format
            string valueString = val.ToString();

            // get string in required format type
            format = format.ToUpper();
            switch (format)
            {
                // our user format
                case "U":

                    // get decimals
                    string decimals = val.ToString("G", CultureInfo.InvariantCulture);
                    decimals = decimals.Substring(decimals.IndexOf('.') + 1);

                    // get current culture info
                    NumberFormatInfo nfi = new CultureInfo(CultureInfo.CurrentCulture.Name).NumberFormat;

                    // set our separators
                    nfi.NumberGroupSeparator = ",";
                    nfi.NumberDecimalSeparator = ".";

                    // set numebr of decimals
                    nfi.NumberDecimalDigits = decimals.Length;

                    // convert value to our format
                    valueString = val.ToString("N", nfi);
                    break;
                default:
                    break;
            }

            return valueString;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        decimal dec = 32445.324777M;
        Console.WriteLine(String.Format(new CustomerFormatter(), "{0}", dec));
        Console.WriteLine(String.Format(new CustomerFormatter(), "{0:G}", dec));
        Console.WriteLine(String.Format(new CustomerFormatter(), "{0:U}", dec));
        Console.WriteLine(String.Format(new CustomerFormatter(), "{0:T}", dec));

        Console.ReadLine();
    }
}