.NET Format String 101

"I see stuff like {0,-8:G2} passed in as a format string. What exactly does that do?" -- Very Confused String Formatter

The above format can be translated into this:

"{<argument index>[,<alignment>][:<formatString><zeros>]}"

argument index: This represent which argument goes into the string.

String.Format("first = {0};second = {1}", "apple", "orange");

String.Format("first = {1};second = {0}", "apple", "orange");


gives the following strings:


"first = apple;second = orange"

"first = orange;second = apple"


alignment (optional): This represent the minimal length of the string.

Postive values, the string argument will be right justified and if the string is not long enough, the string will be padded with spaces on the left.

Negative values, the string argument will be left justied and if the string is not long enough, the string will be padded with spaces on the right.

If this value was not specified, we will default to the length of the string argument.


String.Format("{0,-10}", "apple");      //"apple     "

String.Format("{0,10}", "apple");       //"     apple"

format string (optional): This represent the format code.

Numeric format specifier is available here. (e.g. C, G...etc.)
Datetime format specifier is available here.

Enumeration format specifier is available here.

Custom Numeric format specifier is available here. (e.g. 0. #...etc.)


Custom formatting is kinda hard to understand. The best way I know how to explain something is via code:


int pos = 10;

int neg = -10;

int bigpos = 123456;

int bigneg = -123456;

int zero = 0;

string strInt = "120ab";


String.Format("{0:00000}", pos);      //"00010"

String.Format("{0:00000}", neg);      //"-00010"

String.Format("{0:00000}", bigpos);   //"123456"

String.Format("{0:00000}", bigneg);   //"-123456"

String.Format("{0:00000}", zero);     //"00000"

String.Format("{0:00000}", strInt);   //"120ab"

String.Format("{0:#####}", pos);      //"10"

String.Format("{0:#####}", neg);      //"-10"

String.Format("{0:#####}", bigpos);   //"123456"

String.Format("{0:#####}", bigneg);   //"-123456"

String.Format("{0:#####}", zero);     //""

String.Format("{0:#####}", strInt);   //"120ab"

While playing around with this, I made an interesting observation:


String.Format("{0:X00000}", pos);      //"A"

String.Format("{0:X00000}", neg);      //"FFFFFFF6"

String.Format("{0:X#####}", pos);      //"X10"

String.Format("{0:X#####}", neg);      //"-X10"


The "0" specifier works well with other numeric specifier, but the "#" doesn't. Umm... I think the "Custom Numeric Format String" probably deserve a whole post of it's own. Since this is only the "101" post, I'll move on to the next argument in the format string.



zeros (optional): It actually has a different meaning depending on which numeric specifier you use.


int neg = -10;

int pos = 10;

// C or c (Currency): It represent how many decimal place of zeros to show.

String.Format("{0:C4}", pos);      //"$10.0000"

String.Format("{0:C4}", neg);      //"($10.0000)"


// D or d (Decimal): It represent leading zeros

String.Format("{0:D4}", pos);      //"0010"

String.Format("{0:D4}", neg);      //"-0010"


// E or e (Exponential): It represent how many decimal places of zeros to show.

String.Format("{0:E4}", pos);      //"1.0000E+001"

String.Format("{0:E4}", neg);      //"-1.0000E+001"


// F or f (Fixed-point): It represent how many decimal places of zeros to show.

String.Format("{0:F4}", pos);      //"10.0000"

String.Format("{0:F4}", neg);      //"-10.0000"


// G or g (General): This does nothing

String.Format("{0:G4}", pos);      //"10"

String.Format("{0:G4}", neg);      //"-10"


// N or n (Number): It represent how many decimal places of zeros to show.

String.Format("{0:N4}", pos);      //"10.0000"

String.Format("{0:N4}", neg);      //"-10.0000"


// P or p (Percent): It represent how many decimal places of zeros to show.

String.Format("{0:P4}", pos);      //"1,000.0000%"

String.Format("{0:P4}", neg);      //"-1,000.0000%"


// R or r (Round-Trip): This is invalid, FormatException is thrown.

String.Format("{0:R4}", pos);      //FormatException thrown

String.Format("{0:R4}", neg);      //FormatException thrown


// X or x (Hex): It represent leading zeros

String.Format("{0:X4}", pos);      //"000A"

String.Format("{0:X4}", neg);      //"FFFFFFF6"


// nothing: This is invalid, no exception is thrown.

String.Format("{0:4}", pos));      //"4"

