.NET 通用数字格式与千位分隔符
Posted
技术标签:
【中文标题】.NET 通用数字格式与千位分隔符【英文标题】:.NET General Number Formatting with Thousands Separator 【发布时间】:2015-04-13 07:01:06 【问题描述】:.NET 中是否可以使用最紧凑的数字格式,例如 "G"
eneral Number formatting,带有额外的千位分隔符。
我不能使用下面的
String.Format("0:#,###.###",32445.324777M)
因为我得到了"32,445.325"
,而我想要的结果应该是"32.445,325777"
。 Is 也应该与小数部分中任意数量的有效数字一起使用。
PS:我只需要decimals。
【问题讨论】:
您正在解决您的问题的 2 个问题:1) 使用小数分隔符切换组分隔符(使用适当的文化)和 2) 不限制小数位数,不明确使用#
。 ..
【参考方案1】:
这就是格式化文化的用武之地。您需要获得一个符合您要求的格式说明符。您拥有的默认值通常是当前文化、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";
这个实现有点hacky,当然,我相信你能找到更好的例子。但它确实有效。在Format
方法中,您可以选择更适合给定数字的格式,或者甚至只是尝试执行通常的ToString("G", CultureInfo.InvariantCulture)
并将小数分隔符添加到该字符串中。无论你的船漂浮什么:)
【讨论】:
【参考方案2】:来自.NET documentation
“#”自定义格式说明符用作数字占位符符号。 如果正在格式化的值的位置有一个数字 “#”符号出现在格式字符串中,该数字被复制到 结果字符串。
否则,没有任何内容存储在该位置 结果字符串。请注意,此说明符从不显示零 不是有效数字,即使零是唯一的数字 细绳。只有当它是有效数字时才会显示零 正在显示的数字。
“##”格式字符串导致 要四舍五入到小数点前最接近的数字的值,其中 始终使用从零四舍五入的方法。例如,格式化 34.5 使用 "##" 将导致值 35。
无法使用默认格式设置未指定数量的小数位数。因此,如果需要,您应该考虑编写自己的实现。
关于小数点和千位分隔符,这取决于您的系统设置,但您可以使用 @Luaan 在他的回答中描述的不同文化来覆盖它们。
你也应该看看this answer。
【讨论】:
【参考方案3】:如果您想要完全控制,请创建 yoru 自己的格式化程序,如下所示。请参阅大小写“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();
【讨论】:
以上是关于.NET 通用数字格式与千位分隔符的主要内容,如果未能解决你的问题,请参考以下文章