5
votes

I know there is a global FormatSettings variable available, which is initialized with the current regional OS settings on startup. That means, when you convert strings to numbers and visa verse, e.g. in an xml file, and you exchange that files with other PCs. It can happen that such a file cannot be loaded, since the strings cannot be convertet back to numbers anymore. It depence on the DecimaleSeparator.

So my question is: Is there another globel FormatSettings variabel available, which I can use for storing persistent data into text file?

Example:

FloatToStr(Value, PersistentFormatSettings);
3
when you convert strings to numbers for JSON, XML and other formats, you should not use OS user settings, but use custom formatting routines, defines by format specifications (which may follow US tradition to some unknown extent). Personally i tend to use good old Str and Val procedures to do such conversion. But before that i read specs for those procedures and for data formats to seethat they match. And if you need variables like "XMLFormatSettings" or "JSONFormatSetting" then just introduce them. Persistent is just wrong here - it is not about persistency of the settings. - Arioch 'The
In C# there is InvariantCultur object, which can be used. Would be great if Delphi could also provide such thing. - markus_ja
@max var InvariantCulture: TFormatSettings = (...); and here you have it. However that does not automatically make it matching XML or JSON or any other independent specification - to check the matching is still your own task (or task for vendor of XML or JSON parsing/generating library). - Arioch 'The
@Arioch I know, but then I have to define it in every unit. Or at least I have to create a unit, which I have to add to each project, where it is used. If it would be provided by the framework, it would be much easier. - markus_ja
MUCH easier ? creating a unit once is A LOT of work ? well... Just use Str and Val and you have that "persistence" for granted. - Arioch 'The

3 Answers

1
votes

No, there is no such variable. You're welcome to define one yourself, though. Declare it in a unit, and then use that unit wherever you need your locale-independent settings.

1
votes

In modern Delphi versions, the global FormatSettings variable(s) are deprecated (mainly because they are not thread-safe). Every RTL function that uses formatting variables has been overloaded to take an optional TFormatSettings record as input. That allows you to not only use thread-specific formatting settings, but also custom formatting settings on a per-use basis, without affecting any other formatting uses. For example:

var
  Fmt: TFormatSettings;
  S: String;
begin
  Fmt := TFormatSettings.Create; // get default settings
  //
  // or:
  // Fmt := TFormatSettings.Create(SomeLocaleID); // get locale-specific settings
  //
  // or:
  // Fmt := TFormatSettings.Create(SomeLocaleName); // get locale-specific settings
  //

  // customize its fields to use whatever you want...
  Fmt.DecimalSeparator := ...;
  Fmt.ThousandSeparator := ...;

  // now format it...
  S := FloatToStr(Value, Fmt);
end;
0
votes

Use FormatSettings variable from SysUtils. So you can save a lot of time (see in TFormatSettings constructor) and do not initialize this large record each time you're converting float - you do not need to create a new TFormatSettings record. Btw you can use simple FloatToStr(val).

FormatSettings does not marked as deprecated, but is not thread-safe. You can read this variable from any threads (= you can use FloatToStr from any parallel threads), but write to FormatSettings only from one thread (e.g. changing separators in your Core or main Form constructor) and before other threads start to read it (= use FloatToStr).