skyfielders / python-skyfield

Elegant astronomy for Python
MIT License
1.38k stars 208 forks source link

Comparison operators not implemented between Time objects #881

Closed Engineero closed 5 months ago

Engineero commented 11 months ago

An example is given below.

from skyfield.api import load
from datetime import timedelta

ts = load.timescale()
now = ts.now()
future = now + timedelta(days=1)

now < future
  # TypeError: '<' not supported between instances of 'Time' and 'Time'
future > now
  # TypeError: '>' not supported between instances of 'Time' and 'Time'

I'd expect that comparison operators would work between time objects, e.g., that t1 < t2 would return True if t1 occurs before t2 and False otherwise. This behaves as expected with datetime objects (example below).

from datetime import datetime, timedelta

now = datetime.now()
future = now + timedelta(days=1)

now < future
  # True
future > now
  # True

For Skyfield applications, this would be helpful if, for instance, you are interested when a satellite reaches culmination (obtainable with EarthSatellite.find_events) whether it is sunlit (EarthSatellite.at(time).is_sunlit) and the observatory is not (almanac.find_discrete). The problem I'm running into doing something like this without comparisons is that culmination is a single time value, which can be used directly to find whether the object is sunlit at that time, but almanac gives discrete time values for twilight/darkness start/end as well, so I need to figure out whether my culmination value lies between some darkness start/end time that I've deemed dark enough.

brandon-rhodes commented 11 months ago

While I generally try to avoid adding too many magic methods to Skyfield objects, I think there's definite value to a comparison operator between times, because it takes so many steps to do correctly — while you can compare, say, two angles quite easily, by comparing their .degrees, you can't easily compare two times at high precision because they are built out of two floating point numbers rather than one.

So I'll plan to add a simple comparison operator in the next version; it should be simple enough.