Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pandas==1.2.3
scipy==1.6.2
tenacity==7.0.0
newrelic
epiweeks==2.1.2
5 changes: 3 additions & 2 deletions src/server/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
from typing import List, Optional, Sequence, Tuple, Union

from flask import request
from numpy import sign

from ._exceptions import ValidationFailedException
from .utils import days_in_range
from .utils import days_in_range, weeks_in_range


def _parse_common_multi_arg(key: str) -> List[Tuple[str, Union[bool, Sequence[str]]]]:
Expand Down Expand Up @@ -116,6 +115,8 @@ def count(self) -> float:
"""
if isinstance(self.time_values, bool):
return inf if self.time_values else 0
if self.time_type == 'week':
return sum(1 if isinstance(v, int) else weeks_in_range(v) for v in self.time_values)
return sum(1 if isinstance(v, int) else days_in_range(v) for v in self.time_values)


Expand Down
2 changes: 1 addition & 1 deletion src/server/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .dates import shift_time_value, date_to_time_value, time_value_to_iso, time_value_to_date, days_in_range
from .dates import shift_time_value, date_to_time_value, time_value_to_iso, time_value_to_date, days_in_range, weeks_in_range
23 changes: 22 additions & 1 deletion src/server/utils/dates.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Tuple
from datetime import date, timedelta
from epiweeks import Week, Year


def time_value_to_date(value: int) -> date:
Expand All @@ -10,11 +11,21 @@ def time_value_to_date(value: int) -> date:
return date.max
return date(year=year, month=month, day=day)

def week_value_to_week(value: int) -> Week:
year, week = value // 100, value % 100
if year < date.min.year:
return Week(date.min.year, 1)
if year > date.max.year:
return Week(date.max.year, 1)
return Week(year=year, week=week)

def date_to_time_value(d: date) -> int:
return int(d.strftime("%Y%m%d"))


def week_to_time_value(w: Week) -> int:
return w.year * 100 + w.week

def time_value_to_iso(value: int) -> str:
return time_value_to_date(value).strftime("%Y-%m-%d")

Expand All @@ -35,4 +46,14 @@ def days_in_range(range: Tuple[int, int]) -> int:
start = time_value_to_date(range[0])
end = time_value_to_date(range[1])
delta = end - start
return delta.days + 1 # same date should lead to 1 day that will be queried
return delta.days + 1 # same date should lead to 1 day that will be queried

def weeks_in_range(week_range: Tuple[int, int]) -> int:
start = week_value_to_week(week_range[0])
end = week_value_to_week(week_range[1])
acc = end.week - start.week
# accumulate the number of weeks in the years between
for y in range(start.year, end.year):
year = Year(y)
acc += year.totalweeks()
return acc + 1 # same week should lead to 1 week that will be queried
17 changes: 16 additions & 1 deletion tests/server/utils/test_dates.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import unittest
from datetime import date
from epiweeks import Week

from delphi.epidata.server.utils.dates import time_value_to_date, date_to_time_value, shift_time_value, time_value_to_iso, days_in_range
from delphi.epidata.server.utils.dates import time_value_to_date, date_to_time_value, shift_time_value, time_value_to_iso, days_in_range, weeks_in_range, week_to_time_value, week_value_to_week


class UnitTests(unittest.TestCase):
Expand All @@ -25,3 +26,17 @@ def test_days_in_range(self):
self.assertEqual(days_in_range((20201010, 20201010)), 1)
self.assertEqual(days_in_range((20201010, 20201011)), 2)
self.assertEqual(days_in_range((20200130, 20200203)), 5)

def test_weeks_in_range(self):
self.assertEqual(weeks_in_range((202110, 202110)), 1)
self.assertEqual(weeks_in_range((202110, 202112)), 3)
self.assertEqual(weeks_in_range((202001, 202101)), 54) # 2020 has 53 weeks
self.assertEqual(weeks_in_range((202101, 202204)), 56)

def test_week_value_to_week(self):
self.assertEqual(week_value_to_week(202021), Week(2020, 21))
self.assertEqual(week_value_to_week(202101), Week(2021, 1))

def test_week_to_time_value(self):
self.assertEqual(week_to_time_value(Week(2021, 1)), 202101)
self.assertEqual(week_to_time_value(Week(2020, 42)), 202042)