.Net Runtime Library for Delphi
Formatting Types

Formatting is the process of converting an instance of a class, structure, or enumeration value to its string representation, often so that the resulting string can be displayed to users or deserialized to restore the original data type.

The Delphi Framework provides rich formatting support that enables developers to address these requirements.This overview contains the following sections:
  • Formatting in the Framework Library

  • The ToString Method and Format Strings

    • Standard Format Strings

    • Custom Format Strings

    • Format Strings and .NET Framework Class Library Types

Formatting in the Framework Library
The Framework library provides several ways to modify and extend its default formatting support. These include the following:

  • Defining format specifiers that enable the string representation of an object's value to take multiple forms. For example, the "X" format specifier in the following statement converts an integer to the string representation of a hexadecimal value.

    var Console: _Console; AInt32: ClrInt32; begin Console := CoConsole.CreateInstance; AInt32 := 60312; Console.WriteLine_14(TClrInt32Helper.ToString(AInt32, 'X')); // Displays EB98. end.

  • Using format providers to take advantage of the formatting conventions of a specific culture. For example, the following statement displays a currency value by using the formatting conventions of the en-US culture.

    var Console: _Console; ADouble: ClrDouble; ACultureInfo: _CultureInfo; begin Console := CoConsole.CreateInstance; ADouble := 1632.54; ACultureInfo := CoCultureInfo.CreateInstance('en-US'); Console.WriteLine_14(TClrDoubleHelper.ToString(ADouble, 'C', ACultureInfo.AsIFormatProvider)); // The example displays the following output: // $1,632.54 end.


Relying on the default ToString method or overriding ToString is appropriate when an object has a single string representation. However, the value of an object often has multiple representations. For example, a temperature can be expressed in degrees Fahrenheit, degrees Celsius, or kelvins. Similarly, the integer value 10 can be represented in numerous ways, including 10, 10.0, 1.0e01, or $10.00.

To enable a single value to have multiple string representations, the .NET Framework uses format strings. A format string is a string that contains one or more predefined format specifiers, which are single characters or groups of characters that define how the ToString method should format its output. The format string is then passed as a parameter to the object's ToString method and determines how the string representation of that object's value should appear.

All numeric types, date and time types, and enumeration types in the .NET Framework support a predefined set of format specifiers. You can also use format strings to define multiple string representations of your application-defined data types.

Standard format strings for numeric types usually define a result string whose precise appearance is controlled by one or more property values. For example, the "C" format specifier formats a number as a currency value. When you call the ToString method with the "C" format specifier as the only parameter, the following property values from the current culture's NumberFormatInfo interface are used to define the string representation of the numeric value:

  • The CurrencySymbol property, which specifies the current culture's currency symbol.

  • The CurrencyNegativePattern or CurrencyPositivePattern property, which returns an integer that determines the following:

    • The placement of the currency symbol.

    • Whether negative values are indicated by a leading negative sign, a trailing negative sign, or parentheses.

    • Whether a space appears between the numeric value and the currency symbol.

  • The CurrencyDecimalDigits property, which defines the number of fractional digits in the result string.

  • The CurrencyDecimalSeparator property, which defines the decimal separator symbol in the result string.

  • The CurrencyGroupSeparator property, which defines the group separator symbol.

  • The CurrencyGroupSizes property, which defines the number of digits in each group to the left of the decimal.

  • The NegativeSign property, which determines the negative sign used in the result string if parentheses are not used to indicate negative values.

In addition, numeric format strings may include a precision specifier. The meaning of this specifier depends on the format string with which it is used, but it typically indicates either the total number of digits or the number of fractional digits that should appear in the result string. For example, the following example uses the "X4" standard numeric string and a precision specifier to create a string value that has four hexadecimal digits.

var Console: _Console; AByteValue: ClrByte; AByteValues: array[0..2] of ClrByte; begin Console := CoConsole.CreateInstance; AByteValues[0] := 12; AByteValues[1] := 163; AByteValues[2] := 255; for AByteValue in AByteValues do Console.WriteLine_14(TClrByteHelper.ToString(AByteValue, 'X4')); end. // The example displays the following output: // 000C // 00A3 // 00FF