String.Format("{0:4}", neg));      //"-4"

In summary, there are four types of behaviour when using this <zeros> specifier:

Leading Zeros: D, X

Trailing Zeros: C, E, F, N, P

Nothing: G

Invalid: R, <empty>


Now, that we've gone through the valid specifiers, you can actually use this in more than just String.Format(). For example, when using this with Byte.ToString():


Byte b = 10;

b.ToString("D4");      //"0010"

b.ToString("X4");      //"000A"


Wow... this was way longer than I expected. The BCL team is having blog day today, I need to get back to posting something for the BCLWeblog.

<Editorial Comment>

One of the lesson I learnt from an earlier post is that, readers are not interested in a post that doesn't give you more information than what MSDN provides. Instead, readers are more interested in seeing stuff that are not available on MSDN. So when I was doing research to post about this topic, I found that MSDN actually talks about exactly what the {0,-8:G2} format does. It is just not easy to find nor centrally located.

For example, in the ToString MSDN Doc, the "Remarks" section covered some basic rules on what a "format string" is. In the String.Format MSDN Doc, the "Remarks" section actually have a pretty detail explaination of what the above format does. Furthermore, MSDN provides a format string overview as well as a the table that specifies all the values that are allowed.

This puts me in an interesting position when writing about this topic. MSDN actually have lots of info that cover it. But since I have also heard more than one person being confused about this topic, I decided to post a summary of the documents and more examples. Do you think this is useful? Should I just stick to posting exclusively on non-MSDN topics?

</Editorial Comment>

