"""Util functions and helpers related to dates and timestamps calculations.""" import datetime from dateutil.parser import parse as parse_date from analytics.constants.date import DATE_FIELDS, DATE_FORMAT, END_DATE, START_DATE from analytics.constants.error import ( ERROR_INCORRECT_DATE_FORMAT, ERROR_REQUIRED_DATE, ERROR_START_DATE_GREATER_THAN_END_DATE, ) from analytics.constants.parameters import ALL_TIME from analytics.logic import data_availability as data_availability_logic def get_start_date_end_date(start_date, end_date, default_days, downloads=False): """Return populated start and end dates.""" if start_date == ALL_TIME and not end_date: end_date = data_availability_logic.get_max_available_date() return start_date, end_date if not (start_date and end_date): start_date, end_date = data_availability_logic.get_date_range( data_availability_logic.HIGHWATERMARK_DATE, days=default_days, downloads=downloads, ) return start_date, end_date else: return start_date, end_date def get_prior_date_intervals(date, count=2, length=7): """Get n intervals of length m ending at given date. Starts with an interval with oldest dates, ends with an interval with the latest dates. Args: date (datetime.date): End date count (int): Number of intervals to get. length (int): Number of days in interval. Returns: list: A list of dicts: (dict): Dictionary representing an interval with keys start_date (datetime.date): Start date end_date (datetime.date): End date """ intervals = [] for interval_number in range(1, count + 1): interval = { "start_date": date - datetime.timedelta(days=(length * interval_number) - 1), "end_date": date - datetime.timedelta(days=length * (interval_number - 1)), } intervals.append(interval) return intervals[::-1] def validate_dates(start_date, end_date): if not start_date: raise Exception(ERROR_REQUIRED_DATE, START_DATE) if not end_date: raise Exception(ERROR_REQUIRED_DATE, END_DATE) try: datetime.datetime.strptime(start_date, DATE_FORMAT) datetime.datetime.strptime(end_date, DATE_FORMAT) except Exception: raise Exception(ERROR_INCORRECT_DATE_FORMAT, DATE_FIELDS) if parse_date(start_date) > parse_date(end_date): raise Exception(ERROR_START_DATE_GREATER_THAN_END_DATE, START_DATE) def generate_date_range_starting_from_date(start_date, days_back=28): """Generate a list of dates starting from passed date and going back in time.""" start_date = datetime.datetime.strptime(start_date, "%Y-%m-%d").date() dates = [] for i in range(days_back): dates.append((start_date - datetime.timedelta(days=i)).strftime("%Y-%m-%d")) return dates