def complete_timeframe(timeframe, config, partial=False):
    """
    Apply fallback strategy to incomplete timeframes.

    Our fallback strategy is as follows:
        * Missing start-date: Fallback to ``today``.
        * Missing start-time: Fallback to ``store.config['day_start']``.
        * Missing end-date: Fallback to ``today`` for ``day_start='00:00`,
          ``tomorrow`` otherwise.
          See ``hamster_lib.helpers.end_day_to_datetime`` for details and
          explanations.
        * Missing end-time: 1 second before ``store.config['day_start']``.

    Args:
        timeframe (TimeFrame): ``TimeFrame`` instance incorporating all
            available information available about the timespan. Any missing info
            will be completed per fallback strategy.
        config (dict): A config-dict providing settings relevant to determine
            fallback values.
        partial (bool, optional): If true, we will only complete start/end times if there
            is at least either date or time information present. Defaults to
            ``False``.

    Returns:
        tuple: ``(start, end)`` tuple. Where ``start`` and ``end`` are full
        ``datetime.datetime`` instances.

    Raises:
        TypeError: If any of the ``timeframe`` values is of inappropriate
            datetime type.
    """

    def complete_start_date(date):
        """
        Assign ``today`` if ``date=None``, else ensure its a ``datetime.date`` instance.

        Args:
            date (datetime.date): Startdate information.

        Returns:
            datetime.date: Either the original date or the default solution.

        Raises:
            TypeError: If ``date``` is neither ``None`` nor  ``datetime.date`` instance.

        Note:
            Reference behavior taken from [hamster-cli](https://github.com/projecthamster/
            hamster/blob/master/src/hamster-cli#L368).
        """

        if not date:
            date = datetime.date.today()
        else:
            if not isinstance(date, datetime.date):
                raise TypeError(_(
                    "Expected datetime.date instance, got {type} instead.".format(
                        type=type(date))
                ))
        return date

    def complete_start_time(time, day_start):
        """Assign ``day_start`` if no start-time is given."""
        if not time:
            time = day_start
        else:
            if not isinstance(time, datetime.time):
                raise TypeError(_(
                    "Expected datetime.time instance, got {type} instead.".format(
                        type=type(time))
                ))
        return time

    def complete_start(date, time, config):
        return datetime.datetime.combine(
            complete_start_date(timeframe.start_date),
            complete_start_time(timeframe.start_time, config['day_start']),
        )

    def complete_end_date(date):
        if not date:
            date = datetime.date.today()
        else:
            if not isinstance(date, datetime.date):
                raise TypeError(_(
                    "Expected datetime.date instance, got {type} instead.".format(
                        type=type(date))
                ))
        return date

    def complete_end(date, time, config):
        date = complete_end_date(date)
        if time:
            result = datetime.datetime.combine(date, time)
        else:
            result = end_day_to_datetime(date, config)
        return result

    start, end = None, None

    if any((timeframe.offset, timeframe.start_time, timeframe.start_date)) or not partial:
        if not timeframe.offset:
            start = complete_start(timeframe.start_date, timeframe.start_time, config)
        else:
            start = datetime.datetime.now() - timeframe.offset

    if any((timeframe.end_date, timeframe.end_time)) or not partial:
        end = complete_end(timeframe.end_date, timeframe.end_time, config)

    return (start, end)
def complete_timeframe ( timeframe , config , partial = False ) : def complete_start_date ( date ) : if not date : date = datetime . date . today ( ) else : if not isinstance ( date , datetime . date ) : raise TypeError ( _ ( "Expected datetime.date instance, got {type} instead." . format ( type = type ( date ) ) ) ) return date def complete_start_time ( time , day_start ) : if not time : time = day_start else : if not isinstance ( time , datetime . time ) : raise TypeError ( _ ( "Expected datetime.time instance, got {type} instead." . format ( type = type ( time ) ) ) ) return time def complete_start ( date , time , config ) : return datetime . datetime . combine ( complete_start_date ( timeframe . start_date ) , complete_start_time ( timeframe . start_time , config [ 'day_start' ] ) , ) def complete_end_date ( date ) : if not date : date = datetime . date . today ( ) else : if not isinstance ( date , datetime . date ) : raise TypeError ( _ ( "Expected datetime.date instance, got {type} instead." . format ( type = type ( date ) ) ) ) return date def complete_end ( date , time , config ) : date = complete_end_date ( date ) if time : result = datetime . datetime . combine ( date , time ) else : result = end_day_to_datetime ( date , config ) return result start , end = None , None if any ( ( timeframe . offset , timeframe . start_time , timeframe . start_date ) ) or not partial : if not timeframe . offset : start = complete_start ( timeframe . start_date , timeframe . start_time , config ) else : start = datetime . datetime . now ( ) - timeframe . offset if any ( ( timeframe . end_date , timeframe . end_time ) ) or not partial : end = complete_end ( timeframe . end_date , timeframe . end_time , config ) return ( start , end )
Apply fallback strategy to incomplete timeframes.

    Our fallback strategy is as follows:
        * Missing start-date: Fallback to ``today``.
        * Missing start-time: Fallback to ``store.config['day_start']``.
        * Missing end-date: Fallback to ``today`` for ``day_start='00:00`,
          ``tomorrow`` otherwise.
          See ``hamster_lib.helpers.end_day_to_datetime`` for details and
          explanations.
        * Missing end-time: 1 second before ``store.config['day_start']``.

    Args:
        timeframe (TimeFrame): ``TimeFrame`` instance incorporating all
            available information available about the timespan. Any missing info
            will be completed per fallback strategy.
        config (dict): A config-dict providing settings relevant to determine
            fallback values.
        partial (bool, optional): If true, we will only complete start/end times if there
            is at least either date or time information present. Defaults to
            ``False``.

    Returns:
        tuple: ``(start, end)`` tuple. Where ``start`` and ``end`` are full
        ``datetime.datetime`` instances.

    Raises:
        TypeError: If any of the ``timeframe`` values is of inappropriate
            datetime type.