'Parse a string for start/end date(time) of an interval
@param timestr: the time string
@param start: the start datetime to relate relative times to'

@staticmethod
def dtparse(timestr, start=None):

    if (start is None):
        start = tp_tzsafe(datetime.datetime.utcnow())
    if (not timestr):
        return start
    match = dt_regex.DELTA.match(timestr)
    if match:
        groups = match.groups()
        intervals = {'y': 'years', 'm': 'months', 'w': 'weeks', 'd': 'days', 'h': 'hours'}
        length = intervals.get(groups[2])
        if (not length):
            raise SyntaxError(('Invalid    date/time:    %s' % timestr))
        num = int(groups[1])
        if (not num):
            return start
        if (groups[0] == '-'):
            num *= (-1)
        return (start + relativedelta(**{length: num}))
    match = dt_regex.MONTH_YEAR.match(timestr)
    if match:
        groups = match.groups()
        year = int(groups[1])
        month = int(groups[0])
        return tp_datetime(year, month, 1, 0, 0, 0)
    match = dt_regex.YEAR_MONTH.match(timestr)
    if match:
        groups = match.groups()
        month = int(groups[1])
        year = int(groups[0])
        return tp_datetime(year, month, 1, 0, 0, 0)
    match = dt_regex.YEAR.match(timestr)
    if match:
        groups = match.groups()
        year = int(groups[0])
        return tp_datetime(year, 1, 1, 0, 0, 0)
    match = dt_regex.DATE.match(timestr)
    if match:
        groups = match.groups()
        year = int(groups[0])
        month = int(groups[1])
        day = int(groups[2])
        try:
            return tp_datetime(year, month, day)
        except ValueError:
            return (tp_datetime(year, month, 1) + datetime.timedelta(days=(day - 1)))
    dt = s3_decode_iso_datetime(str(timestr))
    return s3_utc(dt)
