33import time
44
55# Third Party (PyPI) Imports
6+ import dateutil .parser
67import pytz
78
89# Django Imports
1718from htk .constants .time import *
1819
1920
21+ # isort: off
22+
23+
2024def utcnow ():
2125 now = datetime .datetime .utcnow ().replace (tzinfo = pytz .utc )
2226 if settings .TEST :
2327 from htk .test_scaffold .models import TestScaffold
28+
2429 fake_time = TestScaffold .get_fake_timestamp ()
2530 if fake_time :
2631 now = fake_time
@@ -34,15 +39,22 @@ def tznow(timezone_name='America/Los_Angeles'):
3439
3540
3641def localized_datetime (naive_dt , timezone_name = 'America/Los_Angeles' ):
37- """Attaches a timezone to a `naive_dt`
38- """
42+ """Attaches a timezone to a `naive_dt`"""
3943 tz = pytz .timezone (timezone_name )
4044 dt = tz .localize (naive_dt )
4145 return dt
4246
4347
4448def parse_datetime (dt_str ):
45- return django_parse_datetime (dt_str )
49+ """Parses a datetime-like string into a DateTime object
50+
51+ Utilizes `dateutil.parser.parse` from `python-dateutil` package,
52+ and Django's `parse_datetime` as a fallback.
53+ """
54+ dt = dateutil .parser .parse (dt_str )
55+ if dt is None :
56+ dt = django_parse_datetime (dt_str )
57+ return dt
4658
4759
4860def datetime_to_unix_time (dt ):
@@ -75,9 +87,11 @@ def unix_time_to_datetime(timestamp, tzinfo=pytz.utc):
7587
7688def iso_datetime_to_unix_time (iso ):
7789 """Converts an ISO datetime string to UNIX timestamp
90+
91+ Returns `None` if `iso` is `None`
7892 """
79- dt = parse_datetime (iso )
80- unix_time = datetime_to_unix_time (dt )
93+ dt = parse_datetime (iso ) if iso is not None else None
94+ unix_time = datetime_to_unix_time (dt ) if dt is not None else None
8195 return unix_time
8296
8397
@@ -91,38 +105,49 @@ def iso_to_gregorian(iso_year, iso_week, iso_day):
91105 fourth_jan = datetime .date (iso_year , 1 , 4 )
92106 _ , fourth_jan_week , fourth_jan_day = fourth_jan .isocalendar ()
93107 delta = datetime .timedelta (
94- days = iso_day - fourth_jan_day ,
95- weeks = iso_week - fourth_jan_week
108+ days = iso_day - fourth_jan_day , weeks = iso_week - fourth_jan_week
96109 )
97110 gregorian = fourth_jan + delta
98111 return gregorian
99112
100113
101- def is_within_hour_bounds_for_timezone (start_hour , end_hour , timezone_name = 'America/Los_Angeles' ):
114+ def is_within_hour_bounds_for_timezone (
115+ start_hour , end_hour , timezone_name = 'America/Los_Angeles'
116+ ):
102117 """Determine if the local time for given `timezone_name` is currently within `start_hour` and `end_hour` bounds
118+
119+ This function is used to check whether a daemon or long-running job should execute when it wakes from sleep.
103120 """
104121 local_datetime = tznow (timezone_name )
105122 is_within_hour_bounds = start_hour <= local_datetime .hour < end_hour
106123 return is_within_hour_bounds
107124
125+
108126def is_business_hours_for_timezone (timezone_name = 'America/Los_Angeles' ):
109127 """Determine if the local time for given `timezone_name` is currently during business hours
110128
111129 Business hours defined as BUSINESS_HOURS_START to BUSINESS_HOURS_END (approx: 9:00am to 5:59pm)
112130 """
113- is_business_hours = is_within_hour_bounds (BUSINESS_HOURS_START , BUSINESS_HOURS_END , timezone_name = timezone_name )
131+ is_business_hours = is_within_hour_bounds (
132+ BUSINESS_HOURS_START , BUSINESS_HOURS_END , timezone_name = timezone_name
133+ )
114134 return is_business_hours
115135
136+
116137def is_morning_hours_for_timezone (timezone_name = 'America/Los_Angeles' ):
117138 """Determine if the local time for given `timezone_name` is currently during morning hours
118139
119140 Morning hours defined as MORNING_HOURS_START to MORNING_HOURS_END (approx: 6:00am to 9:59am)
120141 """
121- is_morning_hours = is_within_hour_bounds (MORNING_HOURS_START , MORNING_HOURS_END , timezone_name = timezone_name )
142+ is_morning_hours = is_within_hour_bounds (
143+ MORNING_HOURS_START , MORNING_HOURS_END , timezone_name = timezone_name
144+ )
122145 return is_morning_hours
123146
124147
125- def get_timezones_within_current_local_time_bounds (start_hour , end_hour , isoweekdays = None ):
148+ def get_timezones_within_current_local_time_bounds (
149+ start_hour , end_hour , isoweekdays = None
150+ ):
126151 """Get a list of all timezone names whose current local time is within `start_hour` and `end_hour`
127152
128153 If `isoweekdays` specified, also checks that it falls on one of the days of the week (Monday = 1, Sunday = 7)
@@ -132,11 +157,15 @@ def get_timezones_within_current_local_time_bounds(start_hour, end_hour, isoweek
132157 all_timezones = pytz .all_timezones
133158 timezone_names = []
134159 now = utcnow ()
160+
135161 def _is_within_time_bounds (tz_name ):
136162 tz = pytz .timezone (tz_name )
137163 tz_datetime = now .astimezone (tz )
138- result = start_hour <= tz_datetime .hour < end_hour and (isoweekdays is None or now .isoweekday () in isoweekdays )
164+ result = start_hour <= tz_datetime .hour < end_hour and (
165+ isoweekdays is None or now .isoweekday () in isoweekdays
166+ )
139167 return result
168+
140169 timezone_names = filter (_is_within_time_bounds , all_timezones )
141170 return timezone_names
142171
0 commit comments