我有一个价格字段显示,有时可以是100或100.99或100.9,我想要的是显示价格在小数点后2位,只有小数输入的价格,例如,如果它的100,它应该只显示100而不是100.00,如果价格是100.2,它应该显示100.20类似的100.22应该是一样的。
我谷歌了一下,找到了一些例子,但它们并不完全符合我想要的:
// just two decimal places
String.Format("{0:0.00}", 123.4567); // "123.46"
String.Format("{0:0.00}", 123.4); // "123.40"
String.Format("{0:0.00}", 123.0); // "123.00"
最近的一个项目也有类似的需求。我写了这个十进制扩展法,
它使用货币(“C”)格式说明符。除了删除零之外,它还可以选择十进制数字精度、货币符号、分隔符和区域性。
public static DecimalExtension{
public static string ToCurrency(this decimal val,
int precision = 2,
bool currencySymbol = false,
bool separator = false,
CultureInfo culture = null)
{
if(culture == null) culture = new CultureInfo("en-US");
NumberFormatInfo nfi = culture.NumberFormat;
nfi.CurrencyDecimalDigits = precision;
string zeros = new String('0', precision);
//Remove zeros
var result = val.ToString("C",fi).Replace(nfi.CurrencyDecimalSeparator + zeros,"");
if(!separator) result = result.Replace(nfi.CurrencyGroupSeparator,"");
return currencySymbol? result: result.Replace(nfi.CurrencySymbol,"");
}
}
例子:
decimal Total = 123.00M;
Console.WriteLine(Total.ToCurrency());
//output: 123
decimal Total = 1123.12M;
Console.WriteLine(Total.ToCurrency());
//Output: 1123.12
Console.WriteLine(Total.ToCurrency(4));
//Output: 1123.1200
Console.WriteLine(Total.ToCurrency(2,true,true));
//output: $1,123.12
CultureInfo culture = new CultureInfo("pt-BR") //Brazil
Console.WriteLine(Total.ToCurrency(2,true,true, culture));
//output: R$ 1.123,12
我不知道如何在格式说明符中放入一个条件,但你可以编写自己的格式化程序:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// all of these don't work
Console.WriteLine("{0:C}", 10);
Console.WriteLine("{0:00.0}", 10);
Console.WriteLine("{0:0}", 10);
Console.WriteLine("{0:0.00}", 10);
Console.WriteLine("{0:0}", 10.0);
Console.WriteLine("{0:0}", 10.1);
Console.WriteLine("{0:0.00}", 10.1);
// works
Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9));
Console.WriteLine(String.Format(new MyFormatter(),"{0:custom}", 9.1));
Console.ReadKey();
}
}
class MyFormatter : IFormatProvider, ICustomFormatter
{
public string Format(string format, object arg, IFormatProvider formatProvider)
{
switch (format.ToUpper())
{
case "CUSTOM":
if (arg is short || arg is int || arg is long)
return arg.ToString();
if (arg is Single || arg is Double)
return String.Format("{0:0.00}",arg);
break;
// Handle other
default:
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e);
}
}
return arg.ToString(); // only as a last resort
}
private string HandleOtherFormats(string format, object arg)
{
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
if (arg != null)
return arg.ToString();
return String.Empty;
}
public object GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
return this;
return null;
}
}
}
下面是Uwe Keim的方法的替代方案,它仍然保持相同的方法调用:
var example1 = MyCustomFormat(123.1); // Output: 123.10
var example2 = MyCustomFormat(123.95); // Output: 123.95
var example3 = MyCustomFormat(123); // Output: 123
MyCustomFormat是这样的:
public static string MyCustomFormat( double myNumber )
{
var str (string.Format("{0:0.00}", myNumber))
return (str.EndsWith(".00") ? str.Substring(0, strLastIndexOf(".00")) : str;
}
老问题了,但我想在我看来添加一个最简单的选项。
没有数千个隔板:
value.ToString(value % 1 == 0 ? "F0" : "F2")
有成千上万的隔板:
value.ToString(value % 1 == 0 ? "N0" : "N2")
与String相同。格式:
String.Format(value % 1 == 0 ? "{0:F0}" : "{0:F2}", value) // Without thousands separators
String.Format(value % 1 == 0 ? "{0:N0}" : "{0:N2}", value) // With thousands separators
如果你在很多地方都需要它,我会在一个扩展方法中使用这个逻辑:
public static string ToCoolString(this decimal value)
{
return value.ToString(value % 1 == 0 ? "N0" : "N2"); // Or F0/F2 ;)
}