3
3
import time
4
4
5
5
# Third Party (PyPI) Imports
6
+ import dateutil .parser
6
7
import pytz
7
8
8
9
# Django Imports
17
18
from htk .constants .time import *
18
19
19
20
21
+ # isort: off
22
+
23
+
20
24
def utcnow ():
21
25
now = datetime .datetime .utcnow ().replace (tzinfo = pytz .utc )
22
26
if settings .TEST :
23
27
from htk .test_scaffold .models import TestScaffold
28
+
24
29
fake_time = TestScaffold .get_fake_timestamp ()
25
30
if fake_time :
26
31
now = fake_time
@@ -34,15 +39,22 @@ def tznow(timezone_name='America/Los_Angeles'):
34
39
35
40
36
41
def 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`"""
39
43
tz = pytz .timezone (timezone_name )
40
44
dt = tz .localize (naive_dt )
41
45
return dt
42
46
43
47
44
48
def 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
46
58
47
59
48
60
def datetime_to_unix_time (dt ):
@@ -75,9 +87,11 @@ def unix_time_to_datetime(timestamp, tzinfo=pytz.utc):
75
87
76
88
def iso_datetime_to_unix_time (iso ):
77
89
"""Converts an ISO datetime string to UNIX timestamp
90
+
91
+ Returns `None` if `iso` is `None`
78
92
"""
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
81
95
return unix_time
82
96
83
97
@@ -91,38 +105,49 @@ def iso_to_gregorian(iso_year, iso_week, iso_day):
91
105
fourth_jan = datetime .date (iso_year , 1 , 4 )
92
106
_ , fourth_jan_week , fourth_jan_day = fourth_jan .isocalendar ()
93
107
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
96
109
)
97
110
gregorian = fourth_jan + delta
98
111
return gregorian
99
112
100
113
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
+ ):
102
117
"""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.
103
120
"""
104
121
local_datetime = tznow (timezone_name )
105
122
is_within_hour_bounds = start_hour <= local_datetime .hour < end_hour
106
123
return is_within_hour_bounds
107
124
125
+
108
126
def is_business_hours_for_timezone (timezone_name = 'America/Los_Angeles' ):
109
127
"""Determine if the local time for given `timezone_name` is currently during business hours
110
128
111
129
Business hours defined as BUSINESS_HOURS_START to BUSINESS_HOURS_END (approx: 9:00am to 5:59pm)
112
130
"""
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
+ )
114
134
return is_business_hours
115
135
136
+
116
137
def is_morning_hours_for_timezone (timezone_name = 'America/Los_Angeles' ):
117
138
"""Determine if the local time for given `timezone_name` is currently during morning hours
118
139
119
140
Morning hours defined as MORNING_HOURS_START to MORNING_HOURS_END (approx: 6:00am to 9:59am)
120
141
"""
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
+ )
122
145
return is_morning_hours
123
146
124
147
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
+ ):
126
151
"""Get a list of all timezone names whose current local time is within `start_hour` and `end_hour`
127
152
128
153
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
132
157
all_timezones = pytz .all_timezones
133
158
timezone_names = []
134
159
now = utcnow ()
160
+
135
161
def _is_within_time_bounds (tz_name ):
136
162
tz = pytz .timezone (tz_name )
137
163
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
+ )
139
167
return result
168
+
140
169
timezone_names = filter (_is_within_time_bounds , all_timezones )
141
170
return timezone_names
142
171
0 commit comments