String.Format is a very powerful method but the documentation at MSDN is quite wordy and spreads the details over many pages. For this post I have made quick reference to its many specifiers and for good measure added some examples to help get you started.If you would like to format a date, currency, number or just the time, String.Format is your friend.
For a trip down memory lane a little example how we did things in C. The C sprintf function takes a buffer, a formatting string, a couple of parameters and munches them together:
#include <stdio.h> int main() { char buffer[255]; sprintf(buffer,"Customer %d lives is %d years old and owns us %2.2f dollars", 1024, 96, 125.6f); printf("%s",buffer); }
This results in the following output:
Customer 1024 is 96 years old and owns us 125.50
Of course, if we made the buffer too small and the string expanded too much we might have created a buffer overrun once of C’s pesky little annoyances. And of course for each parameter we need to specify how to format them (%d for integers, %s for strings and %f for floats). Get the type wrong and things will go funny fast.
Enter String.Format and Console.WriteLine
So how do things work in C#? The String.Format method takes care of all our needs and a little more. Similar to the relationships between sprintf and printf the methods String.Format and Console.WriteLine work similary. String.Format returns a string whereas Console.WriteLine sends the resulting string to the console output.
The following should be a familiar example:
int ResultValue = 123;
string myString = String.Format(“The value is {0}”,ResultValue);
Console.WriteLine(“The value is {0}”,ResultValue);
The Index
The {0} is an index and refers to the first parameter given following the formatting string. {1},{2} to the second, third etc. You can also refer to a parameter more than once. The following is perfectly acceptable:
Console.WriteLine(“First {0}, Second {1}, Third {2}, And again the First {0}”,Value1,Value2,Value2);
Aligning the output
C# provides an alignment value that allows you to left or right align the output. Handy for screen or print formatting.
If you specify an alignment of 10 characters the resulting string will always be 10 characters even if the number only took up 4 places. The remainder is padded with spaces. If the value we want to display is longer than our given alignment size the alignment value is ignored.
Console.WriteLine(“The value is {0,10} – continue from here”,9999);
The above will output the value “9999″, and allocate 10 spaces for it. The output is right-aligned, the format method will simply add sufficient spaces to make sure the total length adds up to 10 characters.
To make the output left-aligned we need to make the number negative:
Console.WriteLine(“The value is {0,-10} – continue from here”,9999);
Displaying enumerated types
One very interesting feature of C# is the ability to display enumerated types.If you make your own enumeration wouldn’t it be nice if you could just print the values as a string literals? In fact you can as shown by the following example:
class MainClass { public enum Transport {Car = 1, Plane = 2, Motorcycle = 3} public static void Main(string[] args) { Transport peopleMover = Transport.Plane; Console.WriteLine("{0:G}",peopleMover); // string literal Console.WriteLine("{0:f}",peopleMover); // flag -- not clear Console.WriteLine("{0:d}",peopleMover); // decimal Console.WriteLine("{0:x}",peopleMover); // hexadecimal } }
This outputs:
Plane
Plane
2
00000002
Basic number formatting
When no format is specified the String.Format method applies the “g” (General) type, which results in any value passed being rendered into a standard string. The following table shows what is possible:
If the table lists (error) it means that the String.Format method threw a String.Formatting exception. This happens if the number cannot be converted properly.
Format specifier | Name | 1234.56 (double) | -100000 (int) | Description |
{0:c} | Currency | $123.45 | ($-100,000.00) | The number is converted to a string that represents a currency amount. |
{0:d} | Decimal | (error) | -100000 | Display a decimal amount, but throws an exception on non-decimal values (floats). |
{0:e} | Scientific | 1.234500e+002 | -1.000000e+005 | The number is converted to a string of the form “-d.ddd…E+ddd” or “-d.ddd…e+ddd”, where each ‘d’ indicates a digit (0-9). |
{0:f} | Fixed-point | 123.45 | -100000.00 | The number is converted to a string of the form “-ddd.ddd…” where each ‘d’ indicates a digit (0-9). The string starts with a minus sign if the number is negative. |
{0:g} | General | 123.45 | -100000 | The default format |
{0:n} | Number | 123.45 | -100,000.00 | Thousand separators are inserted between each group of three digits to the left of the decimal point. |
{0:p} | Percent | 12,345.00% | -10,000,000.00 % | The number is converted to a percentage. |
{0:r} | Round-Trip | 123.45 | (error) | Guarantees that the number can be returned to its original value on conversion from string to number. |
{0:x} or {0:X} | Hexadecimal | (error) | FFFE7960 | Use ‘X’ to produce “ABCDEF”, and ‘x’ to produce “abcdef”. |
Custom number formatting
Of course, your preferred format is not listed above and you need a few modifications made. Not a problem. Custom formatting allows for any kind of number-to-string conversion you might need:
Name | Format | Example | Input | Output |
Zero placeholder | 0 | {0:000.00} | 45.5 | 045.50 |
Digit placeholder | # | {0:###.##} | 45.5 | 45.5 |
Decimal point | . | {0:00.00} | 45.5 | 45.50 |
Thousand separator (requires 0) | , | {0:0,0} | 1000000 | 1,000,000 |
Percent (multiplies by 100) | % | {0:0%} | 45.5 | 4550% |
Scientific notation (multiple formats) | E0,E+0,E-0,e0,e+0,e-0 | {0:E0} | 1000000 | 1E+006 |
Date formats
The following table show the basic date formats obtained from calling DateTime.Now and then formatting the result. Note that different systems might produce different results depending on how the operating system is configured (think Chinese/Japanese/etc systems).
Specifier | Description | Example |
{0:d} | Short date | 2/4/2009 |
{0:D} | Long date | Wednesday, February 04, 2009 |
{0:t} | Short time | 2:59 PM |
{0:T} | Long time | 2:59:14 PM |
{0:f} | Full date/time (short time) | Wednesday, February 04, 2009 2:59 PM |
{0:F} | Full date/time (long time) | Wednesday, February 04, 2009 2:59:40 PM |
{0:g} | General date/time (short time) | 2/4/2009 2:59 PM |
{0:G} | General date/time (long time) | 2/4/2009 3:01:12 PM |
{0:M} | Month day | February 4 |
{0:R} | RFC1123 | Wed, 04 Feb 2009 15:01:55 GMT |
{0:s} | Sortable date/time ; conforms to ISO 8601 | 2009-02-04T15:02:10 |
{0:u} | Universal sortable date/time | 2009-02-04 15:02:28Z |
{0:U} | Universal sortable date/time | Wednesday, February 04, 2009 7:03:11 AM |
{0:Y} | Year month | February, 2009 |
Custom Date formatting
The custom format strings allow DateTime objects to be formatted when the standard formatting strings are not useful and you need some special.
Specifier |
Description |
Example |
Output |
d | Day of the month as a number | {0:d} | 4 |
dd | Day of the month as a number, with leading zero | {0:dd} | 04 |
ddd | Abbriviated day of the month name | {0:ddd} | Wed |
dddd | Full day of the month name | {0:dddd} | Wednesday |
f,ff,fff | Fraction of a second (repeat “f” for more precision) | {0:fff} | 405 |
gg,ggg | The era | {0:gg} | A.D. |
h | Hour (1-12 range) | {0:h} | 3 |
hh | Hour (1-12 range, with leading zero for 0-9) | {0:hh} | 03 |
H | Hour (0-23 range) | {0:H} | 15 |
HH | Hour (0-23 range with leading zero for 0-9) | {0:HH} | 03 |
m | Minutes (0-59) | {0:m} | 9 |
mm | Minutes (0-59 range with leading zero for 0-9) | {0:mm} | 09 |
M | Number of the month (0-12) | {0:M} | 2 |
MM | Number of the month (0-12 with leading zero for 0-9) | {0:MM} | 02 |
MMM | Abbreviated name of the month | {0:MMM} | Feb |
MMMM | Specifies the full name of the month | {0:MMMM} | February |
s | Seconds (0-59 range) | {0:s} | 23 |
ss | Seconds (0-59 range with leading zero for 0-9) | {0:ss} | 23 |
tt | Both characters of the AM/PM range | {0:tt} | PM |
y | The first two digits of the year (0-99) | {0:y} | 9 |
yy | The first two digits of the year (0-99) with leading zero for 0-9 | {0:yy} | 09 |
yyyy | Four digit year number, if the year is less than 1000 it has 0′s prepended | {0:yyyy} | |
zz | The timezone offset in whole hours | {0:zz} | +08 |
zzz | The timezone offset in hours and minutes | {0:zzz} | +08:00 |
: | Time seperator | {0:hh:mm} | 03:33 |
/ | Date seperator | {0:MM/yyyy} | 02/2009 |
Image credit: easement
This is a post from Martijn's C# Coding Blog.