Standard format strings for date and time values are aliases for custom format strings stored by a particular DateTimeFormatInfo property. For example, calling the ToString method of a date and time value with the "D" format specifier displays the date and time by using the custom format string stored in the current culture's DateTimeFormatInfo.LongDatePattern property. The following example illustrates this relationship.

var Console: _Console; ADate1: TDateTime; ACultureInfo: _CultureInfoHelper; ALongPattern: string; begin Console := CoConsole.CreateInstance; ADate1 := TClrDateTimeHelper.Parse('30/06/2009'); Console.WriteLine_15('D Format Specifier: {0:D}', ADate1); ACultureInfo := CoCultureInfoHelper.CreateInstance; ALongPattern := ACultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern; Console.WriteLine_17('''{0}'' custom format string: {1}', ALongPattern, TClrDateTimeHelper.ToString(ADate1, ALongPattern)); end. // The example displays the following output when run on a system whose // current culture is en-US: // D Format Specifier: Tuesday, June 30, 2009 // 'dddd, MMMM dd, yyyy' custom format string: Tuesday, June 30, 2009



For more information about standard date and time format strings, see Standard Date and Time Format Strings.

You can also use standard format strings to define the string representation of an application-defined object that is produced by the object's ToString(String) method. You can define the specific standard format specifiers that your object supports, and you can determine whether they are case-sensitive or case-insensitive. Your implementation of the ToString(String) method should support the following:

  • A "G" format specifier that represents a customary or common format of the object. The parameterless overload of your object's ToString method should call its ToString(String) overload and pass it the "G" standard format string.

  • Support for a format specifier that is equal to a null reference (Nothing in Visual Basic). A format specifier that is equal to a null reference should be considered equivalent to the "G" format specifier.

Custom Format StringsIn addition to the standard format strings, the .NET Framework defines custom format strings for both numeric values and date and time values. A custom format string consists of one or more custom format specifiers that define the string representation of a value. For example, the custom date and time format string "yyyy/mm/dd hh:mm:ss.ffff t zzz" converts a date to its string representation in the form "2008/11/15 07:45:00.0000 P -08:00" for the en-US culture. Similarly, the custom format string "0000" converts the integer value 12 to "0012". For a complete list of custom format strings, see Custom Date and Time Format Strings.

If a format string consists of a single custom format specifier, the format specifier should be preceded by the percent (%) symbol to avoid confusion with a standard format specifier. The following example uses the "M" custom format specifier to display a one-digit or two-digit number of the month of a particular date.

var Console: _Console; ADate1: TDateTime; begin Console := CoConsole.CreateInstance; ADate1 := TClrDateTimeHelper.Parse('08/09/2009'); Console.WriteLine_14(TClrDateTimeHelper.ToString(ADate1, '%M')); end. //Displays 9


Many standard format strings for date and time values are aliases for custom format strings that are defined by properties of the DateTimeFormatInfo object. Custom format strings also offer considerable flexibility in providing application-defined formatting for numeric values or date and time values. You can define your own custom result strings for both numeric values and date and time values by combining multiple custom format specifiers into a single custom format string. The following example defines a custom format string that displays the day of the week in parentheses after the month name, day, and year.

var Console: _Console; ADate1: TDateTime; ACustomFormat: string; begin Console := CoConsole.CreateInstance; ACustomFormat := 'MMMM dd, yyyy (dddd)'; ADate1 := TClrDateTimeHelper.Parse('28/08/2009'); Console.WriteLine_14(TClrDateTimeHelper.ToString(ADate1, ACustomFormat)); end. // The example displays the following output if run on a system// whose language is English: // August 28, 2009 (Friday)



The following example defines a custom format string that displays an Int64 value as a standard, seven-digit U.S. telephone number along with its area code.

program Example; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, CNClrLib.Host, CNClrLib.Core, CNClrLib.Core.Intf, CNClrLib.Host.Helper; var Console: _Console; ANumber: ClrInt64; AFmt: string; begin Console := CoConsole.CreateInstance; ANumber := 8009999999; AFmt := '000-000-0000'; Console.WriteLine_14(TClrInt64Helper.ToString(ANumber, AFmt)); Console.ReadKey; end. // The example displays the following output: // 800-999-9999



Although standard format strings can generally handle most of the formatting needs for your application-defined types, you may also define custom format specifiers to format your types.