Recent

Author Topic: StrToDateTime problems  (Read 806 times)

andyH

  • Full Member
  • ***
  • Posts: 102
StrToDateTime problems
« on: January 12, 2026, 09:05:56 pm »
Mods, if in the wrong topic area, please move.

It doesn't get much simpler:

Code: Pascal  [Select][+][-]
  1. program parseSID;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   {$IFDEF UNIX}
  5.   cthreads,
  6.   {$ENDIF}
  7.   Classes, StrUtils, Types, sysutils, dateutils;
  8. var
  9.   ReadingDate : TDateTime;
  10.   testdate :  string;
  11.  
  12. begin
  13.   Writeln ('ShortDateFormat ',ShortDateFormat);
  14.   //ShortDateFormat:= 'dd/mm/yyyy';
  15.   Writeln ('ShortDateFormat ',ShortDateFormat);
  16.   testdate:= '29/10/2025';
  17.   ReadingDate:= StrToDateTime(testdate);
  18. end.

Program outputs ShortDateFormat d/m/y or dd/mm/yyyy depending what is commented out (to confirm the date format is correct) and then errors out with EConvertError: "29/10/2025" is not a valid date format (see screenshot). I've tried various permutations - different date, adding in time, e.g. 29/10/2025 10:15, replacing testdate with a string '29/10/2025'. All generate the same error, invalid date format.

Obviously doing something wrong but can't see it?

If relevant, lazarus 3.8, fpc 3.2.2 running under linux.

Nimbus

  • Jr. Member
  • **
  • Posts: 84
Re: StrToDateTime problems
« Reply #1 on: January 12, 2026, 10:14:41 pm »
I think the problem is with DateSeparator, which is set independently from the date format, and if I remember correctly, can be '-' by default - then setting it to '/' might help.

https://www.freepascal.org/docs-html/rtl/sysutils/dateseparator.html

Also note the docs say DateSeparator is deprecated (so is ShortDateFormat), FormatSettings record should be used instead.

wp

  • Hero Member
  • *****
  • Posts: 13350
Re: StrToDateTime problems
« Reply #2 on: January 13, 2026, 12:00:25 am »
Maybe Nimbus' answer is the same, but I want to tell you that the symbol '/' in the ShortDateFormat ('dd/mm/yyyy') is replaced by the FormatSettings.DateSeparator when the string is analyzed. So, when you are in a country where the DateSeparator is different from the '/' (like me in Germany where it is the '.') you must set the FormatSettings.DateSeparator to '/' so that the date string is accepted:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}{$H+}
  3.  
  4. uses
  5.   SysUtils;
  6. var
  7.   ReadingDate : TDateTime;
  8.   testdate :  string;
  9.  
  10. begin
  11.   FormatSettings.ShortDateFormat:= 'dd/mm/yyyy';
  12.   FormatSettings.DateSeparator := '/';
  13.   testdate:= '29/10/2025';
  14.   ReadingDate:= StrToDateTime(testdate);
  15. end.

