Deuchnord 3 тижднів тому
committed by GitHub
джерело
коміт
0e1f23045a
Не вдалося знайти GPG ключ що відповідає даному підпису Ідентифікатор GPG ключа: B5690EEEBB952194
3 змінених файлів з 167 додано та 79 видалено
  1. +5
    -5
      kosmorrolib/dateutil.py
  2. +73
    -26
      kosmorrolib/ephemerides.py
  3. +89
    -48
      kosmorrolib/events.py

+ 5
- 5
kosmorrolib/dateutil.py Переглянути файл

@@ -19,18 +19,18 @@
from datetime import datetime, timezone, timedelta


def translate_to_timezone(date: datetime, to_tz: int):
"""Convert a datetime from a timezone to another.
def translate_to_utc_offset(date: datetime, to_tz: int):
"""Convert a datetime from a UTC offset to another.

>>> translate_to_timezone(datetime(2021, 6, 9, 5, 0, 0, tzinfo=timezone.utc), 2)
>>> translate_to_utc_offset(datetime(2021, 6, 9, 5, 0, 0, tzinfo=timezone.utc), 2)
datetime.datetime(2021, 6, 9, 7, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200)))

>>> translate_to_timezone(datetime(2021, 6, 9, 5, 0, 0, tzinfo=timezone(timedelta(hours=1))), 2)
>>> translate_to_utc_offset(datetime(2021, 6, 9, 5, 0, 0, tzinfo=timezone(timedelta(hours=1))), 2)
datetime.datetime(2021, 6, 9, 6, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200)))

If the datetime has no timezone information, then it is interpreted as UTC:

>>> translate_to_timezone(datetime(2021, 6, 9, 5, 0, 0), 2)
>>> translate_to_utc_offset(datetime(2021, 6, 9, 5, 0, 0), 2)
datetime.datetime(2021, 6, 9, 7, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200)))
"""
source_tz = date.tzinfo if date.tzinfo is not None else timezone.utc


+ 73
- 26
kosmorrolib/ephemerides.py Переглянути файл

@@ -25,8 +25,14 @@ from skyfield.constants import tau
from skyfield.errors import EphemerisRangeError

from .model import Position, AsterEphemerides, MoonPhase, Object, ASTERS
from .dateutil import translate_to_timezone, normalize_datetime
from .core import get_skf_objects, get_timescale, get_iau2000b
from .dateutil import translate_to_utc_offset, normalize_datetime
from .core import (
get_skf_objects,
get_timescale,
get_iau2000b,
deprecated,
alert_deprecation,
)
from .enum import MoonPhaseType
from .exceptions import OutOfRangeDateError

@@ -34,7 +40,7 @@ RISEN_ANGLE = -0.8333


def _get_skyfield_to_moon_phase(
times: [Time], vals: [int], now: Time, timezone: int
times: [Time], vals: [int], now: Time, utc_offset: Union[int, float]
) -> Union[MoonPhase, None]:
tomorrow = get_timescale().utc(
now.utc_datetime().year, now.utc_datetime().month, now.utc_datetime().day + 1
@@ -58,21 +64,27 @@ def _get_skyfield_to_moon_phase(
MoonPhaseType.FULL_MOON,
MoonPhaseType.LAST_QUARTER,
]:
current_phase_time = translate_to_timezone(times[i].utc_datetime(), timezone)
current_phase_time = translate_to_utc_offset(
times[i].utc_datetime(), utc_offset
)
else:
current_phase_time = None

# Find the next moon phase
for j in range(i + 1, len(times)):
if vals[j] in [0, 2, 4, 6]:
next_phase_time = translate_to_timezone(times[j].utc_datetime(), timezone)
next_phase_time = translate_to_utc_offset(
times[j].utc_datetime(), utc_offset
)
break

return MoonPhase(current_phase, current_phase_time, next_phase_time)


def get_moon_phase(for_date: date = date.today(), timezone: int = 0) -> MoonPhase:
"""Calculate and return the moon phase for the given date, adjusted to the given timezone if any.
def get_moon_phase(
for_date: date = date.today(), utc_offset: Union[int, float] = 0, **argv
) -> MoonPhase:
"""Calculate and return the moon phase for the given date, adjusted to the given UTC offset if any.

Get the moon phase for the 27 March, 2021:

@@ -85,7 +97,12 @@ def get_moon_phase(for_date: date = date.today(), timezone: int = 0) -> MoonPhas
>>> get_moon_phase(datetime(2021, 3, 28))
<MoonPhase phase_type=MoonPhaseType.FULL_MOON time=2021-03-28 18:48:10.902298+00:00 next_phase_date=2021-04-04 10:02:27.393689+00:00>

Get the moon phase for the 27 March, 2021, in the UTC+2 timezone:
Get the moon phase for the 27 March, 2021, in UTC+2:

>>> get_moon_phase(date(2021, 3, 27), utc_offset=2)
<MoonPhase phase_type=MoonPhaseType.WAXING_GIBBOUS time=None next_phase_date=2021-03-28 20:48:10.902298+02:00>

Note that the `utc_offset` argument was named `timezone` before version 1.1. The old name still works, but will be dropped in the future.

>>> get_moon_phase(date(2021, 3, 27), timezone=2)
<MoonPhase phase_type=MoonPhaseType.WAXING_GIBBOUS time=None next_phase_date=2021-03-28 20:48:10.902298+02:00>
@@ -98,6 +115,13 @@ def get_moon_phase(for_date: date = date.today(), timezone: int = 0) -> MoonPhas
...
kosmorrolib.exceptions.OutOfRangeDateError: The date must be between 1899-08-09 and 2053-09-26
"""

