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.