Recent

Author Topic: for nerds or even a bug: negative date works "sometimes"  (Read 886 times)

Nicole

  • Hero Member
  • *****
  • Posts: 1009
for nerds or even a bug: negative date works "sometimes"
« on: March 04, 2024, 05:23:25 pm »
Here is a thing, I want to share with you.
To find a workaround is easy, but this is too strange to just work around.

All starts with a line in an iCal or *.ics
Code: Text  [Select][+][-]
  1. DTSTART:16010311T020000
Who is not familiar with it: This means the 11th of March in the year 1601 at time 2 o'clock.
So a date-typo, ok
We reduce it to
16010311
which is in the year 1601.

This I wanted to skip by a validity check, but surprisingly it passed.
I wrote:
valid:=TryStrToDate(s, myDate);
Valid was true and the date -109105.

A reverse check
ShowMessage(DateToStr(myDate));
gave me the correct date in the year 1601.
WOW!

The strange thing starts, when I add the value to a Listbox

I added it by
ListBox1.Items.Add(DateToStr(newsA.datum)

The value newsA.datum is negative, and contains the 17the century-date.
However the displayed Listbox contains
30.12.1899
instead, what shall be zero.

Awaiting any comments.




marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11992
  • FPC developer.
Re: for nerds or even a bug: negative date works "sometimes"
« Reply #1 on: March 04, 2024, 05:51:13 pm »
Afaik some negative date issues have been fixed in both 3.2.3 and trunk

wp

  • Hero Member
  • *****
  • Posts: 12525
Re: for nerds or even a bug: negative date works "sometimes"
« Reply #2 on: March 04, 2024, 06:30:08 pm »
I don't understand this post. I have completely different experience...

valid:=TryStrToDate(s, myDate);
Valid was true and the date -109105.
Please show the complete code how you did this. In my opinion it should not work: first, because you do not specify a formatSettings parameter, and this means that your DateSeparator (probably a '.', '-', or '/') is expected to be present in the string. Since it is not present, the conversion should fail. Secondly, StrToDate and TryStrToDate absolutely need a dateseparator to find the end of the year and month digits. I debugged it and the accumulation of the y's did not stop after 4 digits.

It works, however, with the function ScanDateTime which only seems to count the number of Ys, Ms and Ds to get the year, month and day digits.
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. uses
  4.   SysUtils, DateUtils;
  5. var
  6.   s: String;
  7.   dt: TDateTime;
  8.   fs: TFormatSettings;
  9. begin
  10.   s := '16010311';
  11.  
  12.   fs := DefaultFormatSettings;
  13.   fs.ShortDateformat := 'yyyymmdd';
  14.   //fs.DateSeparator := #0;  --- there's no way to set the date separator to '' since it is a char rather than a string...
  15.  
  16.   WriteLn('TryStrToDate');
  17.   if TryStrToDate(s, dt, fs) then
  18.   begin
  19.     WriteLn(s, ' ---> ', dt:0:0, ' ---> ', DateToStr(dt) )
  20.   end else
  21.     WriteLn('invalid date');
  22.  
  23.   WriteLn;
  24.   WriteLn('ScanDateTime');
  25.   try
  26.     dt := ScanDateTime('yyyymmdd', s, fs);
  27.     WriteLn(s, ' ---> ', dt:0:0, ' ---> ', DateToStr(dt) )
  28.   except
  29.     on E:Exception do WriteLn('invalid date');
  30.   end;
  31.  
  32.   ReadLn;
  33. end.

The strange thing starts, when I add the value to a Listbox

I added it by
ListBox1.Items.Add(DateToStr(newsA[ i].datum)

The value newsA[ i].datum is negative, and contains the 17the century-date.
However the displayed Listbox contains
30.12.1899
instead, what shall be zero.

In my own test DateToStr does accept a negative date without issues. Please post a short program so that we can see what you are doing.

Nicole

  • Hero Member
  • *****
  • Posts: 1009
Re: for nerds or even a bug: negative date works "sometimes"
« Reply #3 on: March 04, 2024, 06:40:46 pm »
just posted with all my work inprogress inside.

Code: Pascal  [Select][+][-]
  1.  for i:=0 to SL.Count - 1 do begin   // 2.3.2024 J ist bei der Zeit - 1 und die ChecklisBox ist uU die falsche Komponente
  2.      Zeile:=SL[i];
  3.      if ContainsText(Zeile,'DTSTART') then begin   // DTSTART:20240112T120000  => das ist 12 Uhr, was wäre EST nicht CST?
  4.         teil:=trim(Zeile);
  5.         k:=Pos(':', teil);  // 1.6.2017 daher suche ich nach dem Doppelpunkt
  6.         teil:=copy(teil, k+1, Length(teil));
  7.         teil:=trim(teil);
  8.         s:=leftStr(teil,8); // 20240112T120000 =>   20240112
  9.         s:=copy(s,5,2)  + '.' + copy(s,7,2) +'.' + copy(s,1,4);  // Datum wird verwandelt in  12.1.2024
  10.         gueltig:=TryStrToDate(s,datum_);
  11.         if gueltig  and (datum_ > 0) then begin // nur wenn das Datum gültig ist, wird etwas eingetragen
  12.            j:=j + 1;   // für eine neue Zeilennummer im Array newsA
  13.            newsA[j].Datum:=datum_;  // damit habe ich den Eventtext extrahiert
  14.             // wie kann das negatig und gültig sein?!
  15.         //   ShowMessage(DateToStr(datum_)); Das "problem" ist, dass das korrekt verarbeitet wird.


Code: Pascal  [Select][+][-]
  1. type TNews = record
  2.   id_news: integer;
  3.   datum: TDate;
  4.   Zeit: TTime;
  5.   Code: integer;
  6.   Bezeichnung: string; // max 80 Zeichen in der Tabelle
  7.   end;
  8.  
  9. TNews_array = Array of TNews;  

To my mind the negative date is an advantage, because it enables to display data before 1800.

PS: If you see any connection with your kind e-mail, that ical is nothing but text, - you are perfectly all right with this idea.

Nicole

  • Hero Member
  • *****
  • Posts: 1009
Re: for nerds or even a bug: negative date works "sometimes"
« Reply #4 on: March 04, 2024, 06:50:42 pm »
and the iCal, I am afraid you know it.
However it is not about the iCal, it is about writing data before 1800.


wp

  • Hero Member
  • *****
  • Posts: 12525
Re: for nerds or even a bug: negative date works "sometimes"
« Reply #5 on: March 04, 2024, 08:06:09 pm »
In the particular case of the ical file, you could also use TryISOStrToDate or TryISOStrToDateTime (rather than TryStrToDate), they are able to work without a date separator.

And if you plan to use negative date in TvPlanIt: I just found out that there is a limitation in the 17th century because then the formula used to calculate Easter is not valid any more.

 

TinyPortal © 2005-2018