Page 1 of 1

XValues in the 1800's Not Working Correctly

Posted: Mon Jul 15, 2024 12:27 am
by 13049545
I have an app that works fine with modern dates.
But I tried to run a chart yesterday with dates from 1892 and the Bottom (XValue) Axis doesn't show values in the middle of the XAxis.
Only values on the left and right sides of the chart show -- which is weird.
I've attached some screenshots and the sample project --

Thanks for your help.

Joseph

ErrorChartCode.jpg
ErrorChartCode.jpg (124.01 KiB) Viewed 16921 times
ErrorChart.jpg
ErrorChart.jpg (124.67 KiB) Viewed 16921 times

Re: XValues in the 1800's Not Working Correctly

Posted: Mon Jul 15, 2024 11:21 am
by edu
Hello,
thank you for your report. Seems like the issue is related to Microsoft's datetime zero
more here: https://learn.microsoft.com/en-us/dotne ... ew=net-8.0

We are currently checking for a solution or an interim workaround.


Regards,
Edu

Re: XValues in the 1800's Not Working Correctly

Posted: Fri Jul 19, 2024 11:32 am
by Marc
Hello Joseph,

This is not something for which we can apply a quick fix to the code so we'll need to know a little about the type of use you envisage, ie. whether all your dates in a chart will be restricted to the pre Dec 1899 period or whether you expect a mixture of pre-post 1899 mixes in a single chart? ... or whether showing just whole day increments may be sufficient.

The problem (for us as chart designers) comes down to the date implementation by Microsoft for Windows. The zero date being midnight, 30 December 1899.

Note from the reference here:
https://learn.microsoft.com/en-us/dotne ... ew=net-8.0
An OLE Automation date is implemented as a floating-point number whose integral component is the number of days before or after midnight, 30 December 1899, and whose fractional component represents the time on that day divided by 24. For example, midnight, 31 December 1899 is represented by 1.0; 6 A.M., 1 January 1900 is represented by 2.25; midnight, 29 December 1899 is represented by -1.0; and 6 A.M., 29 December 1899 is represented by -1.25.
That makes it easy to handle whole days linearly, as they count back from 0. 1 being 29th Dec 1899, 2 being 28th, etc. But the inconvenience is that the fractional part of each day, 1/24 being one hour, is also counted backwards meaning that a simple date conversion in a table is no problem but that visually, on a chart, time goes backwards from the 30 December 1899.

For a chart merely showing whole days that is fine but to resolve that for each incremental fraction of the day requires inverting the fractional part of each integer (day) segment for any day-time data to plot correctly. We are looking at options.

In the meantime, an alternative option would be to set the x-values of the Series as non-datetime, simply numeric incremented values like 1,2,3 ..., and to set Labels either from an associated label table or calculating them according to a value algorithm.

We can work on an example for that if you're able to confirm a little about your intended use of the daterange.

With thanks.
Regards,
Marc Meumann

Re: XValues in the 1800's Not Working Correctly

Posted: Fri Jul 19, 2024 12:21 pm
by 13049545
DDT5.jpg
JFKRectification
DDT5.jpg (114.85 KiB) Viewed 16718 times
Hi Marc,
My website, HarmonicLife, figures out people's birth times given important dates in their lives -- ie Rectification.
So all of my charts are within one day.
Anyone born before 1899, ie historical figures, will run into this issue.
Julian's dates are doubles, so if I could use a double for X-Axis and then format the labels to UTC and Local Time, that would work, but I'd have to retool my reports, which will take time and testing, etc...
And time is limited.

Hopefully, you can recode for pre-1899 intraday charts to reverse your intraday intervals and no one else will run into this issue later on.
I can't believe I'm the first.

Man, I'm getting old.

:)

Thanks,

Joseph

Re: XValues in the 1800's Not Working Correctly

Posted: Fri Jul 19, 2024 2:54 pm
by Marc
Hello Joseph,

If your charts are showing one full day or less then we may have a straightforward solution, to invert the Axis.

This sample code for example:

Code: Select all

DateTime startDate = new DateTime(1892, 12, 29, 0, 0, 0);

if (startDate.ToOADate() <= 0)
    tChart1.Axes.Bottom.Inverted = true;

for (int i = 0; i < 24; i++)
{
    DateTime currentDayTime = startDate.AddHours(i);
    tChart1[0].Add(currentDayTime, i);
}

tChart1.Axes.Bottom.Labels.DateTimeFormat = "dd/MM/yyyy HH:mm:ss";
tChart1.Axes.Bottom.Labels.Angle = 90;
1892Dtes.png
1892Dtes.png (14.29 KiB) Viewed 16712 times
Re:
I can't believe I'm the first.
Unbelievably I'd say "yes" ... I've worked with TeeChart for a chunk of years and have never come close to perceiving this issue. It's been an interesting encounter, thank you for bringing it to our attention.

We'll see if we can find a better generic solution.

Regards,
Marc

Re: XValues in the 1800's Not Working Correctly

Posted: Fri Jul 19, 2024 10:56 pm
by 13049545
Marc,
Even though I work in 24-hour spans, some time bands cross Date Boundaries ie 12 hours one day and 12 hours the next day. I'll try it out this weekend and see what happens.
Thanks,
ja

Re: XValues in the 1800's Not Working Correctly

Posted: Wed Jul 24, 2024 8:30 am
by Marc
Hello Joseph,

An alternative workaround suggestion: Assuming that the range for the x-axis could exceed one day then perhaps the easiest thing to do would be to move the dates to a workable range and then modify the year label.

ie.

Code: Select all

bool pre1900 = false;
int dateYear;

private void InitializeChart()
{
    DateTime startDate = new DateTime(1892, 12, 29, 0, 0, 0);

    if (startDate.ToOADate() <= 0)
    {
        startDate = startDate.AddYears(100);
        dateYear = startDate.Year;
        pre1900 = true;
    }

    for (int i = 0; i < 36; i++)
    {
        DateTime currentDayTime = startDate.AddHours(i);
        tChart1[0].Add(currentDayTime, i);
    }

    tChart1.Axes.Bottom.Labels.DateTimeFormat = "dd/MM/yyyy HH:mm:ss";
    tChart1.Axes.Bottom.Labels.Angle = 90;
}

private void tChart1_GetAxisLabel(object sender, GetAxisLabelEventArgs e)
{
    if ((sender == tChart1.Axes.Bottom) && (pre1900))
        e.LabelText = e.LabelText.Replace(dateYear.ToString(), (dateYear-100).ToString());
}
20240724_Pre1900Dates.png
20240724_Pre1900Dates.png (14.23 KiB) Viewed 16497 times
I hope that something in there may prove useable.

Regards,
Marc

Re: XValues in the 1800's Not Working Correctly

Posted: Wed Jul 24, 2024 8:44 am
by 13049545
I'll give it a try this weekend. Looks promising.
Thanks for your help Marc!
ja