Skip to content

Commit b469817

Browse files
committed
fix deserializers for date and boolean strings
1 parent 9a97157 commit b469817

File tree

4 files changed

+47
-17
lines changed

4 files changed

+47
-17
lines changed

models/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def normalize_model_field_value(model, field, value):
2020
if internal_type == 'BooleanField':
2121
normalized_value = strtobool_safe(value)
2222
elif internal_type in ('DateField', 'DateTimeField'):
23-
normalized_value = parse_datetime(value)
23+
normalized_value = parse_datetime(value) if value is not None else None
2424
else:
2525
normalized_value = value
2626

requirements.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ django-grappelli==2.5.3
55
numpy==1.22.0
66
pydantic==1.7.4
77
pygeoip==0.2.6
8+
python-dateutil>=2.8.2,<3
89
redis==4.4.4
910
reportlab==3.6.13
10-
requests==2.31.0
11-
requests-oauthlib==1.0.0
12-
rollbar==0.8.2
11+
requests-oauthlib>=1.0.0
12+
requests>=2.31.0
13+
rollbar>=0.8.2
1314
stripe==1.19.0
1415
xhtml2pdf==0.0.6

utils/datetime_utils.py

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import time
44

55
# Third Party (PyPI) Imports
6+
import dateutil.parser
67
import pytz
78

89
# Django Imports
@@ -17,10 +18,14 @@
1718
from htk.constants.time import *
1819

1920

21+
# isort: off
22+
23+
2024
def 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

3641
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`"""
3943
tz = pytz.timezone(timezone_name)
4044
dt = tz.localize(naive_dt)
4145
return dt
4246

4347

4448
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
4658

4759

4860
def datetime_to_unix_time(dt):
@@ -75,9 +87,11 @@ def unix_time_to_datetime(timestamp, tzinfo=pytz.utc):
7587

7688
def 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+
108126
def 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+
116137
def 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

utils/general.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def strtobool_safe(value):
8181
try:
8282
from distutils.util import strtobool
8383

84-
result = bool(strtobool(value))
84+
result = bool(strtobool(str(value)))
8585
except:
8686
result = False
8787
return result

0 commit comments

Comments
 (0)