You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Although python's datetime objects support microsecond resolution, and Time objects support sub-nanosecond resolution, conversion and arithmetic between the two can be off by tens of microseconds. (By design datetime objects do not support leap seconds, so UTC cannot be expected to work. The problems described here are for non-UTC timescales like TAI.)
Expected behavior
Computing the difference between two datetime objects then converting to a TimeDelta should give the same result as converting the datetime objects to Time objects and subtracting, to within a couple of microseconds.
Actual behavior
In fact PR #9532 demonstrates several examples where the difference exceeds 20 microseconds.
No time right now to fix it, but I did find the problem: it is in the TimeDelta creation - the TimeDeltaDatetime class is based on timedelta.total_seconds() which returns a double, hence the loss of precision (for this case with a very large number of days). Instead it should combine the timedelta.{days, seconds, microseconds} attributes. Similarly, the value property should properly initialize using days, seconds, and microseconds. This should be a very easy fix, so labeling it accordingly.
@mhvk – I'm working on this and I've I implemented the first part of your suggestion (getting rid of total_seconds), but I'm not sure about what should happen to value – how does one take the JD and properly construct a datetime.timedelta using days, seconds, microseconds? Thanks!
@bmorris3 - I haven't thought too hard, and it depends a little what timedelta does internally, but jd1 is the integer part of the JD difference, so is in days, and then one can construct seconds and microseconds from jd2 using something like
@bmorris3 - I haven't thought too hard, and it depends a little what timedelta does internally, but jd1 is the integer part of the JD difference, so is in days, and then one can construct seconds and microseconds from jd2 using something like
Not to be difficult, but I'd like to point out that we were just talking about how we do not guarantee that jd1 and jd2 are related in this way. And in fact as a result of bug #9533 jd1 is not always an integer. For this code, it's probably safest to run jd1, jd2 = day_frac(jd1, jd2) first.
@mhvk , "package-novice" might be a little misleading here, as the solution is only obvious when one already know the code base a little. As someone who doesn't touch the time sub-package, I glanced at the conversation and I didn't get a clear picture on where to start, so I re-labeled it to "package-intermediate". FYI.
Activity
mhvk commentedon Nov 10, 2019
No time right now to fix it, but I did find the problem: it is in the
TimeDeltacreation - theTimeDeltaDatetimeclass is based ontimedelta.total_seconds()which returns a double, hence the loss of precision (for this case with a very large number of days). Instead it should combine thetimedelta.{days, seconds, microseconds}attributes. Similarly, thevalueproperty should properly initialize usingdays,seconds, andmicroseconds. This should be a very easy fix, so labeling it accordingly.bmorris3 commentedon Nov 11, 2019
@mhvk – I'm working on this and I've I implemented the first part of your suggestion (getting rid of
total_seconds), but I'm not sure about what should happen tovalue– how does one take the JD and properly construct adatetime.timedeltausingdays,seconds,microseconds? Thanks!mhvk commentedon Nov 11, 2019
@bmorris3 - I haven't thought too hard, and it depends a little what
timedeltadoes internally, butjd1is the integer part of the JD difference, so is in days, and then one can constructsecondsandmicrosecondsfrom jd2 using something likeaarchiba commentedon Nov 11, 2019
Not to be difficult, but I'd like to point out that we were just talking about how we do not guarantee that jd1 and jd2 are related in this way. And in fact as a result of bug #9533 jd1 is not always an integer. For this code, it's probably safest to run
jd1, jd2 = day_frac(jd1, jd2)first.mhvk commentedon Nov 11, 2019
Actually,
timedeltadoes the addition of days and seconds internally anyway. At the precision needed here, I'd probably dobmorris3 commentedon Nov 11, 2019
Thanks for the tips, but neither tip seems to help make the proposed test pass. I think I'm missing something.
pllim commentedon Nov 11, 2019
@mhvk , "package-novice" might be a little misleading here, as the solution is only obvious when one already know the code base a little. As someone who doesn't touch the
timesub-package, I glanced at the conversation and I didn't get a clear picture on where to start, so I re-labeled it to "package-intermediate". FYI.Introduce non-hypothesis example for use in astropy#9579
Fix datetime accuracy
Add hypothesis testing for Time precision
aarchiba commentedon Nov 26, 2019
Indeed I think the subtlety is that your conversion, in both directions, needs to make full use of jd1 and jd2.
Add hypothesis testing for Time precision
Fix datetime accuracy