diff --git a/kosmorrolib/__init__.py b/kosmorrolib/__init__.py
index d317d1c..6eaf919 100644
--- a/kosmorrolib/__init__.py
+++ b/kosmorrolib/__init__.py
@@ -3,4 +3,4 @@
from .model import Position, Event, AsterEphemerides, Object
from .ephemerides import get_ephemerides, get_moon_phase
from .events import get_events
-from .enum import EventType, MoonPhaseType
+from .enum import *
diff --git a/kosmorrolib/dateutil.py b/kosmorrolib/dateutil.py
index b5a8fda..472b733 100644
--- a/kosmorrolib/dateutil.py
+++ b/kosmorrolib/dateutil.py
@@ -12,3 +12,21 @@ def translate_to_timezone(date: datetime, to_tz: int, from_tz: int = None):
return date.replace(tzinfo=source_tz).astimezone(
tz=timezone(timedelta(hours=to_tz))
)
+
+
+def normalize_datetime(date: datetime) -> datetime:
+ """Round the seconds in the given datetime
+
+ >>> normalize_datetime(datetime(2021, 6, 9, 2, 30, 29))
+ datetime.datetime(2021, 6, 9, 2, 30)
+
+ >>> normalize_datetime(datetime(2021, 6, 9, 2, 30, 30))
+ datetime.datetime(2021, 6, 9, 2, 31)
+ """
+ return datetime(
+ date.year,
+ date.month,
+ date.day,
+ date.hour,
+ date.minute if date.second < 30 else date.minute + 1,
+ )
diff --git a/kosmorrolib/enum.py b/kosmorrolib/enum.py
index 03676ec..e9420cd 100644
--- a/kosmorrolib/enum.py
+++ b/kosmorrolib/enum.py
@@ -25,3 +25,28 @@ class EventType(Enum):
MAXIMAL_ELONGATION = 4
MOON_PERIGEE = 5
MOON_APOGEE = 6
+
+
+class ObjectType(Enum):
+ """An enumeration of object types"""
+
+ STAR = 0
+ PLANET = 1
+ DWARF_PLANET = 11
+ SATELLITE = 2
+
+
+class ObjectIdentifier(Enum):
+ """An enumeration of identifiers for objects"""
+
+ SUN = 0
+ EARTH = 1
+ MOON = 11
+ MERCURY = 2
+ VENUS = 3
+ MARS = 4
+ JUPITER = 5
+ SATURN = 6
+ URANUS = 7
+ NEPTUNE = 8
+ PLUTO = 9
diff --git a/kosmorrolib/ephemerides.py b/kosmorrolib/ephemerides.py
index 14f5397..f201183 100644
--- a/kosmorrolib/ephemerides.py
+++ b/kosmorrolib/ephemerides.py
@@ -9,7 +9,7 @@ from skyfield.constants import tau
from skyfield.errors import EphemerisRangeError
from .model import Position, AsterEphemerides, MoonPhase, Object, ASTERS
-from .dateutil import translate_to_timezone
+from .dateutil import translate_to_timezone, normalize_datetime
from .core import get_skf_objects, get_timescale, get_iau2000b
from .enum import MoonPhaseType
from .exceptions import OutOfRangeDateError
@@ -121,12 +121,12 @@ def get_ephemerides(
>>> pos = Position(50.5824, 3.0624)
>>> get_ephemerides(pos, datetime.date(2021, 6, 9))
- [>, >, >, >, >, >, >, >, >, >]
+ [>, >, >, >, >, >, >, >, >, >]
Compute the ephemerides for June 9th, 2021:
>>> get_ephemerides(pos, datetime.date(2021, 6, 9), timezone=2)
- [>, >, >, >, >, >, >, >, >, >]
+ [>, >, >, >, >, >, >, >, >, >]
"""
ephemerides = []
@@ -182,19 +182,25 @@ def get_ephemerides(
# Convert the Time instances to Python datetime objects
if rise_time is not None:
- rise_time = translate_to_timezone(
- rise_time.utc_datetime().replace(microsecond=0), to_tz=timezone
+ rise_time = normalize_datetime(
+ translate_to_timezone(
+ rise_time.utc_datetime().replace(microsecond=0), to_tz=timezone
+ )
)
if culmination_time is not None:
- culmination_time = translate_to_timezone(
- culmination_time.utc_datetime().replace(microsecond=0),
- to_tz=timezone,
+ culmination_time = normalize_datetime(
+ translate_to_timezone(
+ culmination_time.utc_datetime().replace(microsecond=0),
+ to_tz=timezone,
+ )
)
if set_time is not None:
- set_time = translate_to_timezone(
- set_time.utc_datetime().replace(microsecond=0), to_tz=timezone
+ set_time = normalize_datetime(
+ translate_to_timezone(
+ set_time.utc_datetime().replace(microsecond=0), to_tz=timezone
+ )
)
ephemerides.append(
diff --git a/kosmorrolib/events.py b/kosmorrolib/events.py
index f1d1e86..efa36d3 100644
--- a/kosmorrolib/events.py
+++ b/kosmorrolib/events.py
@@ -219,17 +219,17 @@ def get_events(date: date_type = date_type.today(), timezone: int = 0) -> [Event
Find events that happen on April 4th, 2020 (show hours in UTC):
>>> get_events(date_type(2020, 4, 4))
- [, ] start=2020-04-04 01:14:39.063308+00:00 end=None details=None />]
+ [, ] start=2020-04-04 01:14:39.063308+00:00 end=None details=None />]
Find events that happen on April 4th, 2020 (show timezones in UTC+2):
>>> get_events(date_type(2020, 4, 4), 2)
- [, ] start=2020-04-04 03:14:39.063267+02:00 end=None details=None />]
+ [, ] start=2020-04-04 03:14:39.063267+02:00 end=None details=None />]
Find events that happen on April 3rd, 2020 (show timezones in UTC-2):
>>> get_events(date_type(2020, 4, 3), -2)
- [, ] start=2020-04-03 23:14:39.063388-02:00 end=None details=None />]
+ [, ] start=2020-04-03 23:14:39.063388-02:00 end=None details=None />]
:param date: the date for which the events must be calculated
:param timezone: the timezone to adapt the results to. If not given, defaults to 0.
diff --git a/kosmorrolib/model.py b/kosmorrolib/model.py
index 45ab90e..42db7a9 100644
--- a/kosmorrolib/model.py
+++ b/kosmorrolib/model.py
@@ -10,7 +10,7 @@ from skyfield.api import Topos, Time
from skyfield.vectorlib import VectorSum as SkfPlanet
from .core import get_skf_objects
-from .enum import MoonPhaseType, EventType
+from .enum import MoonPhaseType, EventType, ObjectIdentifier, ObjectType
class Serializable(ABC):
@@ -66,27 +66,32 @@ class Object(Serializable):
An astronomical object.
"""
- def __init__(self, name: str, skyfield_name: str, radius: float = None):
+ def __init__(
+ self, identifier: ObjectIdentifier, skyfield_name: str, radius: float = None
+ ):
"""
Initialize an astronomical object
- :param str name: the official name of the object (may be internationalized)
+ :param ObjectIdentifier identifier: the official name of the object (may be internationalized)
:param str skyfield_name: the internal name of the object in Skyfield library
:param float radius: the radius (in km) of the object
:param AsterEphemerides ephemerides: the ephemerides associated to the object
"""
- self.name = name
+ self.identifier = identifier
self.skyfield_name = skyfield_name
self.radius = radius
def __repr__(self):
- return "" % (self.get_type(), self.name)
+ return "" % (
+ self.get_type().name,
+ self.identifier.name,
+ )
def get_skyfield_object(self) -> SkfPlanet:
return get_skf_objects()[self.skyfield_name]
@abstractmethod
- def get_type(self) -> str:
+ def get_type(self) -> ObjectType:
pass
def get_apparent_radius(self, time: Time, from_place) -> float:
@@ -97,7 +102,7 @@ class Object(Serializable):
:return:
"""
if self.radius is None:
- raise ValueError("Missing radius for %s object" % self.name)
+ raise ValueError("Missing radius for %s" % self.identifier.name)
return (
360
@@ -110,30 +115,30 @@ class Object(Serializable):
def serialize(self) -> dict:
return {
- "name": self.name,
+ "identifier": self.identifier.name,
"type": self.get_type(),
"radius": self.radius,
}
class Star(Object):
- def get_type(self) -> str:
- return "star"
+ def get_type(self) -> ObjectType:
+ return ObjectType.STAR
class Planet(Object):
- def get_type(self) -> str:
- return "planet"
+ def get_type(self) -> ObjectType:
+ return ObjectType.PLANET
class DwarfPlanet(Planet):
- def get_type(self) -> str:
- return "dwarf_planet"
+ def get_type(self) -> ObjectType:
+ return ObjectType.DWARF_PLANET
class Satellite(Object):
- def get_type(self) -> str:
- return "satellite"
+ def get_type(self) -> ObjectType:
+ return ObjectType.SATELLITE
class Event(Serializable):
@@ -216,19 +221,19 @@ class AsterEphemerides(Serializable):
}
-EARTH = Planet("Earth", "EARTH")
+EARTH = Planet(ObjectIdentifier.EARTH, "EARTH")
ASTERS = [
- Star("Sun", "SUN", radius=696342),
- Satellite("Moon", "MOON", radius=1737.4),
- Planet("Mercury", "MERCURY", radius=2439.7),
- Planet("Venus", "VENUS", radius=6051.8),
- Planet("Mars", "MARS", radius=3396.2),
- Planet("Jupiter", "JUPITER BARYCENTER", radius=71492),
- Planet("Saturn", "SATURN BARYCENTER", radius=60268),
- Planet("Uranus", "URANUS BARYCENTER", radius=25559),
- Planet("Neptune", "NEPTUNE BARYCENTER", radius=24764),
- Planet("Pluto", "PLUTO BARYCENTER", radius=1185),
+ Star(ObjectIdentifier.SUN, "SUN", radius=696342),
+ Satellite(ObjectIdentifier.MOON, "MOON", radius=1737.4),
+ Planet(ObjectIdentifier.MERCURY, "MERCURY", radius=2439.7),
+ Planet(ObjectIdentifier.VENUS, "VENUS", radius=6051.8),
+ Planet(ObjectIdentifier.MARS, "MARS", radius=3396.2),
+ Planet(ObjectIdentifier.JUPITER, "JUPITER BARYCENTER", radius=71492),
+ Planet(ObjectIdentifier.SATURN, "SATURN BARYCENTER", radius=60268),
+ Planet(ObjectIdentifier.URANUS, "URANUS BARYCENTER", radius=25559),
+ Planet(ObjectIdentifier.NEPTUNE, "NEPTUNE BARYCENTER", radius=24764),
+ Planet(ObjectIdentifier.PLUTO, "PLUTO BARYCENTER", radius=1185),
]
diff --git a/tests/data.py b/tests/data.py
index 0cab89c..e956a3d 100644
--- a/tests/data.py
+++ b/tests/data.py
@@ -1,18 +1,19 @@
import unittest
from kosmorrolib import model, core
+from kosmorrolib.enum import ObjectIdentifier
class DataTestCase(unittest.TestCase):
def test_object_radius_must_be_set_to_get_apparent_radius(self):
- o = model.Planet("Saturn", "SATURN")
+ o = model.Planet(ObjectIdentifier.SATURN, "SATURN")
with self.assertRaises(ValueError) as context:
o.get_apparent_radius(
core.get_timescale().now(), core.get_skf_objects()["earth"]
)
- self.assertEqual(("Missing radius for Saturn object",), context.exception.args)
+ self.assertEqual(("Missing radius for SATURN",), context.exception.args)
if __name__ == "__main__":
diff --git a/tests/ephemerides.py b/tests/ephemerides.py
index 589f7ee..653d520 100644
--- a/tests/ephemerides.py
+++ b/tests/ephemerides.py
@@ -18,11 +18,11 @@ class EphemeridesTestCase(unittest.TestCase):
def do_assertions(assert_regex):
for ephemeris in eph:
if ephemeris.object.skyfield_name == "SUN":
- assert_regex(ephemeris.rise_time.isoformat(), "^2019-11-18T05:41:")
+ assert_regex(ephemeris.rise_time.isoformat(), "^2019-11-18T05:42:")
assert_regex(
ephemeris.culmination_time.isoformat(), "^2019-11-18T11:45:"
)
- assert_regex(ephemeris.set_time.isoformat(), "^2019-11-18T17:48:")
+ assert_regex(ephemeris.set_time.isoformat(), "^2019-11-18T17:49:")
break
do_assertions()