2009-08-05

The String.Format method

Believe it or not, one of the most powerful classes in the .NET Framework is the String class. Yep, you read it right, the String class. It has about ten millions uses, and every other class can be converted to one.

The String class also has some pretty cool methods: String.Contains and String.IsNullOrEmpty are two of my favorites, no to mention a whole other bunch of methods that every programmer uses on a a daily basis: Substring, CompareTo, IndexOf, Replace, and so on. The list is pretty huge, and they all have great uses. Specially the String.Format method, which is what I’ll talk about in this post.

Many .NET developers use String.Fomat, but from my experience, most of them only use it to concatenate strings in a more fancy, readable way. So, instead of writing this:

  1: string s = "Your name is, '" + name + "' and your age is " + age;

They’ll write this:

  1: string s = string.Format("Your name is '{0}' and your age is {1}", name, age);

What tat line says is “replace the {0} symbol with the first variable and the {1} symbol with the second variable” (and so on). Even though that’s a good start, and it’s a better solution performance-wise, there’s really a lot more we can get from the String.Format method. Take a look at this example (the dots at the beginning and end of the string are just for reference):

  1: string.Format(".{0,10}.", "right") //".     right."

Here we also have the {0} symbol, which will be replaced by the first variable, “right” in this case, but we’re also telling the method to fill with blank spaces the rest of the string until it reaches 10 characters long. The positive 10 indicates that the variable text should be placed to the right of those spaces. So if used a negative number, we’ll get the variable value to the left:

  1: string.Format(".{0,-10}.", "left"); // ".left      ."

We could also format numbers and dates, like in this examples:

  1: string.Format("{0:g}", DateTime.Now); //5/08/2009 04:02 PM
  2: string.Format("{0,-9:g5}", 3.14159); // "3.1416   "

In line 1, what we said was “give me the current date and time with a general (g) format”. In line 2, it was something like “give me the number 3.14159, formatted to deliver 5 decimal places (which include the decimal point, so ‘g5’ will give only 4 decimal numbers), and complete result, aligned to the right, with spaces to reach 9 characters”.

Is the above examples, the ‘g’ character is called a Formatting Specifier. with a number to the right of a formatting specifier, we specify the number of decimal places. Here are all the others:

Numeric formatting specifiers
  1: int x = 12345;
  2: string.Format("{0:g}", x); // 12345 (general)
  3: string.Format("{0:c}", x); // $12,345 (currency)
  4: string.Format("{0:e}", x); // 1.234500e+004 (scientific notation)
  5: string.Format("{0:f}", x); // 12345.00 (fixed-point)
  6: string.Format("{0:p}", x); // 12,345% (percent)
  7: string.Format("{0:r}", x); // 12345 (rounded)
  8: string.Format("{0:n}", x); // 12,345.00 (number with commas)
  9: string.Format("{0:d}", x); // 12345 (decimal)
 10: string.Format("{0:x}", x); // 3039 (hexadecimal)
Date and time formatting specifiers
  1: string a = DateTime.Now;
  2: string.Format("{0:d}", a); // 8/5/2009 (short date)
  3: string.Format("{0:D}", a); // Wednesday, 5 August 2009 (long date)
  4: string.Format("{0:f}", a); // Wednesday, 5 August 2009 04:35 PM (full short)
  5: string.Format("{0:F}", a); // Wednesday, 5 August 2009 04:35:17 PM (full long)
  6: string.Format("{0:g}", a); // 5/08/2009 04:35 PM (general)
  7: string.Format("{0:G}", a); // 5/08/2009 04:35:17 PM (general long)
  8: string.Format("{0:m}", a); // 5 August (month day)
  9: string.Format("{0:o}", a); // 2009-08-05T16:35:17.4687500-05:00 (round trip)
 10: string.Format("{0:R}", a); // Wed, 5 August 2009 16:35:17 GMT (RFC1123 pattern)
 11: string.Format("{0:s}", a); // 2009-08-5T16:35:17 (sortable)
 12: string.Format("{0:t}", a); // 04:35 PM (short time)
 13: string.Format("{0:T}", a); // 04:35:17 PM (long time)
 14: string.Format("{0:u}", a); // 2009-08-5 16:35:17Z (universal)
 15: string.Format("{0:U}", a); // Wednesday, 5 August 2009 4:35 PM (Universal GMT)
 16: string.Format("{0:Y}", a); // August 2009 (Year month)

Besides, you can always use custom formats for both numbers and dates:

  1: //Numbers
  2: "{0:0.0}" // 1234.6 (decimal point)
  3: "{0:0,0}" // 1,235 (thousands)
  4: "{0:0,.}" // 1 (number scaling)
  5: "{0:0%}" // 123456% (percent)
  6: "{0:00e+0}" // 12e+2 (scientific notation)
  7: //Dates an times
  8: "{0:MMM}" // Aug (month abbr)
  9: "{0:MMMM}" // August (month full)
 10: "{0:ss}" // 40 (seconds)
 11: "{0:tt}" // PM (am/pm)
 12: "{0:yy}" // 09 (year)
 13: "{0:yyyy}" // 2009 (year full)

A complete document about custom formats can de found here.

The final thing I want to talk about in the String.Format method is the conditional formatting. Let’s see:

  1: int x = 1;
  2: string.Format("{0:positive;negative;zero}", x);

The output of the String.Format depends on the value of the variable x. If the value is > 0, the output will be the word “positive”, which takes the first position after the “0:”. Obviously, if it’s < 0, it will display the word “negative”, and if it’s == 0, then it’ll show “zero”. Another example is:

  1: string.Format("{0:$#,##0.00;($#,##0.00);-}", x);

In this case, we’re not only formatting the number as a currency value, but also using parenthesis for negative values and a dash for zeroes.

So, getting to really know the String class, and in this particular case the String.Format method, is something that will open up a world of possibilities. Remember, most of the times the simplest things are the most important ones.

No hay comentarios:

Publicar un comentario

Your tips and thoughts are always welcome, and they provide good motivation: