Thread safe proměnné pro formátování času a oddělovače

vložil Radek Červinka 26. listopadu 2010 22:15

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.

Tagy: , ,

Novinky v Delphi

Komentáře

26.11.2010 23:54:03 #

pingback

Pingback from topsy.com

Twitter Trackbacks for
        
        Delphi.cz | Thread safe promÄ›nnĂ© pro formátovánĂ­ ÄŤasu a oddÄ›lovaÄŤe
        [delphi.cz]
        on Topsy.com

topsy.com

28.11.2010 16:15:31 #

Radim

Prikazom:

FormatSettings.DecimalSeparator := '.';

prepisujem systemove nastavenie, ktore by sa inak aplikovalo? Nap.r mohla by to byt aj - , /ciarka/?

Radim

28.11.2010 21:13:15 #

radekc

Prepisuji nastavení načtené ze systému při startu programu. Pro naše Windows je to , tj. čárka, ale pokud někde něco takového ukládám tak používám svůj formát tj. s tečkou.

Nejsem si jist zda moc rozumím tvému dotazu.

radekc

30.11.2010 17:57:47 #

Radim

Nie je horsie ney niekto napise program na anglickych Windows s cislami s . a potom kontroluje vstupne udaje regionalne s , . Stretol som sa s par /free/ programkami, kde po starte pred spustenim bolo potrebne rucne prepisat vsetky bodky na ciarky alebo naopak. Uff, uz ziadny taky nastastie nemam.

Radim

1.12.2010 10:11:38 #

JaroB

Chápu to dobře, že nastavení v Sysutils a FormatSettings je synchronizováno?

JaroB

1.12.2010 10:37:11 #

radekc

Oboje je v SysUtils

  FormatSettings: TFormatSettings absolute CurrencyString;

kde CurrencyString je prvni promennou z bloku promennych, takze diky absolute je to proste prepisovane, at menite to a nebo to.


var
  // Important: Do not change the order of these declarations, they must
  // match the declaration order of the fields in TFormatSettings exactly!
  CurrencyString: string deprecated 'Use FormatSettings.CurrencyString';
  CurrencyFormat: Byte deprecated 'Use FormatSettings.CurrencyFormat';
  CurrencyDecimals: Byte deprecated 'Use FormatSettings.CurrencyDecimals';
  DateSeparator: Char deprecated 'Use FormatSettings.DateSeparator';
  TimeSeparator: Char deprecated 'Use FormatSettings.TimeSeparator';
  ListSeparator: Char deprecated 'Use FormatSettings.ListSeparator';

radekc

21.6.2012 16:37:37 #

Ivan

"Protože většina funkcí jako FloatToStr, DateTimeToStr dostalo bráchu, kde jako druhý parametr je TFormatSettings"
Ale tohle už existuje minimálně od D7, nebo spíš déle.
Nové je jen zabalení existujících proměnných do recordu FormatSettings, čímž se thread-safetyness nijak nemění.

Ivan

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců