TCHart has trouble handling dates < 1895

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
H.Hasenack
Newbie
Newbie
Posts: 16
Joined: Thu Nov 10, 2011 12:00 am

TCHart has trouble handling dates < 1895

Post by H.Hasenack » Thu Apr 19, 2012 7:27 am

Open a chart (eg in TeeChartOffice)
Add a (bar) series
make bottom axis exact datetime, interval 1 year
ensure round first label is checked
add/change a data point so it is before 1895, eg 01-01-1850
Crash: EInvalidOp casued by routine that tries to determine the length of the rounded label. Actually the EInvalid op is raised inside the RTL because a way to large negative value is passed to the DateTImeToStr routine. the value is calculated as 365 * AxisMinimumDate

What happens is here is that a date (float days) is multiplied with the # of days in a year, and then pass it on to DAteTimeToStr. Happens earlier buiolds and also with the build I downloaded today: 2012.05.120327

Regards - Hans

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: TCHart has trouble handling dates < 1895

Post by Narcís » Thu Apr 19, 2012 10:49 am

Hi Hans,

I'm not able to reproduce the issue either at design-time nor at run-time using this code snippet:

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Chart1.AddSeries(TBarSeries.Create(Self));
  Chart1[0].XValues.DateTime:=True;

  Chart1.Axes.Bottom.ExactDateTime:=True;
  Chart1.Axes.Bottom.Increment:=DateTimeStep[dtOneYear];
  Chart1.Axes.Bottom.RoundFirstLabel:=True;
  Chart1.Axes.Bottom.DateTimeFormat:='dd/mm/yyyy';

  Chart1[0].AddXY(EncodeDate(1850, 1, 1), random);
end;
Does this work fine at your end? Can you modify the code snippet so that we can reproduce the issue here?
Actually the EInvalid op is raised inside the RTL because a way to large negative value is passed to the DateTImeToStr routine.
Can you reproduce this issue outside TeeChart? It might be a RTL problem.

Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

H.Hasenack
Newbie
Newbie
Posts: 16
Joined: Thu Nov 10, 2011 12:00 am

Re: TCHart has trouble handling dates < 1895

Post by H.Hasenack » Fri Apr 20, 2012 9:24 am

Unfortunately the TChartOffice.exe delivered with the binaries install wont start. I downloaded another one separately, but this one does not accept dates before 1900, they are truncated to 00:00:00

Tee9New_win32.exe ran just fine. I manage to reproduce the error like this:
Tab All features
Miscellaneous/Design options
Show editor
Add a new (bar series)
Add numeric data points: [-3650,10 ] [1,10] [3650,10]
Now set series horiz axis to datetime
goto bottom axis editor
select tab increament, CHange
Check extact datetime and Standard: One year
click OK
bang - the error.

I managed to reproduce it like this, using Delphi XE2, Update 4, Win32:

Code: Select all

procedure TfrmMain.btDateTroubleClick(Sender: TObject);
VAR y:integer;
    sr:tChartSeries;
begin
  sr:=Chart1.AddSeries(TBarSeries.Create(Self));
  sr.XValues.DateTime:=True;

  Chart1.Axes.Bottom.ExactDateTime:=True;
  Chart1.Axes.Bottom.Increment:=DateTimeStep[dtOneYear];
  Chart1.Axes.Bottom.RoundFirstLabel:=True;
  Chart1.Axes.Bottom.DateTimeFormat:='dd/mm/yyyy';

  for y:=1850 to 2012 do
    sr.AddXY(EncodeDate(y,1,1),random(100));
end;

procedure TfrmMain.btNoDateTroubleClick(Sender: TObject);
VAR y:integer;
    sr:tChartSeries;
begin
  sr:=Chart1.AddSeries(TBarSeries.Create(Self));
  sr.XValues.DateTime:=True;

  Chart1.Axes.Bottom.ExactDateTime:=True;
  Chart1.Axes.Bottom.Increment:=DateTimeStep[dtOneYear];
  Chart1.Axes.Bottom.RoundFirstLabel:=True;
  Chart1.Axes.Bottom.DateTimeFormat:='dd/mm/yyyy';

  for y:=1896 to 2012 do
    sr.AddXY(EncodeDate(y,1,1),random(100));
end;
I have attached the XE2 project I use for reproducing the error.

regards - Hans
Attachments
DateTrouble.part2.rar
(287.44 KiB) Downloaded 858 times
DateTrouble.part1.rar
XE2 demo case demonstrating the date problem
(512 KiB) Downloaded 881 times

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: TCHart has trouble handling dates < 1895

Post by Yeray » Wed Apr 25, 2012 11:33 am

Hi Hans,

We could reproduce it now with XE2, and we have a fix proposal you could try (since you are a source code customer).
In VCLTee.TeEngine.pas, in the function:

Code: Select all

Function TChartAxis.LabelValue(Const Value:Double):String;
Change the line:

Code: Select all

    DateTimeToString(result,tmp,Value);
For:

Code: Select all

    DateTimeToString(result,tmp,Abs(Value));
Please, confirm us this solves the problem for you so we can apply the fix in the next maintenance release.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

H.Hasenack
Newbie
Newbie
Posts: 16
Joined: Thu Nov 10, 2011 12:00 am

Re: TCHart has trouble handling dates < 1895

Post by H.Hasenack » Thu Apr 26, 2012 7:58 am

Hi Yeray

I am afraid your solution introduces a new error because it will not be able to generate labels for dates before 31-12-1899. :shock: The labels would be translated into dates after the delphi "0" date because of thre abs call.

Here;'s the solution I came up with, and which seems to work as required. 8)

Code: Select all

Function TChartAxis.InternalLabelSize(Const Value:Double; IsWidth:Boolean):Integer;
var ...
    v:double;
Begin
{$ifdef HH_PATCH_TC_MINDATE}
  v:=Value;
  if ExactDateTime then
  begin // avoid invalid dates
    v:=Max(v,EncodeDate(1,1,1)); // consider changing this into a const
    v:=Min(v,EncodeDate(9999,12,31)); // consider changing this into a const
  end;
  result:=ParentChart.MultiLineTextWidth(LabelValue(V),tmp);
{$else}
  result:=ParentChart.MultiLineTextWidth(LabelValue(Value),tmp);
{$endif}
....
end;

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: TCHart has trouble handling dates < 1895

Post by Yeray » Fri Apr 27, 2012 11:55 am

Hi Hans,
H.Hasenack wrote:I am afraid your solution introduces a new error because it will not be able to generate labels for dates before 31-12-1899. :shock: The labels would be translated into dates after the delphi "0" date because of thre abs call.
Right :oops:
H.Hasenack wrote:Here;'s the solution I came up with, and which seems to work as required. 8)
I'm not sure if that's a definitive solution either:
- It still fails if you have ExactDateTime to true.
- If anyone wants a date before 1/1/1, it'll be truncated to 1/1/1.

I've added it to the wish list to be further investigated for future releases (TV52016171). Of course, in the meanwhile, feel free to use your patch.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

H.Hasenack
Newbie
Newbie
Posts: 16
Joined: Thu Nov 10, 2011 12:00 am

Re: TCHart has trouble handling dates < 1895

Post by H.Hasenack » Fri Apr 27, 2012 12:14 pm

- It still fails if you have ExactDateTime to true.
Does it ? - at least it works just fine in my tests...
- If anyone wants a date before 1/1/1, it'll be truncated to 1/1/1.
Well, that allows for an additional 1895 years of history. I must say, using pre-historic dates (29/02/-100) did not spring into my mind as a real issue. Maybe the guys that actually do that dont use TDateTime and ExacteDateTime for producing their date :lol:

Anyway I'm away for a week's holiday, I'll see what you came up with next week.

Regards - hans

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: TCHart has trouble handling dates < 1895

Post by Yeray » Fri Apr 27, 2012 12:21 pm

Hi Hans,

Oups, I meant it still fails if you have ExactDateTime to false.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

H.Hasenack
Newbie
Newbie
Posts: 16
Joined: Thu Nov 10, 2011 12:00 am

Re: TCHart has trouble handling dates < 1895

Post by H.Hasenack » Wed May 09, 2012 11:03 am

The fix was easy and simple... Just use IsDateTime instead of ExactDateTime
It works like a charm, independent of the ExactDateTime value. Also I precalculated the values to optimize the code.

The final patch would then look like tis:

Code: Select all

{$ifdef HH_PATCH_TC_MINDATE}
  v:=Value;
  if IsDateTime then
  begin // avoid invalid dates
    v:=Max(v,-693593); //Max(v,EncodeDate(1,1,1));
    v:=Min(v,2958465); //Min(v,EncodeDate(9999,12,31));
  end;
  result:=ParentChart.MultiLineTextWidth(LabelValue(V),tmp);
{$else}
  result:=ParentChart.MultiLineTextWidth(LabelValue(Value),tmp);
{$endif}

Yeray
Site Admin
Site Admin
Posts: 9613
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: TCHart has trouble handling dates < 1895

Post by Yeray » Thu May 10, 2012 11:48 am

Hi Hans,
H.Hasenack wrote:The fix was easy and simple... Just use IsDateTime instead of ExactDateTime
Yep. This looks more logical to me.

Now the only aspect in this suggestion that still makes me doubt is this:
H.Hasenack wrote:
yeray wrote:- If anyone wants a date before 1/1/1, it'll be truncated to 1/1/1.
Well, that allows for an additional 1895 years of history. I must say, using pre-historic dates (29/02/-100) did not spring into my mind as a real issue. Maybe the guys that actually do that dont use TDateTime and ExacteDateTime for producing their date :lol:
I still think dates before 1/1/1 shouldn't be truncated. I don't see why dates before 1/1/1 wouldn't be plotted. Or at least I don't understand the 1/1/1 as a line separating what can be dated&plotted and what can't.
Actually, I think no date should be truncated as far as possible, even if it's just a label and not the real XValue what we are manipulating here.
Also note this happens with the automatic labels; one can always use custom labels to draw any date in the history of the universe.
Anyway, I'd like to thank you for your feedback and suggestions. We appreciate it.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

H.Hasenack
Newbie
Newbie
Posts: 16
Joined: Thu Nov 10, 2011 12:00 am

Re: TCHart has trouble handling dates < 1895

Post by H.Hasenack » Thu May 10, 2012 12:00 pm

In this case you'd have to write your own DateTimeToStr routines, as the XE2 VCL raises an exception if the date is before 01-01-0001
The other limit (31-12-9999) was just introduced by myself for completeness.

Moreover, this is the routine that determines the label size, not the plotting routine itself.

I did not test, but it is very likely that plotting labels before 01-01-0001 will still raise the error. Whether its a VCL bug or feature: I think it's a feature since the VCL explicitly checks for this value limits and raises the exception.

I hope the change makes it into the next release, for now I'll keep my patch.

Regards - Hans

Post Reply