def timeShift(requestContext, seriesList, timeShift, resetEnd=True,
              alignDST=False):
    """
    Takes one metric or a wildcard seriesList, followed by a quoted string
    with the length of time (See ``from / until`` in the render\_api_ for
    examples of time formats).

    Draws the selected metrics shifted in time. If no sign is given, a minus
    sign ( - ) is implied which will shift the metric back in time. If a plus
    sign ( + ) is given, the metric will be shifted forward in time.

    Will reset the end date range automatically to the end of the base stat
    unless resetEnd is False. Example case is when you timeshift to last week
    and have the graph date range set to include a time in the future, will
    limit this timeshift to pretend ending at the current time. If resetEnd is
    False, will instead draw full range including future time.

    Because time is shifted by a fixed number of seconds, comparing a time
    period with DST to a time period without DST, and vice-versa, will result
    in an apparent misalignment. For example, 8am might be overlaid with 7am.
    To compensate for this, use the alignDST option.

    Useful for comparing a metric against itself at a past periods or
    correcting data stored at an offset.

    Example::

        &target=timeShift(Sales.widgets.largeBlue,"7d")
        &target=timeShift(Sales.widgets.largeBlue,"-7d")
        &target=timeShift(Sales.widgets.largeBlue,"+1h")

    """
    # Default to negative. parseTimeOffset defaults to +
    if timeShift[0].isdigit():
        timeShift = '-' + timeShift
    delta = parseTimeOffset(timeShift)
    myContext = requestContext.copy()
    myContext['startTime'] = requestContext['startTime'] + delta
    myContext['endTime'] = requestContext['endTime'] + delta

    if alignDST:
        reqStartDST = localDST(requestContext['startTime'])
        reqEndDST = localDST(requestContext['endTime'])
        myStartDST = localDST(myContext['startTime'])
        myEndDST = localDST(myContext['endTime'])

        dstOffset = timedelta(hours=0)
        # If the requestContext is entirely in DST, and we are entirely
        # NOT in DST
        if (
            (reqStartDST and reqEndDST) and
            (not myStartDST and not myEndDST)
        ):
            dstOffset = timedelta(hours=1)
        # Or if the requestContext is entirely NOT in DST, and we are
        # entirely in DST
        elif (
            (not reqStartDST and not reqEndDST) and
            (myStartDST and myEndDST)
        ):
            dstOffset = timedelta(hours=-1)
        # Otherwise, we don't do anything, because it would be visually
        # confusing
        myContext['startTime'] += dstOffset
        myContext['endTime'] += dstOffset

    results = []
    if not seriesList:
        return results

    # if len(seriesList) > 1, they will all have the same pathExpression,
    # which is all we care about.
    series = seriesList[0]

    for shiftedSeries in evaluateTarget(myContext, series.pathExpression):
        shiftedSeries.name = 'timeShift(%s, %s)' % (shiftedSeries.name,
                                                    timeShift)
        if resetEnd:
            shiftedSeries.end = series.end
        else:
            shiftedSeries.end = (
                shiftedSeries.end - shiftedSeries.start + series.start)
        shiftedSeries.start = series.start
        results.append(shiftedSeries)

    return results
Takes one metric or a wildcard seriesList, followed by a quoted string
    with the length of time (See ``from / until`` in the render\_api_ for
    examples of time formats).

    Draws the selected metrics shifted in time. If no sign is given, a minus
    sign ( - ) is implied which will shift the metric back in time. If a plus
    sign ( + ) is given, the metric will be shifted forward in time.

    Will reset the end date range automatically to the end of the base stat
    unless resetEnd is False. Example case is when you timeshift to last week
    and have the graph date range set to include a time in the future, will
    limit this timeshift to pretend ending at the current time. If resetEnd is
    False, will instead draw full range including future time.

    Because time is shifted by a fixed number of seconds, comparing a time
    period with DST to a time period without DST, and vice-versa, will result
    in an apparent misalignment. For example, 8am might be overlaid with 7am.
    To compensate for this, use the alignDST option.

    Useful for comparing a metric against itself at a past periods or
    correcting data stored at an offset.

    Example::

        &target=timeShift(Sales.widgets.largeBlue,"7d")
        &target=timeShift(Sales.widgets.largeBlue,"-7d")
        &target=timeShift(Sales.widgets.largeBlue,"+1h")