if argv.get("timezone") is not None:
alert_deprecation(
"'timezone' argument of the get_moon_phase() function is deprecated. Use utc_offset instead."
)
utc_offset = argv.get("timezone")

earth = get_skf_objects()["earth"]
moon = get_skf_objects()["moon"]
sun = get_skf_objects()["sun"]
@@ -117,11 +141,11 @@ def get_moon_phase(for_date: date = date.today(), timezone: int = 0) -> MoonPhas

try:
times, phases = find_discrete(start_time, end_time, moon_phase_at)
return _get_skyfield_to_moon_phase(times, phases, today, timezone)
return _get_skyfield_to_moon_phase(times, phases, today, utc_offset)

except EphemerisRangeError as error:
start = translate_to_timezone(error.start_time.utc_datetime(), timezone)
end = translate_to_timezone(error.end_time.utc_datetime(), timezone)
start = translate_to_utc_offset(error.start_time.utc_datetime(), utc_offset)
end = translate_to_utc_offset(error.end_time.utc_datetime(), utc_offset)

start = date(start.year, start.month, start.day) + timedelta(days=12)
end = date(end.year, end.month, end.day) - timedelta(days=12)
@@ -130,9 +154,12 @@ def get_moon_phase(for_date: date = date.today(), timezone: int = 0) -> MoonPhas


def get_ephemerides(
position: Position, for_date: date = date.today(), timezone: int = 0
position: Position,
for_date: date = date.today(),
utc_offset: Union[int, float] = 0,
**argv
) -> [AsterEphemerides]:
"""Compute and return the ephemerides for the given position and date, adjusted to the given timezone if any.
"""Compute and return the ephemerides for the given position and date, adjusted to the given UTC offset if any.

Compute the ephemerides for July 7th, 2022:

@@ -148,9 +175,9 @@ def get_ephemerides(
<AsterEphemerides rise_time=2022-07-07 22:27:00 culmination_time=2022-07-07 04:25:00 set_time=2022-07-07 10:20:00 aster=<Object type=PLANET name=NEPTUNE />>,
<AsterEphemerides rise_time=2022-07-07 19:46:00 culmination_time=2022-07-07 00:41:00 set_time=2022-07-07 05:33:00 aster=<Object type=PLANET name=PLUTO />>]

Timezone can be optionnaly set to adapt the hours to your location:
UTC offset can be optionnaly set to adapt the hours to your location:

