KStarsDateTime clone constructor needs proper millisecond rounding
When initialising a KStarsDateTime
time to 2020-01-01 23:00
and assigning another KStarsDateTime
with it, the cloned KStarsDateTime
is set to 2020-01-01 22:59
.
After a few step-intos, the problem happens at kstars.cpp:192
, when the copy constructor of KStarsDateTime
is called to receive the command-line date/time argument string. That copy constructor uses the Julian day as reference. And it appears the Julian day fraction calculated by the cast of QDateTime
into KStarsDateTime
at kstarsdatetime.cpp:57
, in this case, is a bit smaller than expected.
KStarsDateTime::KStarsDateTime(const QDateTime &qdt) : QDateTime(qdt) //, QDateTime::Spec::UTC() )
{
// FIXME: This method might be buggy. Need to write some tests -- asimha (Oct 2016)
QTime _t = qdt.time();
QDate _d = qdt.date();
long double jdFrac = (_t.hour() - 12 + (_t.minute() + (_t.second() + _t.msec() / 1000.) / 60.) / 60.) / 24.;
DJD = static_cast<long double>(_d.toJulianDay()) + jdFrac;
setTimeSpec(qdt.timeSpec());
//setUtcOffset(qdt.utcOffset());
}
The KStarsDateTime
clone constructor at kstars.cpp:192
is then using the Julian day only and converts it back into a QTime:
if (StartDateString.isEmpty() == false)
{
KStarsDateTime startDate = KStarsDateTime::fromString(StartDateString);
if (startDate.isValid())
data()->changeDateTime(data()->geo()->LTtoUT(startDate));
else
data()->changeDateTime(KStarsDateTime::currentDateTimeUtc());
datetimeSet = true;
}
And KStarsDateTime::SetDJD
is actually missing something:
void KStarsDateTime::setDJD(long double _jd)
{
(...)
double hour = 24. * dayfrac;
int h = int(hour);
int m = int(60. * (hour - h));
int s = int(60. * (60. * (hour - h) - m));
int ms = int(1000. * (60. * (60. * (hour - h) - m) - s));
QDateTime::setTime(QTime(h, m, s, ms));
}
In the problematic situation, dayfrac
equals 22.99999999999818
. I believe the bug is then in the setDJD
function, which does not round milliseconds properly. The epsilon coming from that rounding should push the millisecond up by one, pushing the carry up to seconds, minutes and hours.
@asimha I'm interested in your opinion, as we have a test for your comment somehow :)