from zerver.lib.timestamp import ceiling_to_hour, ceiling_to_day, timestamp_to_datetime from analytics.lib.counts import CountStat from datetime import datetime, timedelta from typing import List, Optional # If min_length is None, returns end_times from ceiling(start) to ceiling(end), inclusive. # If min_length is greater than 0, pads the list to the left. # So informally, time_range(Sep 20, Sep 22, day, None) returns [Sep 20, Sep 21, Sep 22], # and time_range(Sep 20, Sep 22, day, 5) returns [Sep 18, Sep 19, Sep 20, Sep 21, Sep 22] def time_range(start, end, frequency, min_length): # type: (datetime, datetime, str, Optional[int]) -> List[datetime] if frequency == CountStat.HOUR: end = ceiling_to_hour(end) step = timedelta(hours=1) elif frequency == CountStat.DAY: end = ceiling_to_day(end) step = timedelta(days=1) else: raise ValueError("Unknown frequency: %s" % (frequency,)) times = [] if min_length is not None: start = min(start, end - (min_length-1)*step) current = end while current >= start: times.append(current) current -= step return list(reversed(times))