from datetime import datetime
from typing import Tuple
import math


def quantize_time_range(
    start_time: datetime,
    stop_time: datetime
) -> Tuple[datetime, datetime]:
    """Quantize the start and end times to 5 min boundaries.

    :param start_time: Start time
    :param stop_time: Stop time
    :return: Quantized start and end times
    :raises ValueError: if ``start_time`` or ``stop_time`` is ``None``

    :Examples:
    >>> start = datetime(2020, 5, 1, 12, 0, 1)
    >>> stop = datetime(2020, 5, 1, 16, 0, 6)
    >>> qstart, qstop = quantize_time_range(start, stop)
    >>> qstart
    datetime.datetime(2020, 5, 1, 12, 0)
    >>> qstop
    datetime.datetime(2020, 5, 1, 16, 0)
    """
    if start_time is None or stop_time is None:
        raise ValueError("both start and stop times must be provided")

    # truncate to 5 min
    truncated_start_time = start_time.replace(
        minute=math.floor(start_time.minute / 5.0) * 5, second=0, microsecond=0
    )
    truncated_stop_time = stop_time.replace(
        minute=math.floor(stop_time.minute / 5.0) * 5, second=0, microsecond=0
    )
    if truncated_start_time == truncated_stop_time:
        return start_time, stop_time
    else:
        return truncated_start_time, truncated_stop_time