This requires solartime==0.1b
.
See test_daylight.py for an example.
This requires solartime==0.1b
.
See test_daylight.py for an example.
from collections import namedtuple | |
import pytz | |
from dateutil.relativedelta import relativedelta | |
from dateutil.rrule import MINUTELY, rrule | |
from first import first | |
from solartime import SolarTime | |
PlayableHours = namedtuple('PlayableHours', 'start stop') | |
class SportTime(SolarTime): | |
def hours_of_play_utc(self, date, latitude, longitude, am=None, pm=None): | |
""" | |
Calculate dawn time in the UTC timezone. | |
:param date: Date to calculate for. | |
:type date: datetime.date | |
:param latitude: Latitude - Northern latitudes should be positive | |
:type latitude: float | |
:param longitude: Longitude - Eastern longitudes should be positive | |
:type longitude: float | |
:param am: Elevation when it becomes light enough (default 18) | |
:type am: float | |
:param pm: Elevation when it becomes too dark (default 10) | |
:type pm: float | |
:rtype: :class:`PlayableHours` | |
""" | |
if am is None: | |
am = 18 | |
if pm is None: | |
pm = 10 | |
def _light_enough_to_start(t): | |
return self.solar_elevation(t, latitude, longitude) > am | |
def _too_dark_to_continue(t): | |
return self.solar_elevation(t, latitude, longitude) < pm | |
# Some time after sunrise, the sun will be high enough in the sky that | |
# we'll be able to play. | |
sunrise = self.sunrise_utc(date, latitude, longitude) | |
sunrise += relativedelta(microsecond=0, second=0, minutes=1) | |
start = first( | |
rrule(MINUTELY, dtstart=sunrise), | |
key=_light_enough_to_start, | |
) | |
# Some time before sunset, the sun will be low enough in the sky that | |
# we'll want to stop playing if we don't have artificial lighting. | |
sunset = self.sunset_utc(date, latitude, longitude) | |
sunset += relativedelta(microsecond=0, second=0) | |
stop = first( | |
rrule(MINUTELY, dtstart=sunset, interval=-1), | |
key=_too_dark_to_continue, | |
) | |
return PlayableHours(start, stop) | |
def hours_of_play(self, date, latitude, longitude, am=None, pm=None, | |
tz=pytz.utc): | |
""" | |
Calculate dawn time in the UTC timezone. | |
:param date: Date to calculate for. | |
:type date: datetime.date | |
:param latitude: Latitude - Northern latitudes should be positive | |
:type latitude: float | |
:param longitude: Longitude - Eastern longitudes should be positive | |
:type longitude: float | |
:param am: Elevation when it becomes light enough (default 18) | |
:type am: float | |
:param pm: Elevation when it becomes too dark (default 10) | |
:type pm: float | |
:param tz: Time zone to use in return value | |
:type tz: timezone or str | |
:rtype: :class:`PlayableHours` | |
""" | |
if isinstance(tz, basestring): | |
tz = pytz.timezone(tz) | |
start, stop = self.hours_of_play_utc(date, latitude, longitude, am, pm) | |
return PlayableHours(start.astimezone(tz), stop.astimezone(tz)) |
from datetime import date | |
from dateutil.rrule import DAILY, rrule | |
from daylight import SportTime | |
sun = SportTime() | |
# Youth Touch World Cup | |
for d in rrule(DAILY, dtstart=date(2018, 8, 8), count=4): | |
hours = sun.hours_of_play(d, 2.896206, 101.684743, tz='Asia/Kuala_Lumpur') | |
print u"YTWC\t%s\t%s" % hours | |
# Touch World Cup | |
for d in rrule(DAILY, dtstart=date(2019, 4, 29), count=6): | |
hours = sun.hours_of_play(d, 2.896206, 101.684743, tz='Asia/Kuala_Lumpur') | |
print u"TWC\t%s\t%s" % hours |