>>> get_ephemerides(Position(36.6794, 4.8555), date(2022, 7, 7), timezone=2)
>>> get_ephemerides(Position(36.6794, 4.8555), date(2022, 7, 7), utc_offset=2)
[<AsterEphemerides rise_time=2022-07-07 06:29:00 culmination_time=2022-07-07 13:46:00 set_time=2022-07-07 21:02:00 aster=<Object type=STAR name=SUN />>,
<AsterEphemerides rise_time=2022-07-07 14:16:00 culmination_time=2022-07-07 20:06:00 set_time=2022-07-07 01:27:00 aster=<Object type=SATELLITE name=MOON />>,
<AsterEphemerides rise_time=2022-07-07 05:36:00 culmination_time=2022-07-07 12:58:00 set_time=2022-07-07 20:20:00 aster=<Object type=PLANET name=MERCURY />>,
@@ -163,6 +190,20 @@ def get_ephemerides(
<AsterEphemerides rise_time=2022-07-07 21:46:00 culmination_time=2022-07-07 02:41:00 set_time=2022-07-07 07:33:00 aster=<Object type=PLANET name=PLUTO />>]


Note that the `utc_offset` argument was named `timezone` before version 1.1. The old name still works, but will be dropped in the future.

>>> get_ephemerides(Position(36.6794, 4.8555), date(2022, 7, 7), timezone=2)
[<AsterEphemerides rise_time=2022-07-07 06:29:00 culmination_time=2022-07-07 13:46:00 set_time=2022-07-07 21:02:00 aster=<Object type=STAR name=SUN />>,
<AsterEphemerides rise_time=2022-07-07 14:16:00 culmination_time=2022-07-07 20:06:00 set_time=2022-07-07 01:27:00 aster=<Object type=SATELLITE name=MOON />>,
<AsterEphemerides rise_time=2022-07-07 05:36:00 culmination_time=2022-07-07 12:58:00 set_time=2022-07-07 20:20:00 aster=<Object type=PLANET name=MERCURY />>,
<AsterEphemerides rise_time=2022-07-07 04:30:00 culmination_time=2022-07-07 11:44:00 set_time=2022-07-07 18:58:00 aster=<Object type=PLANET name=VENUS />>,
<AsterEphemerides rise_time=2022-07-07 02:05:00 culmination_time=2022-07-07 08:39:00 set_time=2022-07-07 15:14:00 aster=<Object type=PLANET name=MARS />>,
<AsterEphemerides rise_time=2022-07-07 01:02:00 culmination_time=2022-07-07 07:11:00 set_time=2022-07-07 13:20:00 aster=<Object type=PLANET name=JUPITER />>,
<AsterEphemerides rise_time=2022-07-07 23:06:00 culmination_time=2022-07-07 04:29:00 set_time=2022-07-07 09:48:00 aster=<Object type=PLANET name=SATURN />>,
<AsterEphemerides rise_time=2022-07-07 02:47:00 culmination_time=2022-07-07 09:42:00 set_time=2022-07-07 16:38:00 aster=<Object type=PLANET name=URANUS />>,
<AsterEphemerides rise_time=2022-07-07 00:31:00 culmination_time=2022-07-07 06:25:00 set_time=2022-07-07 12:20:00 aster=<Object type=PLANET name=NEPTUNE />>,
<AsterEphemerides rise_time=2022-07-07 21:46:00 culmination_time=2022-07-07 02:41:00 set_time=2022-07-07 07:33:00 aster=<Object type=PLANET name=PLUTO />>]

Objects may not rise or set on the given date (e.g. they rise the previous day or set the next day).
In this case, you will get `None` values on the rise or set time.

@@ -226,10 +267,16 @@ def get_ephemerides(
...
kosmorrolib.exceptions.OutOfRangeDateError: The date must be between 1899-07-29 and 2053-10-07

- The date given in parameter is considered as being given from the point of view of the given timezone.
Using a timezone that does not correspond to the place's actual one can impact the returned times.
- The date given in parameter is considered as being given from the point of view of the given UTC offset.
Using a UTC offset that does not correspond to the place's actual one can impact the returned times.
"""

if argv.get("timezone") is not None:
alert_deprecation(
"'timezone' argument of the get_ephemerides() function is deprecated. Use utc_offset instead."
)
utc_offset = argv.get("timezone")

def get_angle(for_aster: Object):
def fun(time: Time) -> float:
return (
@@ -251,15 +298,15 @@ def get_ephemerides(
fun.rough_period = 0.5
return fun

# The date given in argument is supposed to be given in the given timezone (more natural for a human),
# but we need it in UTC. Subtracting the timezone to get it in UTC.
# The date given in argument is supposed to be given in the given UTC offset (more natural for a human),
# but we need it in UTC. Subtracting the offset to get it in UTC.

start_time = get_timescale().utc(
for_date.year, for_date.month, for_date.day, -timezone
for_date.year, for_date.month, for_date.day, -utc_offset
)

end_time = get_timescale().utc(
for_date.year, for_date.month, for_date.day + 1, -timezone
for_date.year, for_date.month, for_date.day + 1, -utc_offset
)

ephemerides = []
@@ -276,7 +323,7 @@ def get_ephemerides(

for i, time in enumerate(times):
time_dt = normalize_datetime(
translate_to_timezone(time.utc_datetime(), to_tz=timezone)
translate_to_utc_offset(time.utc_datetime(), to_tz=utc_offset)
)

if time_dt is not None and time_dt.day != for_date.day:
@@ -289,9 +336,9 @@ def get_ephemerides(

if culmination_time is not None:
culmination_time = normalize_datetime(
translate_to_timezone(
translate_to_utc_offset(
culmination_time.utc_datetime(),
to_tz=timezone,
to_tz=utc_offset,
)
)

@@ -299,8 +346,8 @@ def get_ephemerides(
AsterEphemerides(rise_time, culmination_time, set_time, aster=aster)
)
except EphemerisRangeError as error:
start = translate_to_timezone(error.start_time.utc_datetime(), timezone)
end = translate_to_timezone(error.end_time.utc_datetime(), timezone)
start = translate_to_utc_offset(error.start_time.utc_datetime(), utc_offset)
end = translate_to_utc_offset(error.end_time.utc_datetime(), utc_offset)

start = date(start.year, start.month, start.day + 1)
end = date(end.year, end.month, end.day - 1)


+ 89
- 48
kosmorrolib/events.py Переглянути файл

@@ -17,6 +17,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.

from datetime import date, timedelta
from typing import Union

from skyfield.errors import EphemerisRangeError
from skyfield.timelib import Time
@@ -34,14 +35,20 @@ from kosmorrolib.model import (
ASTERS,
EARTH,
)
from kosmorrolib.dateutil import translate_to_timezone
from kosmorrolib.dateutil import translate_to_utc_offset
from kosmorrolib.enum import EventType, ObjectIdentifier, SeasonType, LunarEclipseType
from kosmorrolib.exceptions import InvalidDateRangeError, OutOfRangeDateError
from kosmorrolib.core import get_timescale, get_skf_objects, flatten_list
from kosmorrolib.core import (
get_timescale,
get_skf_objects,
flatten_list,
deprecated,
alert_deprecation,
)


def _search_conjunctions_occultations(
start_time: Time, end_time: Time, timezone: int
start_time: Time, end_time: Time, utc_offset: Union[int, float]
) -> [Event]:
"""Function to search conjunction.

@@ -118,7 +125,9 @@ def _search_conjunctions_occultations(
Event(
EventType.OCCULTATION,
occulting_aster,
translate_to_timezone(time.utc_datetime(), timezone),
translate_to_utc_offset(
time.utc_datetime(), utc_offset
),
)
)
else:
@@ -126,7 +135,9 @@ def _search_conjunctions_occultations(
Event(
EventType.CONJUNCTION,
[aster1, aster2],
translate_to_timezone(time.utc_datetime(), timezone),
translate_to_utc_offset(
time.utc_datetime(), utc_offset
),
)
)

@@ -135,7 +146,9 @@ def _search_conjunctions_occultations(
return events


def _search_oppositions(start_time: Time, end_time: Time, timezone: int) -> [Event]:
def _search_oppositions(
start_time: Time, end_time: Time, utc_offset: Union[int, float]
) -> [Event]:
"""Function to search oppositions.

**Warning:** this is an internal function, not intended for use by end-developers.
@@ -198,7 +211,7 @@ def _search_oppositions(start_time: Time, end_time: Time, timezone: int) -> [Eve
Event(
EventType.OPPOSITION,
[aster],
translate_to_timezone(time.utc_datetime(), timezone),
translate_to_utc_offset(time.utc_datetime(), utc_offset),
)
)

@@ -206,7 +219,7 @@ def _search_oppositions(start_time: Time, end_time: Time, timezone: int) -> [Eve


def _search_maximal_elongations(
start_time: Time, end_time: Time, timezone: int
start_time: Time, end_time: Time, utc_offset: Union[int, float]
) -> [Event]:
"""Function to search oppositions.

@@ -249,7 +262,7 @@ def _search_maximal_elongations(
Event(
EventType.MAXIMAL_ELONGATION,
[planet],
translate_to_timezone(time.utc_datetime(), timezone),
translate_to_utc_offset(time.utc_datetime(), utc_offset),
details={"deg": float(elongation)},
)
)
@@ -283,7 +296,7 @@ def _search_apogee(to_aster: Object, from_aster: Object = EARTH) -> callable:
[<Event type=APOGEE objects=[<Object type=PLANET name=EARTH />] start=2021-07-05 22:35:42.148792+00:00 end=None details={'distance_km': 152100521.91712126} />]
"""

def f(start_time: Time, end_time: Time, timezone: int) -> [Event]:
def f(start_time: Time, end_time: Time, utc_offset: Union[int, float]) -> [Event]:
events = []

times, distances = find_maxima(
@@ -298,7 +311,7 @@ def _search_apogee(to_aster: Object, from_aster: Object = EARTH) -> callable:
Event(
EventType.APOGEE,
[to_aster],
translate_to_timezone(time.utc_datetime(), timezone),
translate_to_utc_offset(time.utc_datetime(), utc_offset),
details={"distance_km": float(distances[i])},
)
)
@@ -322,7 +335,7 @@ def _search_perigee(aster: Object, from_aster: Object = EARTH) -> callable:
[<Event type=PERIGEE objects=[<Object type=PLANET name=EARTH />] start=2021-01-02 13:59:00.495905+00:00 end=None details={'distance_km': 147093166.1686309} />]
"""

def f(start_time: Time, end_time: Time, timezone: int) -> [Event]:
def f(start_time: Time, end_time: Time, utc_offset: Union[int, float]) -> [Event]:
events = []

times, distances = find_minima(
@@ -337,7 +350,7 @@ def _search_perigee(aster: Object, from_aster: Object = EARTH) -> callable:
Event(
EventType.PERIGEE,
[aster],
translate_to_timezone(time.utc_datetime(), timezone),
translate_to_utc_offset(time.utc_datetime(), utc_offset),
details={"distance_km": float(distances[i])},
)
)
@@ -348,7 +361,7 @@ def _search_perigee(aster: Object, from_aster: Object = EARTH) -> callable:


def _search_earth_season_change(
start_time: Time, end_time: Time, timezone: int
start_time: Time, end_time: Time, utc_offset: Union[int, float]
) -> [Event]:
"""Function to find earth season change event.

@@ -379,14 +392,16 @@ def _search_earth_season_change(
Event(
EventType.SEASON_CHANGE,
[],
translate_to_timezone(event_time.utc_datetime()[0], timezone),
translate_to_utc_offset(event_time.utc_datetime()[0], utc_offset),
details={"season": SeasonType(event_id[0])},
)
)
return events


def _search_lunar_eclipse(start_time: Time, end_time: Time, timezone: int) -> [Event]:
def _search_lunar_eclipse(
start_time: Time, end_time: Time, utc_offset: Union[int, float]
) -> [Event]:
"""Function to detect lunar eclipses.

**Warning:** this is an internal function, not intended for use by end-developers.
@@ -444,13 +459,15 @@ def _search_lunar_eclipse(start_time: Time, end_time: Time, timezone: int) -> [E
Event(
EventType.LUNAR_ECLIPSE,
[moon],
start_time=translate_to_timezone(
eclipse_start[0].utc_datetime(), timezone
start_time=translate_to_utc_offset(
eclipse_start[0].utc_datetime(), utc_offset
),
end_time=translate_to_utc_offset(
eclipse_end[0].utc_datetime(), utc_offset
),
end_time=translate_to_timezone(eclipse_end[0].utc_datetime(), timezone),
details={
"type": LunarEclipseType(yi),
"maximum": translate_to_timezone(ti.utc_datetime(), timezone),
"maximum": translate_to_utc_offset(ti.utc_datetime(), utc_offset),
},
)
)
@@ -458,24 +475,31 @@ def _search_lunar_eclipse(start_time: Time, end_time: Time, timezone: int) -> [E
return events


def get_events(for_date: date = date.today(), timezone: int = 0) -> [Event]:
"""Calculate and return a list of events for the given date, adjusted to the given timezone if any.
def get_events(
for_date: date = date.today(), utc_offset: Union[int, float] = 0, **argv
) -> [Event]:
"""Calculate and return a list of events for the given date, adjusted to the given UTC offset if any.

Find events that happen on April 4th, 2020 (show hours in UTC):

>>> get_events(date(2020, 4, 4))
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] 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):
Find events that happen on April 4th, 2020 (displayed in UTC+2):

>>> get_events(date(2020, 4, 4), 2)
>>> get_events(date(2020, 4, 4), utc_offset=2)
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] 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):
Find events that happen on April 3rd, 2020 (displayed in UTC-2):

>>> get_events(date(2020, 4, 3), -2)
>>> get_events(date(2020, 4, 3), utc_offset=-2)
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-03 23:14:39.063388-02:00 end=None details=None />]