Comments (81)
  1. Barry Kelly says:

    The best thing would be to try and get some improvement on MSDN. Every time I need to look up String.Format on MSDN, I waste about 15 minutes trying to find and figure out what I need.

    Usually what I’m looking for is the equivalent of "%10.3f" or similar in C/C++, and I keep forgetting the .NET equivalent. It might be useful to include a translation from familiar (to us old fogeys) printf-style format strings to the .NET style.

    At this stage, I’ve learned that it is {0,10:F3} (or whatever index), but it took pavlovian pain to remember.

  2. KathyKam says:

    We’re having a doc update pretty soon. I’m also working closely with our doc team to get some of the stuff I publish here (or some of the stuff the team publish at BCLWeblog)updated on MSDN as well. If you find a particular area confusing, let us know!

  3. mikeb says:

    I’m happy to find out that I’m not the only one who found it difficult to locate this information in MSDN.

    I have no problems with the basics of .NET string formatting, but it has always been a pain to locate the custom format strings.

  4. Johan Asp says:

    very good post..

    thank you!

  5. Brett says:

    I agree with the above–very good post.  Simple and to the point.


  6. Matt says:

    I agree, this has been very helpful!

    <adds to favorites>

    Good job!

  7. gfh says:


  8. Umair says:

    Very good post. I agree that its extremely difficult to search on MSDN. MSDN should be upgraded to have good search feature.

  9. chrisslatt says:

    I always fall back on this post as a reference:


    Short, sweet and to the point.

  10. kjetil says:

    Very helpful. The MSDN help is hard to locate and hard to use. Here I got the info I need with the exsamples it need. Simple and clean. You should copy this almost "as is" into the MSDN and leave what’s there for "additional info".


  11. Glad to find that I am not the only one who wants a good reference on .NET string formatting.http://blogs.msdn.com/kathykam/archive/2006/03/29/564426.aspx-cla

  12. Wolfgang Kaisers says:

    Excellent Information.

    I was looking for a simple problem like "How do I add leading zeros to a String representing a Number so that it has a fixed length (e.g. 04 and 10)?"

    The msdn sites are too complex in this topic and contain no useful Examples therefore I really appreciate this site.

  13. km_rau says:

    I wish i had found this two or three hours before. It would have saved a good piece of time. Yet i’m still looking for the answer to a simple question: How can i format an integer to a string of a fixed length with leading spaces? I mean, how do i format the integer 26 to " 26" and 9 to "  9"?

  14. Kannan says:

    This is a good one for the msdn wiki.

  15. KathyKam says:

    Thank you so much for the great positive feedback! I have pinged our UE manager about the issues with string format (along with some of your feedback about MSDN). Hopefully, we can roll out a change in the next release.

  16. Salai says:

    I need help on how do we format

    in a text box

    like putting commas to represent the currencyvalue


    amount = 12,223,333

    when ever we tried to change the display has to change to the normal value

  17. Anilk says:

    Very good repository of various Formating options.

  18. Alan Howard says:

    Very nice description.

    Now, how do you format the equivalent of

    int  width = 7;

    int value = 10;

    printf ("%*d", width, value);

  19. Jay Gulati says:

    I like the arrticle and is very helpful and I do need to goto this page all the time.

    Here is another link which has date formats also included.


  20. David says:

    Very handy post with great explanations and examples.  The fixed point formatting was just what I needed.  Cheers for knowledge KK.

  21. Kathy Kam says:

    &quot;I see stuff like&amp;nbsp;&quot;zz&quot; passed into DateTime.ToString(). What exactly does that do?&quot; — Very Confused…

  22. Kathy Kam says:

    "I see stuff like "zz" passed into DateTime.ToString(). What exactly does that do?" — Very Confused

  23. Ericson Mar says:


    “{0:#0.00}” supposed to yeild 2 decimal places always right?

    This doesn’t work (at lease not with the decimal type). I tried multiple cases and it just doesn’t do anything to the format.

    It’s weird. I tried “{0:#,##0.00}” and it works for ONLY values > 1000.

  24. KathyKam says:

    Hi Ericson Mar,

    Using .NET framework 2.0

    Console.WriteLine(“{0:#0.00}”, 1);

    writes “1.00” for me.

    Console.WriteLine(“{0:#,##0.00}”, 1);

    writes “1.00” for me as well.

    If you honestly think there is a bug, try submitting it here: http://connect.microsoft.com/



  25. Ericson Mar says:

    OK, I narrowed down the bug.

    Using .NET 1.1.

    When I do and excel export…
    Response.ContentType = “application/vnd.ms-excel”;

    …the “{0:#0.00}”, “{0:#,##0.00}” formatting only works for < 1000. Specifically, I used a Datagrid (not sure which part is buggy). But when I just display it on the page, the formatting works.

  26. KathyKam says:

    Hi Ericson Mar,

    It’s best for you to submit your issues via http://connect.microsoft.com. Someone at Microsoft can help you narrow down your issue to see whether it is really a bug.



  27. jsm says:

    The link for DateTime format specifiers is incorrect.  The correct link is (I think):


  28. @Alan Howard:

    Now, how do you format the equivalent of

    int  width = 7;

    int value = 10;

    printf ("%*d", width, value);


    myString = String.Format(String.Format("{{0:F{0}}", width), value);

    Something similar to that, using the concept that the format string can be made from a formatted string.


  29. harrra1 says:

    Very good read.  Brief, exact and to the point.  YEAH!!!!

  30. rajesh says:

    really good post…………….

  31. billys says:

    Hello! I am Billy Johnson Nice design. Enjoy! Good site! OK. 0n79p7k .

  32. Geoff says:

    I think your description for the lines below might be incorrect??

    String.Format("{0:N4}", pos);      //"10"

    String.Format("{0:N4}", neg);      //"-10"    

    Did you mean output ?

    // "10.0000"

    // "-10.0000"

  33. Johan says:

    I’m trying to change the decimal point that is used by Format() from "," (the default in my country) to ".".

    How can I do this?

  34. kburn says:

    nice article..

    it helped me get out of troubles 🙂


  35. Kimi Rakkionen says:

    Pls help me in Beginners level

  36. Miek says:

    Want to find something on MSDN? Use Google;)

  37. Phil says:

    I always knew how to format a date that has a leading zero if necessary with the Microsoft.VisualBasic namespace, but I wanted to do it in .NET2.  After a days of searching, I finally found how to do it by piecing together bits of a page here and there. But I asked  myself, if I wanted to do percentage, or currency, how would I do those?  I used Google to try to find out, but to no avail.

    I then heard about DotNet Developer’s Search Engine from Dan Appleman on DotNet Rocks.  With that search engine, I found this web page.  This article is awesome!  For my vote, I’d like to see more articles on MSDN content like this.

  38. Phil says:

    I always knew how to format a date that has a leading zero if necessary with the Microsoft.VisualBasic namespace, but I wanted to do it in .NET2.  After a days of searching, I finally found how to do it by piecing together bits of a page here and there. But I asked  myself, if I wanted to do percentage, or currency, how would I do those?  I used Google to try to find out, but to no avail.

    I then heard about DotNet Developer’s Search Engine from Dan Appleman on DotNet Rocks.  With that search engine, I found this web page.  This article is awesome!  For my vote, I’d like to see more articles on MSDN content like this.

  39. Lew Grant says:

    Thanks, this was very helpful, why can’t MSDN include articles as good as this?

  40. miamidot says:

    Where can I find the list of formatting rules? I don’t wish to depend on a blog page to find out the formatting rules. I also don’t wish to depend on examples which do not give me an exhaustive set of rules.

    When I look in java or c++ println or printf manual pages, the link to the sprintf formatting characters and rules are part of the page.

    Let’s say b is a byte array of 3 elements {0xa7, 0x6f, 0xdd}. I would like to print b as "A7 6F DD ". So I attempted

    String.Format((string)fmt, (byte[]) b);

    What should variable fmt be:

    fmt = "{0:X}" – no it didn’t work

    fmt = "{X}" – oops, formatting exception.

    I cannot find any example showing how to format to output an array. Neither could I find the formatting rules to output an array.

    When I read the java or c++ manual pages, the word "format" is a link to the sprintf rules. Why can’t MSDN simply place a link under the word "format" to the formatting rules right in the manual page of String.Format? Why do I have to search high and low in an attempt to locate the formatting rules?

  41. mel says:

    The msdn is really lacking these days.  That is how I came to this post.  I am starting to stay away from all links that I see pointing to it.

  42. Darren says:

    Good article.  Out of interest, does anyone know how to force a leading sign, eg. -10 would show ‘-10’, 10 would show ‘+10’?

  43. CJLopez says:

    Finally, someone who explains clearly how to use the format string.

    I just lose like 2 hours trying to understand what is on the msdn about the format string. Yeah, they the examples, but here i can find even more specific info about the formats, thanks, i hope all the explanation of every aspect of msdn would be like you state this, xD

  44. Advait Supnekar says:

    Very good article… resolved my queries!


  45. CJLopez says:

    Just a little question. I got a date on the format dd/mm/yyyy and i need it to be formated yyyymmdd so i just split the date using the slash carachter, and then i just readded to the original date variable but then, to reformat a 1 digit number, like march that is the third month, i wanted to be 03, i tried to format it with {0:D2} but i never came to get what I wanted, the code goes like this:

    date() = act_date.ToString.Split("/")

    act_date = date(2) + String.Format("{0:D2}", date(1)) + String.Format("{0:D2}", date(0))

    The result always was yyyymd, does this kind of format only works on integer? if so, how can i make it work for strings?

  46. codputer says:

    Editorial Comment – Are you kidding?  I have been looking for something like this for ages!  I’ve printed it off and given to everyone of my developers.  It now hangs proudly in everyones cubicle@

  47. jeza says:

    hot to use String.Format to show only specified length of chars?

    String a = "abcdefghijk";

    i wanna it so it shows only first 5 chars ("abcde")

    Console.WriteLine(String.Format("{0,?:?}", a));

  48. Alister says:

    To force output to have a leading sign

    String.Format("+0;-0;0", 10)

    will do it.

    It goes "format for positive;format for negative; format for zero"

    If you use this type of format the sign is suppressed so you have to explicitly put it in the formatting string

  49. Dan says:

    Can I use string.format to take a value that is equal to A or I and replace the A with Active and I with Inactive?

  50. John says:

    Thanks for this page.  It looks like this page was offered as help, over a year ago, and MSDN still hasn’t gotten it.

    I found this page by searching google.  Searching & looking through MSDN for a similar page, with this information that was sanely & logically laid out, was a huge waste of time.

  51. Hal says:

    this is great, solve my problem

  52. Brian says:

    Thanks – ever thought of re-writing the MS .net documentation (someone ought to!)?

    You resolved my problem on how to format a float to a 2DP string in <20 seconds – Microsoft books and web seem to think formatting examples and info are a state secret – oh and take you round in circles 🙂


  53. Siddharth says:

    Really a good post and helpful

  54. Symo says:

    Very useful info – won’t need my ‘Formats you can never find.doc’ I made out of frustration at the poor MSDN help on string formats any more 🙂

  55. Mark B says:

    Thanks – you helped with my leading zeros issue – when trying to convert seconds into a string of HH:MM:SS.

    Resulting formula thanks to you is


  56. ThaiDev says:

    Thanks, but i have some question

    Can I trim data in place holder ?

    ex : string.Format("{0}", "abc    ")

  57. Mohamed Faramawi says:

    Interesting post and excellent reference , it was always hard to me to remember formatting tricks, but good you gathered them out and put it here for us. Thanks!

  58. Gurjeet Saini says:

    Very useful Custom formatting info of .NET Format String

  59. Sujay Ghosh says:

    Hi Kathy ,

    Nice compilation .

    Can you please provide an example with IFormatProvider .

    I am trying to show up the string in the InstalledCultureUi , but I dont see the string that way,.

    For example :

    US – English : 12.34

    Norway – 12,34

    Thanks ,


  60. Wow, this is a very actively commented post.  🙂  I just wanted to add my kudos.  Your post is very well written.  Unfortunately, I had to go through several others before finding yours!  This topic is getting play for a whole new audience with the advent of PowerShell.  Sysadmins like me aren’t as familiar with MSDN as you devs, so a summary article like this one is definitely valuable.


    Co-Host, PowerScripting Podcast (http://powerscripting.net)

  61. Chris says:

    I would have never found this even with my familiarity using MSDN.  I do a lot of work translating custom classes and XML to fixed length formats and this is by far the best tips I’ve read.  Thanks!

    ps you know your post rocks because 2 years later people are still commenting on it!

  62. John says:

    Very informative post, unfortunately, I’m still looking for a solution to my problem… why oh why does it auto multiply %s by 100?  Such a pain.  

  63. Mauricio Sougarret says:

    Excellent!!!!, Very informative… Why they don´t use something similar to your explanation on MSDN is a mystery to me!!!

  64. Dermanyon says:

    Thank you very much. Thats examples help me too much.

  65. Joyce says:

    I am trying to format the SSN, does this function work for that?  I am trying to insert dashes (-)

  66. John says:

    Absolutely brilliant.!!!

    I really loathe trying to locate useful information on MSDN, and when it is found, a big percentage of the examples are only useful if you already know the subject and just want a represher.

    I only go there if I can’t find it on google, especially with the changes which basically direct us to sites which are more easily found on google.

    Keep up the good work, thanks.!!

  67. Sid says:

    This is way better than MSDN. Thank you for a good post. Saved me time and is written to the point.



  68. SomeGuy says:

    I concur that this info was and still is wicked hard to locate on MSDN. Who writes the stuff on MSDN anyhow? Are the people who write it actually forced to eat their own dog food and use it once in awhile? Do they know how labyrinthian it is? I’m going to go out on a limb and guess that they are not developers and they have never had to actually search through/use their own documentation. If they are developers, I apologize and sell my MSFT stock.

  69. Patrick says:

    Great Reference!!!

    Thank you!

  70. Geoff says:

    Again you have saved me the torment of wading through MSDN…

    Thank you ever so much for a marvelous post!

  71. amirrez4 says:

    thanks !! that helped me alot…

  72. DrDad says:

    I have never found documentation on how to insert a literal curly bracket into a format string. It’s done by doubling, a la:

    Console.WriteLine("{{stuff and junk}} {0}", "hah");


    {stuff and junk} hah

    And I add my voice to those who complain that MSDN documentation is really annoying

  73. Thanks for the great post.  I come back to this article repeatedly as a reference. Thanks!


  74. Larry Rodgers says:

    Keep up the good work.  I looked all over (yes, even on MSDN, which never helps me) to find the info you gave in this article.

Comments are closed.

Skip to main content