Calculates the estimated delta between two time objects in human-readable
    format. Used internally by the :func:`day` and :func:`duration` functions.

    :param t1: timestamp, :class:`datetime.date` or :class:`datetime.datetime`
               object
    :param t2: timestamp, :class:`datetime.date` or :class:`datetime.datetime`
               object
    :param words: default ``True``, allow words like "yesterday", "tomorrow"
               and "just now"
    :param justnow: default ``datetime.timedelta(seconds=10)``,
               :class:`datetime.timedelta` object representing tolerance for
               considering a delta as meaning 'just now'

    >>> (x,y) = delta(_to_datetime('2012-06-13T15:24:17'), \
    _to_datetime('2013-12-11T12:34:56'))
    >>> print(x)
    77 weeks
    >>> int(y)
    -594639

def delta(t1, t2, words=True, justnow=datetime.timedelta(seconds=10)):
    '''
    Calculates the estimated delta between two time objects in human-readable
    format. Used internally by the :func:`day` and :func:`duration` functions.

    :param t1: timestamp, :class:`datetime.date` or :class:`datetime.datetime`
               object
    :param t2: timestamp, :class:`datetime.date` or :class:`datetime.datetime`
               object
    :param words: default ``True``, allow words like "yesterday", "tomorrow"
               and "just now"
    :param justnow: default ``datetime.timedelta(seconds=10)``,
               :class:`datetime.timedelta` object representing tolerance for
               considering a delta as meaning 'just now'

    >>> (x,y) = delta(_to_datetime('2012-06-13T15:24:17'), \
    _to_datetime('2013-12-11T12:34:56'))
    >>> print(x)
    77 weeks
    >>> int(y)
    -594639
    '''

    t1 = _to_datetime(t1)
    t2 = _to_datetime(t2)
    diff = t1 - t2
    date_diff = t1.date() - t2.date()

    # The datetime module includes milliseconds with float precision. Floats
    # will give unexpected results here, so we round the value here
    total = math.ceil(_total_seconds(diff))
    total_abs = abs(total)

    if total_abs < TIME_DAY:
        if abs(diff) < justnow and words:
            return (
                _('just now'),
                0,
            )

        elif total_abs < TIME_MINUTE:
            seconds = total_abs
            return (
                _multi(
                    _('%d second'),
                    _('%d seconds'),
                    seconds
                ) % (seconds,),
                0,
            )
        elif total_abs < TIME_MINUTE * 2 and words:
            return (
                _('a minute'),
                0,
            )

        elif total_abs < TIME_HOUR:
            minutes, seconds = divmod(total_abs, TIME_MINUTE)
            if total < 0:
                seconds *= -1
            return (
                _multi(
                    _('%d minute'),
                    _('%d minutes'),
                    minutes
                ) % (minutes,),
                seconds,
            )

        elif total_abs < TIME_HOUR * 2 and words:
            return (
                _('an hour'),
                0,
            )

        else:
            hours, seconds = divmod(total_abs, TIME_HOUR)
            if total < 0:
                seconds *= -1

            return (
                _multi(
                    _('%d hour'),
                    _('%d hours'),
                    hours
                ) % (hours,),
                seconds,
            )

    elif date_diff.days == 1 and words:
        return (_('tomorrow'), 0)

    elif date_diff.days == -1 and words:
        return (_('yesterday'), 0)

    elif total_abs < TIME_WEEK:
        days, seconds = divmod(total_abs, TIME_DAY)
        if total < 0:
            seconds *= -1
        return (
            _multi(
                _('%d day'),
                _('%d days'),
                days
            ) % (days,),
            seconds,
        )

    elif abs(diff.days) == TIME_WEEK and words:
        if total > 0:
            return (_('next week'), diff.seconds)
        else:
            return (_('last week'), diff.seconds)

# FIXME
#
# The biggest reliable unit we can supply to the user is a week (for now?),
# because we can not safely determine the amount of days in the covered
# month/year span.

    else:
        weeks, seconds = divmod(total_abs, TIME_WEEK)
        if total < 0:
            seconds *= -1
        return (
            _multi(
                _('%d week'),
                _('%d weeks'),
                weeks
            ) % (weeks,),
            seconds,
        )