Recent

Author Topic: [Bug] asDateTime conversion error! 4 digit milisec 2025-12-12 12:12:12.1230  (Read 1562 times)

PizzaProgram

  • Jr. Member
  • **
  • Posts: 60
  • ...developing Delphi apps since 25 years.
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][+][-]
  1. sqlTxt := 'SELECT MAXVALUE(...some TimeStamp fields ) as MAXI FROM RDB$DATABASE;'
  2. ...
  3. 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][+][-]
  1. function IntStrToTime(Out ErrorMsg : AnsiString; const S: PChar; Len : integer;const defs:TFormatSettings; separator : char = #0): TDateTime;
  2. ...
  3.          if (ElemLen <= 2) or ((ElemLen <= 4) and (TimeIndex = tiMSec) ) then // Line#: 646
  4.          begin
  5.            if (TimeIndex = tiMSec) and (ElemLen > 3) then
  6.              ElemLen := 3;
  7.            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.
« Last Edit: December 17, 2025, 10:00:33 am by PizzaProgram »
x86_64-win64 --Win7 PRO 64bit HUN

paweld

  • Hero Member
  • *****
  • Posts: 1561
n my opinion, this is not a bug - milliseconds should not have more than 3 digits.
Best regards / Pozdrawiam
paweld

Zvoni

  • Hero Member
  • *****
  • Posts: 3230
Agree with pawel

Quote
2025-12-12 12:12:12.1230
This 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
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

wp

  • Hero Member
  • *****
  • Posts: 13336
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][+][-]
  1. program Project1;
  2. uses
  3.   SysUtils;
  4. begin
  5.   FormatSettings.DecimalSeparator := '.';
  6.   WriteLn(FormatDateTime('hh:nn.zzz', Now));
  7.   FormatSettings.DecimalSeparator := ',';
  8.   WriteLn(FormatDateTime('hh:nn.zzz', Now));
  9.   ReadLn;
  10. 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.
« Last Edit: December 17, 2025, 12:33:47 pm by wp »

Zvoni

  • Hero Member
  • *****
  • Posts: 3230
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.
The ISO is pretty clear:
https://www.iso.org/iso-8601-date-and-time-format.html
Quote
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.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

wp

  • Hero Member
  • *****
  • Posts: 13336
Yes, but Pascal is not ISO; it could have been that Pascal (or better: FPC) has its own definition.

Zvoni

  • Hero Member
  • *****
  • Posts: 3230
Yes, but Pascal is not ISO; it could have been that Pascal (or better: FPC) has its own definition.
I doubt that very much
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

jcmontherock

  • Sr. Member
  • ****
  • Posts: 336
Seconds is, luckily, a decimal unit. The word millisecond indicate this reality.
Windows 11 UTF8-64 - Lazarus 4.4-64 - FPC 3.2.2

Zvoni

  • Hero Member
  • *****
  • Posts: 3230
Seconds 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
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

dsiders

  • Hero Member
  • *****
  • Posts: 1511
Seconds 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

  • Hero Member
  • *****
  • Posts: 3647
    • tomboy-ng, a rewrite of the classic Tomboy
Re: [Bug] asDateTime conversion error! 4 digit milisec 2025-12-12 12:12:12.1230
« Reply #10 on: December 17, 2025, 11:23:31 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
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

Zvoni

  • Hero Member
  • *****
  • Posts: 3230
Re: [Bug] asDateTime conversion error! 4 digit milisec 2025-12-12 12:12:12.1230
« Reply #11 on: December 18, 2025, 07:42:54 am »
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
« Last Edit: December 18, 2025, 08:19:09 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

PizzaProgram

  • Jr. Member
  • **
  • Posts: 60
  • ...developing Delphi apps since 25 years.
Re: [Bug] asDateTime conversion error! 4 digit milisec 2025-12-12 12:12:12.1230
« Reply #12 on: December 18, 2025, 08:38:11 am »
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.
... 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][+][-]
  1. '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][+][-]
  1.          if (ElemLen <= 2) or ((ElemLen <= 8) and (TimeIndex = tiMSec) ) then // Line#: 646
  2.          begin
  3.            if (TimeIndex = tiMSec) and (ElemLen > 3) then
  4.              ElemLen := 3;
  5.            Val(StrPas(S + FirstSignificantDigit, ElemLen), Value, Err); // this line is old code, no change needed
  6.  

Debate closed, everyone is happy.
x86_64-win64 --Win7 PRO 64bit HUN

paweld

  • Hero Member
  • *****
  • Posts: 1561
Re: [Bug] asDateTime conversion error! 4 digit milisec 2025-12-12 12:12:12.1230
« Reply #13 on: December 18, 2025, 08:55:22 am »
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.
Best regards / Pozdrawiam
paweld

Zvoni

  • Hero Member
  • *****
  • Posts: 3230
Re: [Bug] asDateTime conversion error! 4 digit milisec 2025-12-12 12:12:12.1230
« Reply #14 on: December 18, 2025, 09:14:09 am »
I believe that such cases should be handled by the programmer themselves in their code.
Exactly what i said
Quote
Bottom line: it‘s the user’s responsibility to truncate/round exceeding decimals after the 3rd decimal BEFORE sending it to any Parsing Function
if he wants to display more than 3 digits in the fractional part, he should write his own function
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018