Formatting and Parsing
Formatting means converting to a string.
Parsing means converting from a string.
ToString
Gives meaningful output on all simple value types – bool, DateTime, DateTimeOffset, TimeSpan, Guid.
// The simplest formatting mechanism is the ToString method. string s = true.ToString(); // Parse does the reverse: bool b = bool.Parse (s);
Parse
FormatException is thrown when parsing fails.
TryParse method returns false if the conversation fails rather than throwing exception.
// TryParse avoids a FormatException in case of error:
int i;
int.TryParse ("qwerty", out i).Dump ("Successful");
int.TryParse ("123", out i).Dump ("Successful");
Parse and TryParse methods on DateTime(Offset) and the numeric types respect local culture settings. It can be changed by specifying a CultureInfo object.
// Culture trap:
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo ("de-DE"); // Germany
double.Parse ("1.234").Dump ("Parsing 1.234"); // 1234
// Specifying invariant culture fixes this:
double.Parse ("1.234", CultureInfo.InvariantCulture).Dump ("Parsing 1.234 Invariantly");
(1.234).ToString ().Dump ("1.234.ToString()");
(1.234).ToString (CultureInfo.InvariantCulture).Dump ("1.234.ToString Invariant");
Format Providers
The gateway to using a format provider is IFormattable.
public interface IFormattable
{
//first argument is the format string
//second argument is the format provider
string ToString (string format, IFormatProvider formatP{rovider);
}
The format string provides instructions and the format provider determines how the instructions are translated.
NumberFormatInfo f = new NumberFormatInfo();
f.CurrencySymbol = "$$";
Console.WriteLine (3.ToString ("C", f)); // $$ 3.00
// The default format provider is CultureInfo.CurrentCulture:
Console.WriteLine (10.3.ToString ("C", null));
// For convenience, most types overload ToString such that you can omit a null provider:
Console.WriteLine (10.3.ToString ("C"));
Console.WriteLine (10.3.ToString ("F4")); // (Fix to 4 D.P.)
.NET Framework define three format providers: NumberFormatInfo, DateTimeFormatInfo, CultureInfo.
Format providers and CultureInfo
Returning the object applicable to the culture’s regional settings.
// Requesting a specific culture (english language in Great Britain):
CultureInfo uk = CultureInfo.GetCultureInfo ("en-GB");
Console.WriteLine (3.ToString ("C", uk)); // £3.00
Invariant culture is always the same, regardless of the computer’s settings. It is based on American culture.
// Invariant culture:
DateTime dt = new DateTime (2000, 1, 2);
CultureInfo iv = CultureInfo.InvariantCulture;
Console.WriteLine (dt.ToString (iv)); // 01/02/2000 00:00:00
Console.WriteLine (dt.ToString ("d", iv)); // 01/02/2000
Using NumberFormatInfo or DateTimeFormatInfo
The initial settings for a NumberFormatInfo or DateTimeFormatInfo are based on the invariant culture.
// Creating a custom NumberFormatInfo:
NumberFormatInfo f = new NumberFormatInfo ();
f.NumberGroupSeparator = " ";
Console.WriteLine (12345.6789.ToString ("N3", f)); // 12 345.679
// Cloning:
NumberFormatInfo f2 = (NumberFormatInfo) CultureInfo.CurrentCulture.NumberFormat.Clone();
// Now we can edit f2:
f2.NumberGroupSeparator = "*";
Console.WriteLine (12345.6789.ToString ("N3", f2)); // 12 345.679
Composite formatting
Allows you to combine variable substitution with format strings.
string composite = "Credit={0:C}";
Console.WriteLine (string.Format (composite, 500)); // Credit=$500.00
Console.WriteLine ("Credit={0:C}", 500); // Credit=$500.00
{
object someObject = DateTime.Now;
string s = string.Format (CultureInfo.InvariantCulture, "{0}", someObject);
}
// Equivalent to:
{
object someObject = DateTime.Now;
string s;
if (someObject is IFormattable)
s = ((IFormattable)someObject).ToString (null, CultureInfo.InvariantCulture);
else if (someObject == null)
s = "";
else
s = someObject.ToString();
}
Parsing with format providers
NumberStyles and DateTimeStyles control how parsing work: they let you specify such things as whether parentheses or a currency symbol can appear in the input string.
// There’s no standard interface for parsing through a format provider; instead use Parse/TryParse methods on the target types:
try
{
int error = int.Parse ("(2)"); // Exception thrown
}
catch (FormatException ex) { ex.Dump(); }
int minusTwo = int.Parse ("(2)", NumberStyles.Integer | NumberStyles.AllowParentheses); // OK
minusTwo.Dump();
decimal fivePointTwo = decimal.Parse ("£5.20", NumberStyles.Currency, CultureInfo.GetCultureInfo ("en-GB"));
fivePointTwo.Dump();
IFormatProvider and ICustomFormatter
public interface IFormatProvider {object GetFormat (Type formatType); }
The purpose of this method is to provide indirection where it allows CultureInfo to defer to an appropriate NumberFormatInfo or DateTimeInfo object to do the work.