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.

Leave a Reply

Your email address will not be published. Required fields are marked *