Note that the `utc_offset` argument was named `timezone` before version 1.1. The old name still works, but will be dropped in the future.

>>> get_events(date(2020, 4, 4), timezone=2)
[<Event type=CONJUNCTION objects=[<Object type=PLANET name=MERCURY />, <Object type=PLANET name=NEPTUNE />] start=2020-04-04 03:14:39.063267+02:00 end=None details=None />]

If there is no events for the given date, then an empty list is returned:

>>> get_events(date(2021, 4, 20))
@@ -490,15 +514,21 @@ def get_events(for_date: date = date.today(), timezone: int = 0) -> [Event]:
kosmorrolib.exceptions.OutOfRangeDateError: The date must be between 1899-07-28 and 2053-10-08

:param for_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.
:param utc_offset: the UTC offset to adapt the results to. If not given, defaults to 0.
:return: a list of events found for the given date.
"""

if argv.get("timezone") is not None:
alert_deprecation(
"'timezone' argument of the get_events() function is deprecated. Use utc_offset instead."
)
utc_offset = argv.get("timezone")

start_time = get_timescale().utc(
for_date.year, for_date.month, for_date.day, -timezone
for_date.year, for_date.month, for_date.day, -utc_offset
)
end_time = get_timescale().utc(
for_date.year, for_date.month, for_date.day + 1, -timezone
for_date.year, for_date.month, for_date.day + 1, -utc_offset
)

try:
@@ -515,12 +545,14 @@ def get_events(for_date: date = date.today(), timezone: int = 0) -> [Event]:
_search_earth_season_change,
_search_lunar_eclipse,
]:
found_events.append(fun(start_time, end_time, timezone))
found_events.append(fun(start_time, end_time, utc_offset))

return sorted(flatten_list(found_events), key=lambda event: event.start_time)
except EphemerisRangeError as error:
start_date = translate_to_timezone(error.start_time.utc_datetime(), timezone)
end_date = translate_to_timezone(error.end_time.utc_datetime(), timezone)
start_date = translate_to_utc_offset(
error.start_time.utc_datetime(), utc_offset
)
end_date = translate_to_utc_offset(error.end_time.utc_datetime(), utc_offset)

start_date = date(start_date.year, start_date.month, start_date.day)
end_date = date(end_date.year, end_date.month, end_date.day)
@@ -529,9 +561,12 @@ def get_events(for_date: date = date.today(), timezone: int = 0) -> [Event]:


def search_events(
event_types: [EventType], end: date, start: date = date.today(), timezone: int = 0
event_types: [EventType],
end: date,
start: date = date.today(),
utc_offset: Union[int, float] = 0,
) -> [Event]:
"""Search between `start` and `end` dates, and return a list of matching events for the given time range, adjusted to a given timezone.
"""Search between `start` and `end` dates, and return a list of matching events for the given time range, adjusted to a given UTC offset.

Find all events between January 27th, 2020 and January 29th, 2020:

@@ -549,7 +584,7 @@ def search_events(

Find Apogee events between January 27th, 2020 and January 29th, 2020 (show times in UTC-6):

>>> search_events([EventType.APOGEE], end=date(2020, 1, 29), start=date(2020, 1, 27), timezone=-6)
>>> search_events([EventType.APOGEE], end=date(2020, 1, 29), start=date(2020, 1, 27), utc_offset=-6)
[<Event type=APOGEE objects=[<Object type=SATELLITE name=MOON />] start=2020-01-29 15:32:13.884314-06:00 end=None details={'distance_km': 405426.4150890029} />]

If no events occurred in the given time range, an empty list is returned.
@@ -585,17 +620,21 @@ def search_events(
moon = ASTERS[1]
sun = ASTERS[0]

def search_all_apogee_events(start: date, end: date, timezone: int = 0) -> [Event]:
moon_apogee_events = _search_apogee(moon)(start, end, timezone)
def _search_all_apogee_events(
start: date, end: date, utc_offset: Union[int, float] = 0
) -> [Event]:
moon_apogee_events = _search_apogee(moon)(start, end, utc_offset)
earth_apogee_events = _search_apogee(EARTH, from_aster=sun)(
start, end, timezone
start, end, utc_offset
)
return moon_apogee_events + earth_apogee_events

def search_all_perigee_events(start: date, end: date, timezone: int = 0) -> [Event]:
moon_perigee_events = _search_perigee(moon)(start, end, timezone)
def _search_all_perigee_events(
start: date, end: date, utc_offset: Union[int, float] = 0
) -> [Event]:
moon_perigee_events = _search_perigee(moon)(start, end, utc_offset)
earth_perigee_events = _search_perigee(EARTH, from_aster=sun)(
start, end, timezone
start, end, utc_offset
)
return moon_perigee_events + earth_perigee_events

@@ -604,8 +643,8 @@ def search_events(
EventType.CONJUNCTION: _search_conjunctions_occultations,
EventType.OCCULTATION: _search_conjunctions_occultations,
EventType.MAXIMAL_ELONGATION: _search_maximal_elongations,
EventType.APOGEE: search_all_apogee_events,
EventType.PERIGEE: search_all_perigee_events,
EventType.APOGEE: _search_all_apogee_events,
EventType.PERIGEE: _search_all_perigee_events,
EventType.SEASON_CHANGE: _search_earth_season_change,
EventType.LUNAR_ECLIPSE: _search_lunar_eclipse,
}
@@ -613,22 +652,24 @@ def search_events(
if start > end:
raise InvalidDateRangeError(start, end)

start_time = get_timescale().utc(start.year, start.month, start.day, -timezone)
end_time = get_timescale().utc(end.year, end.month, end.day + 1, -timezone)
start_time = get_timescale().utc(start.year, start.month, start.day, -utc_offset)
end_time = get_timescale().utc(end.year, end.month, end.day + 1, -utc_offset)

try:
found_events = []
for event_type in event_types:
fun = search_funcs[event_type]
events = fun(start_time, end_time, timezone)
events = fun(start_time, end_time, utc_offset)
for event in events:
if event not in found_events:
found_events.append(event)

return sorted(flatten_list(found_events), key=lambda event: event.start_time)
except EphemerisRangeError as error:
start_date = translate_to_timezone(error.start_time.utc_datetime(), timezone)
end_date = translate_to_timezone(error.end_time.utc_datetime(), timezone)
start_date = translate_to_utc_offset(
error.start_time.utc_datetime(), utc_offset
)
end_date = translate_to_utc_offset(error.end_time.utc_datetime(), utc_offset)

start_date = date(start_date.year, start_date.month, start_date.day)
end_date = date(end_date.year, end_date.month, end_date.day)


Завантаження…
Відмінити
Зберегти