Recent

Author Topic: TryStrToDate - do not read, if you do not believe in miracles  (Read 2175 times)

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11459
  • FPC developer.
Re: TryStrToDate - do not read, if you do not believe in miracles
« Reply #15 on: January 29, 2023, 04:11:03 pm »
IMHO, it is less error prone. I use it like Thaddy showed for number formatting. Decimal separator here is comma, but sometimes I need to format numbers from (or to) dot decimal separator. I usually have (global :)) variable, set up early (in .lpr) and then just use when I need specific format.

That's and old trick from Delphi, I use:

Code: [Select]
const
  lCID_Dutch   = 1043; // Belgian 2067
  LCID_French  = 1067; // France
  LCID_English = 2057; // British
  LCID_german  = 1031; // Germany
  LCID_Spanish = 1034; // Spain traditional
  LCID_Spanish_modern = 3082; // Spain modern.
  LCID_American= 1033;

var Englishformatsettings : TFormatSettings;

englishformatsettings:=getlocaleformatsettings(LCID_English,Englishformatsettings); // windows only afaik.

I believe I define my own LCID because etiher Delphi or FPC didn't have a complete list.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TryStrToDate - do not read, if you do not believe in miracles
« Reply #16 on: January 29, 2023, 04:46:50 pm »
... Decimal separator here is comma, but sometimes I need to format numbers from (or to) dot decimal separator. I usually have (global :)) variable, set up early (in .lpr) and then just use when I need specific format.

That can hurt you.
Windows can send a message that local settings have changed, and your application (on Windows) will reset the global DefaultFormatSettings to whatever Windows says it is now.
So, if at start you change DefaultFormatSettings.DecimalSeparator to '.' (dot) and use that (DefaultFormatSetting.Decimalseparator)  throughout your program, at some point it'll be reverted to ',' (comma) and your conversions wil either fail (if you use Val or TryStrToFloat) or raise an exception (if you use StrToFloat).

It's not a theoretical problem. In the past I had an application crash upon a user with a message like "1.23 is not a valid floating point value".
That baffled me for a long time, since at program start I would set DecimalSeparator to '.' (dot).
(Note: this was before the overloads with TFormatSettings were introduced in Delphi, so changing global DecimalSeparator was the only thing one could do.)
(And yes: you can fix that by telling your program to ignore this particular Windows message: Application.UpdateFormatSettings := False)

Bart

dseligo

  • Hero Member
  • *****
  • Posts: 1222
Re: TryStrToDate - do not read, if you do not believe in miracles
« Reply #17 on: January 29, 2023, 06:49:06 pm »
... Decimal separator here is comma, but sometimes I need to format numbers from (or to) dot decimal separator. I usually have (global :)) variable, set up early (in .lpr) and then just use when I need specific format.

That can hurt you.
Windows can send a message that local settings have changed, and your application (on Windows) will reset the global DefaultFormatSettings to whatever Windows says it is now.
So, if at start you change DefaultFormatSettings.DecimalSeparator to '.' (dot) and use that (DefaultFormatSetting.Decimalseparator)  throughout your program, at some point it'll be reverted to ',' (comma) and your conversions wil either fail (if you use Val or TryStrToFloat) or raise an exception (if you use StrToFloat).

It's not a theoretical problem. In the past I had an application crash upon a user with a message like "1.23 is not a valid floating point value".
That baffled me for a long time, since at program start I would set DecimalSeparator to '.' (dot).
(Note: this was before the overloads with TFormatSettings were introduced in Delphi, so changing global DecimalSeparator was the only thing one could do.)
(And yes: you can fix that by telling your program to ignore this particular Windows message: Application.UpdateFormatSettings := False)

Bart

What do you mean?
I have variable named like this:
Code: Pascal  [Select][+][-]
  1. var fsFormat_tocka:TFormatSettings;

Are you saying that Windows will change my variable?

TRon

  • Hero Member
  • *****
  • Posts: 2540
Re: TryStrToDate - do not read, if you do not believe in miracles
« Reply #18 on: January 29, 2023, 07:11:46 pm »
What do you mean?
I have variable named like this:
Code: Pascal  [Select][+][-]
  1. var fsFormat_tocka:TFormatSettings;

Are you saying that Windows will change my variable?
No, not your variable. But your variable is 'frozen' in that you have your settings in there that you wish to use.

The notification that Bart talks can occur when you have your variable "configured" to for example use a "/" as date separator but the notification /could/ change the system/application-wide behaviour in that it will now accept dates with another separator e.g. "-". Same for all other locale related settings.

e.g. in that case your variable is not 'up-to-date" anymore to reflect the current situation.

And yes it happens more frequently then most people realize. I just encountered it because at one specifc account on my machine I forgot to adjust the locale settings. I noticed it because I had libreoffice calc opened so i changed the locale settings to match as wanted. And calc needed to adjust all the separators and format the dates/times correctly again.

You could ofc always argue that whenever that happens your code will react properly on the notification and you change your variable accordingly, before your code continues. But I suspect that that was not in your thoughts when you replied (please correct me when wrong).
« Last Edit: January 29, 2023, 07:15:51 pm by TRon »

dseligo

  • Hero Member
  • *****
  • Posts: 1222
Re: TryStrToDate - do not read, if you do not believe in miracles
« Reply #19 on: January 29, 2023, 07:39:05 pm »
What do you mean?
I have variable named like this:
Code: Pascal  [Select][+][-]
  1. var fsFormat_tocka:TFormatSettings;

Are you saying that Windows will change my variable?
No, not your variable. But your variable is 'frozen' in that you have your settings in there that you wish to use.

The notification that Bart talks can occur when you have your variable "configured" to for example use a "/" as date separator but the notification /could/ change the system/application-wide behaviour in that it will now accept dates with another separator e.g. "-". Same for all other locale related settings.

e.g. in that case your variable is not 'up-to-date" anymore to reflect the current situation.

And yes it happens more frequently then most people realize. I just encountered it because at one specifc account on my machine I forgot to adjust the locale settings. I noticed it because I had libreoffice calc opened so i changed the locale settings to match as wanted. And calc needed to adjust all the separators and format the dates/times correctly again.

You could ofc always argue that whenever that happens your code will react properly on the notification and you change your variable accordingly, before your code continues. But I suspect that that was not in your thoughts when you replied (please correct me when wrong).

But I don't want my variable to reflect changes. When I send data to IRS i.e., I always want decimal point. Or when I read exchange rate from bank. I don't care what user set in OS.
Also, I have more of this variables, such as: quantity format, amount format and similar. If my program works on couple of computers on network, I don't want to print invoices differently just because some salesperson decided to change format on his computer. So when I print documents, I use format from database so everyone has same output. Never had problems with that.

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TryStrToDate - do not read, if you do not believe in miracles
« Reply #20 on: January 29, 2023, 09:59:32 pm »
What do you mean?
I have variable named like this:

It seems I misunderstood you.
Your scenario is perfectly safe.

Sorry for the confusion.

Bart

 

TinyPortal © 2005-2018