Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

C# NumberFormat Sections


:P
On this page:

I'm not sure how I've missed this feature in all those years of working in C#: String.Format() supports Number Formatting Sections that allow you to show separate values for positive, negative and zero values.

Take a look:

You can find the official (and very limited) documentation on this feature on MSDN:

Number Format Sections

Sections are meant to separate:

  • Positive Values
  • Negative Values
  • Zero Values

by using a single format string. The ; character acts as a separator for those three values. But be aware that the format strings you use for the sections are very different than normal format strings - you can't use things like n0 or c2 but you have to be explicit about the number format. Instead you use # or 0 to specify number in the format string and , or . to specify thousands separator and decimal point respectively.

In other words, sections are a special kind of format string using its own custom format for each section.

So:

(12.3).ToString("0.00;(0.00);zero")  // 12.30
(-12.3).ToString("0.00;(0.00);zero")  // 12.302.3.ToString("0.00;(0.00);zero")  // (12.30)
0.ToString("0.00;(0.00);zero")  // 12.302.3.ToString("0.00;(0.00);zero")  // zero

produces the expected 2 decimal places of the number whereas using just 0 produces the integer values:

(12.30).ToString("0;(0);zero")  // 12
(-12).ToString("0;(0);zero")  // 12.302.3.ToString("0.00;(0.00);zero")  // (12)
0.ToString("0;(0);zero")  // 12.302.3.ToString("0.00;(0.00);zero")  // zero

You can use 0 or # for numbers to the left of the decimal point and 0 for numbers on the right of it. So this is the same as the last entries:

(12.30).ToString("#;(#);zero")  // 12
(-12).ToString("#;(#);zero")  // 12.302.3.ToString("0.00;(0.00);zero")  // (12)
0.ToString("#;(#);zero")  // 12.302.3.ToString("0.00;(0.00);zero")  // zero

You also need to be explicit about thousands separator, although you can use just #,###.00 to specify that 1000s should be separated - even for larger numbers:

(112345.30).ToString("#,###.00;(0);zero")  // 112,345.30
(-112345.30).ToString("#,###.00;(0);zero")  // (112,345.30)
0.ToString("#,###.00;(0);zero")  // zero

Note that you can specify that the zero value is empty by not specifying it:

val = 0.ToString("#;(#);");  // string.Empty

String Interpolation

You can also use this functionality in C# 6.0's new String Interpolation template strings:

decimal number = 1355.55M;
val = $"{number:#,###.00;(#,###.00);}";
val.Dump();

Summary

So, this obviously isn't a game changer of a feature, but it's kinda cool in terms of being able to concisely format numbers especially in scenarios where the number formatting is inlined - like in templates are things like Razor where a function is a lot nicer to read than an immediate if expression.

I'm filing it under - obscure C# things I didn't know...

Resources

Posted in C#  

The Voices of Reason


 

JRoger
November 03, 2016

# re: C# NumberFormat Sections

thanks for your shared.

May I know the editor you used above on name?

Rick Strahl
November 03, 2016

# re: C# NumberFormat Sections

@JRoger - LinqPad

Rob Prouse
November 04, 2016

# re: C# NumberFormat Sections

Wow, I've been using C# since 1.0 and I never knew about that either. It is amazing the little nooks and crannies of the language that get overlooked. Thanks Rick...

David Glass
November 04, 2016

# re: C# NumberFormat Sections

Been doing this in Excel for years for financial formatting. Nice to show zero as
£ - 

Torsten
November 09, 2016

# re: C# NumberFormat Sections

Suggestion: add link to the documentation for this feature:
https://msdn.microsoft.com/en-us/library/0c899ak8(v=vs.110).aspx

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024