[Bug] asDateTime conversion error! 4 digit milisec 2025-12-12 12:12:12.1230 lazarus / 64-FPC development ---------------------------------------------------------------------- PizzaProgram · 2025-12-17 08:45 I've just installed latest Lazarus (v4.4) and had to spend 20 hours to find out, what's going on under the surface.  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i sqlTxt := 'SELECT MAXVALUE(...some TimeStamp fields ) as MAXI FROM RDB$DATABASE;'...maxiDateTime := DBDB.QQ.FieldByName('MAXI').AsDateTime; // -> ERROR. As it turns out, Lazarus can not realise that the result field is a Timestamp. Solutions: 1. Please fix better field-type recognition of ISO dates with 4 digits 2. fix the function IntStrToTime()  at unit file: dati.inc ! Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function IntStrToTime(Out ErrorMsg : AnsiString; const S: PChar; Len : integer;const defs:TFormatSettings; separator : char = #0): TDateTime;...         if (ElemLen <= 2) or ((ElemLen <= 4) and (TimeIndex = tiMSec) ) then // Line#: 646         begin           if (TimeIndex = tiMSec) and (ElemLen > 3) then             ElemLen := 3;           Val(StrPas(S + FirstSignificantDigit, ElemLen), Value, Err); That's it! 2 tiny lines added, and problem solved. (!Note the change of:  or ((ElemLen <= 4) (not 3, as before) PS: this code also works, if the separator of ms is: ',' comma instead of  '.' dot. ---------------------------------------------------------------------- paweld · 2025-12-17 10:29 n my opinion, this is not a bug - milliseconds should not have more than 3 digits. ---------------------------------------------------------------------- Zvoni · 2025-12-17 10:48 Agree with pawel Quote2025-12-12 12:12:12.1230This is nonsense. There is no "1230"th millisecond of the 12th second. Period! This carries over to be "2025-12-12 12:12:13.230" --> 230 milliseconds added to 13th second. It's more probable the code which provides that timestamp to your Database (Firebird?) is at fault ---------------------------------------------------------------------- wp · 2025-12-17 11:31 I did not find a specific documentation defining explicitely what the part behind the seconds exactly means in Pascal. Of course, once could imagine that it is not the count of milliseconds but the fractional part of seconds. But in this case, the '.' between integer seconds and fractional seconds should be understood as a decimal separator and therefore should change with the FormatSettings.DecimalSeparator. This does not happen, it always remains a '.'. Therefore, I agree with the opinion of Zvoni and paweld that the "milliseconds" must be an integer, and the number cannot be greater than 999. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1;uses  SysUtils;begin  FormatSettings.DecimalSeparator := '.';  WriteLn(FormatDateTime('hh:nn.zzz', Now));  FormatSettings.DecimalSeparator := ',';  WriteLn(FormatDateTime('hh:nn.zzz', Now));  ReadLn;end.If your database does provide 4 or maybe even more digits after the seconds and the '.' you must read the record value as a string and process it yourself manually. ---------------------------------------------------------------------- Zvoni · 2025-12-17 11:37 Quote from: wp on December 17, 2025, 12:31:49 pmI did not find a specific documentation defining explicitely what the part behind the seconds exactly means in Pascal. Of course, once could imagine that it is not the count of milliseconds but the fractional part of seconds. The ISO is pretty clear: https://www.iso.org/iso-8601-date-and-time-format.html QuoteTherefore, the order of the elements used to express date and time in ISO 8601 is as follows: year, month, day, hour, minutes, seconds, and milliseconds. ---------------------------------------------------------------------- wp · 2025-12-17 12:39 Yes, but Pascal is not ISO; it could have been that Pascal (or better: FPC) has its own definition. ---------------------------------------------------------------------- Zvoni · 2025-12-17 12:49 Quote from: wp on December 17, 2025, 01:39:50 pmYes, but Pascal is not ISO; it could have been that Pascal (or better: FPC) has its own definition. I doubt that very much ---------------------------------------------------------------------- jcmontherock · 2025-12-17 15:11 Seconds is, luckily, a decimal unit. The word millisecond indicate this reality. ---------------------------------------------------------------------- Zvoni · 2025-12-17 15:56 Quote from: jcmontherock on December 17, 2025, 04:11:12 pmSeconds is, luckily, a decimal unit. The word millisecond indicate this reality. Doesn’t change the fact there are only 1000 milliseconds per second, and not 1230 ---------------------------------------------------------------------- dsiders · 2025-12-17 18:38 Quote from: Zvoni on December 17, 2025, 04:56:55 pmQuote from: jcmontherock on December 17, 2025, 04:11:12 pmSeconds is, luckily, a decimal unit. The word millisecond indicate this reality. Doesn’t change the fact there are only 1000 milliseconds per second, and not 1230 Why introduce facts into  the discussion? ---------------------------------------------------------------------- dbannon · 2025-12-17 22:23 Quote from: Zvoni on December 17, 2025, 12:37:13 pm.... Therefore, the order of the elements used to express date and time in ISO 8601 is as follows: year, month, day, hour, minutes, seconds, and milliseconds. I could not find the reference on your quote but wikipedia is quite clear - A decimal fraction may be added to the lowest order time element present in any of these representations. A decimal mark, either a comma or a dot on the baseline, is used as a separator between the time element and its fraction. (Following ISO 80000-1 according to ISO 8601:1-2019,[27] it does not stipulate a preference except within International Standards, but with a preference for a comma according to ISO 8601:2004.[28]) For example, to denote "14 hours, 30 and one half minutes", do not include a seconds figure; represent it as "14:30,5", "T1430,5", "14:30.5", or "T1430.5". There is no limit on the number of decimal places for the decimal fraction. https://en.wikipedia.org/wiki/ISO_8601 I use 7 digits after the decimal point (not for precision, its a useful poor man's unique). Davo ---------------------------------------------------------------------- Zvoni · 2025-12-18 06:42 Dave, Look at my link in reply 4. Though, with what you found i‘d agree with the fractional representation. Meaning: his „1230“ milliseconds from the subject title are actually 123 milliseconds. Bottom line: it‘s the user’s responsibility to truncate/round exceeding decimals after the 3rd decimal BEFORE sending it to any Parsing Function ---------------------------------------------------------------------- PizzaProgram · 2025-12-18 07:38 Thank you for all these replays! What I do not understand:  - Why all these argues / discussions ???  1. If Pascal / FPC can only handle 3 digits, it's OK !  Than let's limit the value while converting by default! 2. That's what I did. Provided a finished, working, 3-line fix.  Copy + Paste -> next release, all OK. DONE. 3. The only thing I was wrong:[/size]  - YES, there could be MORE than 4 chars,  - so why not allowing max of a WORD (integer), like 8 or 9 ?  - I've seen Linux (Debian) LOGs showing 6+ fractions of a second.  - This code should not only work with Firebird, but ALL kinds of (future?) Database code. We can not predict, which one is using 4,6 or more. Firebird's default = 4 digits. It's not a "bug", it's a FACT. The bug is, that FPC can not convert it to it's own format. ________________________________________________ Down from here are only my opinions: 4. Quote from: dbannon on December 17, 2025, 11:23:31 pmQuote from: Zvoni on December 17, 2025, 12:37:13 pm... wikipedia is quite clear - A decimal fraction may be added to the lowest order time element present in any of these representations. A decimal mark, either a comma or a dot on the baseline, is used as a separator between the time element and its fraction. (Following ISO 80000-1 according to ISO 8601:1-2019,[27] it does not stipulate a preference except within International Standards, but with a preference for a comma according to ISO 8601:2004.[28]) For example, to denote "14 hours, 30 and one half minutes", do not include a seconds figure; represent it as "14:30,5", "T1430,5", "14:30.5", or "T1430.5". There is no limit on the number of decimal places for the decimal fraction. https://en.wikipedia.org/wiki/ISO_8601 I use 7 digits after the decimal point (not for precision, its a useful poor man's unique). Davo Totally Agree. 5. Facts: my Language (hu/hun) is using currently this insane format of "short DateTime" by default at Win10+ Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 'yyyy. mm. dd. hh:nn:ss,z' (Yes, Spaces between Y/M/D ! , and comma as dec. separator. But it was "normal" at Win3.1-Win7, they changed just in the last few years. "Run in compatibility more" does not help either.) - So 'truncating' to 23 chars is not a solution. - forcing to write a new time-date analyst-function for ourself makes FPC useless - Changing FormatSettings does not help at all. Tried 20 hours long all possibilities. - also it would not help with: build-in .asDateTime function failing by default. Summarized = finished code = Copy+Paste = ALL DONE: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i          if (ElemLen <= 2) or ((ElemLen <= 8) and (TimeIndex = tiMSec) ) then // Line#: 646         begin           if (TimeIndex = tiMSec) and (ElemLen > 3) then             ElemLen := 3;           Val(StrPas(S + FirstSignificantDigit, ElemLen), Value, Err); // this line is old code, no change needed  Debate closed, everyone is happy. ---------------------------------------------------------------------- paweld · 2025-12-18 07:55 Personally, I don't see the point in cluttering up the main packages with such exceptions. Especially since the last digit is unnecessary (even your modification only analyzes 3 digits from this sequence). I believe that such cases should be handled by the programmer themselves in their code. ---------------------------------------------------------------------- Zvoni · 2025-12-18 08:14 Quote from: paweld on December 18, 2025, 08:55:22 amI believe that such cases should be handled by the programmer themselves in their code. Exactly what i said QuoteBottom line: it‘s the user’s responsibility to truncate/round exceeding decimals after the 3rd decimal BEFORE sending it to any Parsing Functionif he wants to display more than 3 digits in the fractional part, he should write his own function ---------------------------------------------------------------------- dbannon · 2025-12-19 00:02 Quote from: Zvoni on December 18, 2025, 07:42:54 am.... Bottom line: it‘s the user’s responsibility to truncate/round exceeding decimals after the 3rd decimal BEFORE sending it to any Parsing Function Not if you use the iso8601 methods. eg - Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testdate;{$mode objfpc} uses dateutils;varDateTime, DateTime2 : TDateTime; begin        if TryISO8601ToDate('2025-12-19T10:45:00.123456', DateTime) then              writeln('Convert to DateTime OK');        if TryISO8601ToDate('2025-12-19T10:45:00.123', DateTime2) then              writeln('Convert to DateTime2 OK');        writeln('Diff is ', DateTime - DateTime2);end.Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i dbannon@dell:~/Pascal/CLI$ ./test_dateConvert to DateTime OKConvert to DateTime2 OKDiff is  5.2750692702829838E-009Davo ---------------------------------------------------------------------- wp · 2025-12-19 00:25 On Windows the first output is missing, i.e. TryISO8601ToDate('2025-12-19T10:45:00.123456', DateTime) is not OK. ---------------------------------------------------------------------- cdbc · 2025-12-19 09:08 Hi On PCLinuxOS it looks like this:Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i [bc@stinker date-stuff]$ fpc test_date.pp Free Pascal Compiler version 3.2.2 [2024/07/26] for x86_64Copyright (c) 1993-2021 by Florian Klaempfl and othersTarget OS: Linux for x86-64Compiling test_date.ppLinking test_date14 lines compiled, 1.2 sec[bc@stinker date-stuff]$ ./test_date Convert to DateTime2 OKDiff is -4.6010447918090278E+004[bc@stinker date-stuff]$  Same issue as with Werner... Regards Benny ---------------------------------------------------------------------- dbannon · 2025-12-19 09:47 Code: [Select][quote author=cdbc link=topic=73029.msg572609#msg572609 date=1766135288] On PCLinuxOS it looks like this ... [bc@stinker date-stuff]$ ./test_date Convert to DateTime2 OK Diff is -4.6010447918090278E+004 Oh, my code should report an error as well as success !  I and a little surprised WP had a problem on Windows (I use same basic idea in my app and its cross platform). But really surprised with PCLinux. Will do some experimenting .... Davo ---------------------------------------------------------------------- Zvoni · 2025-12-19 10:05 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testdate;{$mode objfpc} uses dateutils;varDateTime, DateTime2 : TDateTime; begin        if TryISO8601ToDate('2025-12-19T10:45:00.123456', DateTime) then              writeln('Yeet DateTime') Else Writeln('No Yeet Datetime');      if TryISO8601ToDate('2025-12-19T10:45:00.123', DateTime2) then              writeln('Yeet DateTime2') Else Writeln('No Yeet Datetime2');      writeln('Diff is ', DateTime - DateTime2);        Readln;end.Returns Code: [Select]Yeet DateTime Yeet DateTime2 Diff is  5.2750692702829838E-009 Win10-64-Bits - FPC3.2.3/Laz4.3 (old fixes) ---------------------------------------------------------------------- paweld · 2025-12-19 10:22 As @Zvoni wrote, it is OK in FPC 3.2-fixes, but in FPC 3.2.2 TryISO8601ToDate(‘2025-12-19T10:45:00.123456’, DateTime) is not. Tested on Windows 10. ---------------------------------------------------------------------- dbannon · 2025-12-19 10:34 Ah, yes paweld, just writing up the same explanation. WP, Benny, are you using FPC322 ? Looks like this is one of the many things that have been fixed in FPC323. I took my binary (compiled with fpc324rc1) to a PCLinux VM and it worked as expected. So I took the source and compiled it on PCLinux and it fails. So, looking in the source of my App (which must compile with FPC322 on Debian) I realize I work around that problem. I vaguely recall reporting the issue and 'someone' fixed it, possibly PascalDragon. But of course, its not in the "Released Version" of FPC yet. Sigh .... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function MyTryISO8601ToDate(DateSt : string; out OutDT : TDateTime; ReturnUTC : boolean = true) : boolean;var    I : integer;    St : string = '';begin    OutDT := 0.0;    if DateSt = '' then exit(False);    Result := True;    I := pos('.', DateSt);                          // if we have decimal point, we have stuff to do.    if I > 0 then begin                           // TryISO8601ToDate cannot handle string with decimals of a second        delete(DateSt, I, 1);                     // Remove decimal point        while I  < length(DateSt) do begin            if DateSt[I] in ['0'..'9'] then begin                St := St + DateSt[I];               // save digits to use later              delete(DateSt, I, 1);            end else break;        end;      // The first six digits in St represent microseconds. we will stop there.        while length(St) > 6 do delete(St, length(St), 1);        while length(St) < 6 do St := St + '0';    end;    if TryISO8601ToDate(DateSt, OutDT, ReturnUTC) then begin               // WARNING - apparently this is a FPC320 only feature        if I > 0 then            OutDT := OutDT + (St.ToDouble() * ValueMicroSecond);         // ValueMicroSecond is Regional const,  eg        end else result := False;                                              // ValueMicroSecond := 1.0 / double(24*60*60*1000*1000);end;                                                                                                                                 Davo ---------------------------------------------------------------------- cdbc · 2025-12-19 12:11 Hi Davo Right, sorry I was a lazy bastard... This time compiled with 2 weeks old 'main' ~ fpc 3.3.1:Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i [bc@stinker date-stuff]$ ./test_date Convert to DateTime OKConvert to DateTime2 OKDiff is  5.2750692702829838E-009[bc@stinker date-stuff]$  Regards Benny