Jedna z mála věcí co jsem ohledně Delphi XE ještě nepopsal, jsou změny v RTL ohledně formátování času a formátování čísel. Nový způsob je zpětně kompatibilní, dá se používat jako bezpečný z hlediska vláken a jen warning při otevření starších zdrojových kódů upozorňuje, že je třeba udělat drobnou změnu.
Základem je rozšířený záznam TFormatSettings, ke kterému patří i globální proměnná FormatSettings. Položky tohoto záznamu jsou stejné jako položky z dřívějších Delphi (jako např. DecimalSeparator, ShortDateFormat atd.). Tento záznam je pomocí absolute namapován na starší proměnné, které jsou ale označeny jako deprecated, tj. při jejich použití je vypsáno varování.
[DCC Warning] Project1.dpr(14): W1000 Symbol 'DecimalSeparator'
is deprecated: 'Use FormatSettings.DecimalSeparator'
Aby bylo jednoduše dosaženo kompatibility (pozor - to nestačí na inzerovanou bezpečnost z hlediska vláken) jednoduše nahradíte DecimalSeparator za FormatSettings.DecimalSeparator jak napovídá warning a je hotovo.
To je prima, ale proč to všechno?
Protože většina funkcí jako FloatToStr, DateTimeToStr dostalo bráchu, kde jako druhý parametr je TFormatSettings a v tom případě se použijí předané informace místo globálních proměnných (které může kdokoliv modifikovat, resp. samotná RTL je obnovuje - tomu se dá mimochodem zabránit přes Application.UpdateFormatSettings).
My ale můžeme nadefinovat vlastní záznam, ten si nastavit jak chceme, uschovat ho a pak ho používat bez rizika, že nám ho někdo upraví.
Např. typická konstrukce, kdy chceme formátovat reálné číslo s desetinou tečkou dvěma způsoby.
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
f: double;
s: string;
fs: TFormatSettings;
c: char;
begin
c := DecimalSeparator; // uschovej stary oddelovac
try
DecimalSeparator := '.';
f := StrToFloat('10.1');
// [DCC Warning] Project1.dpr(14): W1000 Symbol 'DecimalSeparator' is
// deprecated: 'Use FormatSettings.DecimalSeparator'
FormatSettings.DecimalSeparator := '.'; //OK bez warningu, ale..
f := StrToFloat('10.1');
finally
DecimalSeparator := c; //vrať původní separátor
end;
// ***********************************
//Thread safe currency and date/time formatting
// fs je record, nemusim uvolnovat a můžu si ho schovat pro pozdější použití
fs := fs.Create;
// Create získa data ze systému
writeln('DecimalSeparator ', fs.DecimalSeparator);
fs.DecimalSeparator := '.'; // nastavíme vlastní separátor
f := StrToFloat('10.1', fs); //a použiji ho, a pak kdykoliv jindy
end.