Formatsettings or TFormatSettings in Delphi

FormatSettings
Formatsettings is a global variable of TFormatsettings record type in Delphi which is used to get local information's like DateTimeFormat, CurrencyFormat, DecimalSeparator etc. This variable was introduced in Delphi XE and before Delphi XE DateTimeFormat, DecimalSeparator, CurrencyFormat, etc. were declared as separate global variables in SysUtils.pas. 

So when we migrate a Delphi project from old Delphi version to new Delphi version we generally get following errors and to solve this issue we need to use Formatsettings.DecimalSeparator. 

Please visit my blog for more detail about such errors


Errors when we migrate a project from Delphi 7 to Delphi XE3

Undeclared identifier DecimalSeparator
Undeclared identifier CurrencyFormat
Undeclared identifier ThousandSeparator
Undeclared identifier DateSeparator
Undeclared identifier TimeSeparator
Undeclared identifierShortDateFormat 
Undeclared identifier LongDateFormat

Solution to above errors

Formatsettings.DecimalSeparator
Formatsettings.CurrencyFormat
Formatsettings.ThousandSeparator
Formatsettings.DateSeparator
Formatsettings.TimeSeparator
Formatsettings.ShortDateFormat
Formatsettings.LongDateFormat

TFormatSetings
TFormatsettings is a record in Delphi which contains local information's used in string formatting routines. It is also declared in SysUtils.pas. Each member of TFormatSettings is equivalent to the global variable with the same name

TFormatSettings = record
  CurrencyFormat: Byte;
  NegCurrFormat: Byte;
  ThousandSeparator: Char;
  DecimalSeparator: Char;
  CurrencyDecimals: Byte;
  DateSeparator: Char;
  TimeSeparator: Char;
  ListSeparator: Char;
  CurrencyString: string;
  ShortDateFormat: string;
  LongDateFormat: string;
  TimeAMString: string;
  TimePMString: string;
  ShortTimeFormat: string;
  LongTimeFormat: string;
  ShortMonthNames: array[1..12] of string;
  LongMonthNames: array[1..12] of string;
  ShortDayNames: array[1..7] of string;
  LongDayNames: array[1..7] of string;
  TwoDigitYearCenturyWindow: Word;
end;

The problem with Formatsettings is that it is a global variable so it is not suitable for multi-threading process. It is not safe to modify FormatSettings inside threads. So to overcome this issue, we should ensure that Formatsettings is modified only in main thread i.e our main application thread or we can create a new variable of TFormatsettings type and pass to the thread.

To use and modify formatsettings in a thread safe environment we have to follow these steps :

1. Define a variable of type TFormatSettings 

var
  fSettings: TFormatSettings;

2. Call GetLocaleFormatSettings to populate the TFormatSettings variable with locale information. 

GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, fSettings);

The GetLocaleFormatSettings procedure gets the LCIDWindows locale global variable values into a TFormatSettingsrecord. 
(LOCALE_USER_DEFAULT ,  LOCALE_SYSTEM_DEFAULT)

3. Pass the TFormatSettings variable as the last parameter of the string formatting routine like CurrToStrF.  

ShowMessage('Result = '+CurrToStrF(1234.56, ffCurrency, 4, fSettings));

We can create new variable of TFormatsettings type and must initialize before use by calling Create method. As it is a record type so we don’t need to free the instance.

class function Create: TFormatSettings; overload; static; inline;

Initializes a TFormatSettings record with current default values provided by the operating system

class function Create(Locale: TLocaleID): TFormatSettings; overload; platform; static;

On Windows, use the GetThreadLocale API function to get the LocalID value of the current thread. Or LOCALE_USER_DEFAULT LOCALE_SYSTEM_DEFAULT

class function Create(const LocaleName: string): TFormatSettings; overload; static;

"Language-Country" format. For example:
      - 'en-US' for U.S. English settings
      - 'en-GB' for Great Britain English settings

procedure TestFormat;
var
   str1, str2: string;
   fSettings: TFormatSettings;
begin
   fSettings:= TFormatSettings.Create('en-US');   
   str1 := FormatDateTime(strFormat.ToString, Now());
   Showmessage(str1);

   //A second instance with a different locale (used for comparison)
   fSettings:= TFormatSettings.Create('ro-RO');
   str2 := FormatDateTime(strFormat.ToString, Now());
   Showmessage (str2);
End; 

TApplication.UpdateFormatSettings
Specifies whether format settings are updated automatically when the user alters the system configuration. Use UpdateFormatSettings to control automatic updating of format settings. The default of true is set in the constructor. Using the default format settings is recommended. These settings are initialized to the Windows local.

Application.UpdateFormatSettings := False; //block refreshing format settings

SysUtils.GetFormatSettings
Resets the date and number format parameters to initial values. GetFormatSettings resets all date and number format variables to their initial values. It also initializes Formatsettings global variable.

GetFormatSettings;

Comments

  1. titanium bohr model - The Silicon World of Art
    Titanium bohr model. It titanium dab nail has an unusual but not uncommon design: it is a titanium hip straight line with titanium key ring a bar. You will see titanium astroneer an odd pattern on the top of titanium max it.

    ReplyDelete

Post a Comment

Popular posts from this blog

ShellExecute in Delphi

MS Excel Automation in Delphi

Drawing Shapes in Delphi