A more flexible way to convert a string to a date is by using the ScanDateTime function from unit DateUtils (https://www.freepascal.org/docs-html/rtl/dateutils/scandatetime.html):
Code: Pascal  [Select][+][-]
  1.    ReadingDate := ScanDateTime('dd"/"mm"/"yyyy', testDate);
Quoting the '/' here has the effect that it is taken as dateseparator literally without having to specify the FormatSettings.DateSeparator explicitly.

andyH

  • Full Member
  • ***
  • Posts: 102
Re: StrToDateTime problems
« Reply #3 on: January 13, 2026, 12:28:42 am »
Thanks to both of you, I doubt I would have found DateSeparator, I'd picked up that ShortDateFormat was deprecated.

ScanDateTime looks a much better solution.

In the meantime I'd written a function to convert a date/time string to unixtime to get round the problem   :(

Late here, I'll try your suggestions tomorrow. Thanks again.






Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: StrToDateTime problems
« Reply #4 on: January 13, 2026, 01:12:51 pm »
  //ShortDateFormat:= 'dd/mm/yyyy';
Really? For storage? For storage it needs yyyy/mm/dd since that maps to TDateTime.
It also sorts better.

If your database supports it, but really always: do not use a string representation.
Store as TDateTime (float)
For the string conversions, simply use DateTimeToUnix first and only then convert it to string.
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

andyH

  • Full Member
  • ***
  • Posts: 102
Re: StrToDateTime problems
« Reply #5 on: January 13, 2026, 01:32:37 pm »
This is parsing a large CSV file generated by a speed indicator device. Cumbersome to do in excel, hence a pascal program. I have no control over the format of the data.

cdbc

  • Hero Member
  • *****
  • Posts: 2600
    • http://www.cdbc.dk
Re: StrToDateTime problems
« Reply #6 on: January 13, 2026, 03:10:28 pm »
Hi
Hmmm, CSV -- then it's machine-generated data, meaning it doesn't change through, lets say the file, right?!?
Then you could just detect the date format, here's some very crude & quick code:
Code: Pascal  [Select][+][-]
  1. const
  2.   { mostly used date formats }
  3.   dtfErratic = 0;
  4.   dtfYMD = 5;
  5.   dtfDMY = 7;
  6.   dtfMDY = 11;
  7. ...
  8. function DetectDateFormat(const aStr: string): word;
  9. const ssoExcludeEmpty = TStringSplitOptions.ExcludeEmpty;
  10. var ldelim: char = #0; lsa: TStringArray;
  11. begin
  12.   if aStr = '' then exit(dtfErratic);
  13.   for ldelim in aStr do if not (ldelim in ['0','1','2','3','4','5','6','7','8','9']) then break;
  14.   if ldelim = aStr[Length(aStr)] then exit(dtfErratic);
  15.   lsa:= aStr.Split([ldelim],ssoExcludeEmpty);
  16.   if StrToInt(lsa[0]) > 31 then exit(dtfYMD);
  17.   if StrToInt(lsa[0]) > 12 then exit(dtfDMY)
  18.   else Result:= dtfMDY;
  19. end;
  20.  
The more items you test it on, the more accurate it gets... (if you accumulate the results and gather the most hits at the end)
As I said it's VERY crude, but serves to show you the idea...
Regards Benny
« Last Edit: January 13, 2026, 03:13:46 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Nicole

  • Hero Member
  • *****
  • Posts: 1303
Re: StrToDateTime problems
« Reply #7 on: January 13, 2026, 07:45:13 pm »
How I hate this bug and we do not get rid of it for how long? - about 10 years.
It is a Windows-feature.  >:(

Probably due to the regional format settings, which are not done well enough.
And it is an -  I am here - I am gone - error.

Often I just started the app again and it was gone.
Several times not. All looked perfect, but one rainy day I read "not a valid date, bäääh".
As both the watch window and you are tricked by the OS, there is no debug possible.

Try this, enforce a setting, I have not seen it for quite a long time up to now, but we never know:

Code: Pascal  [Select][+][-]
  1. Result[i].Datum := StrToDate(s, DefaultFormatSettings);

which can look e.g. like this:

Code: Pascal  [Select][+][-]
  1. var fs: TFormatSettings;
  2. begin
  3.   fs := DefaultFormatSettings;
  4.   fs.DateSeparator := '-';
  5.   fs.ShortDateFormat := 'yyyy-mm-dd';
  6.   result := StrToDateTime(s, fs);  // Wandelt "2010-12-28" in ein Datum um
  7. end;


Good luck, you will need it.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6311
  • Compiler Developer
Re: StrToDateTime problems
« Reply #8 on: January 15, 2026, 09:29:08 pm »
How I hate this bug and we do not get rid of it for how long? - about 10 years.
It is a Windows-feature.  >:(

That is no bug. It behaves as intended.

Aruna

  • Hero Member
  • *****
  • Posts: 787
Re: StrToDateTime problems
« Reply #9 on: January 15, 2026, 11:56:02 pm »
Mods, if in the wrong topic area, please move.

It doesn't get much simpler:

Code: Pascal  [Select][+][-]
  1. program parseSID;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   {$IFDEF UNIX}
  5.   cthreads,
  6.   {$ENDIF}
  7.   Classes, StrUtils, Types, sysutils, dateutils;
  8. var
  9.   ReadingDate : TDateTime;
  10.   testdate :  string;
  11.  
  12. begin
  13.   Writeln ('ShortDateFormat ',ShortDateFormat);
  14.   //ShortDateFormat:= 'dd/mm/yyyy';
  15.   Writeln ('ShortDateFormat ',ShortDateFormat);
  16.   testdate:= '29/10/2025';
  17.   ReadingDate:= StrToDateTime(testdate);
  18. end.

Program outputs ShortDateFormat d/m/y or dd/mm/yyyy depending what is commented out (to confirm the date format is correct) and then errors out with EConvertError: "29/10/2025" is not a valid date format (see screenshot). I've tried various permutations - different date, adding in time, e.g. 29/10/2025 10:15, replacing testdate with a string '29/10/2025'. All generate the same error, invalid date format.

Obviously doing something wrong but can't see it?

If relevant, lazarus 3.8, fpc 3.2.2 running under linux.

Run this first:
Code: Pascal  [Select][+][-]
  1. writeln('Date Separator: ', DateSeparator);

Now have a look at the attached screenshot you will see the date separator is a '-' so to fix your issue assign '/' to DateSeparator.
Code: Pascal  [Select][+][-]
  1. DateSeparator:='/';
Now run your code and it should work.

The second attached screenshot shows where the DateSeparator defualt value is hard coded. If you look carefully you will see ShortDateFormat: 'd/m/y';  this is why it returns what it does but Dateseparator is DateSeparator: '-';

 

TinyPortal © 2005-2018