Пример #1
0
def parse_date(text, tzinfo=None, hint='date'):
    tzinfo = tzinfo or localtz
    dt = None
    text = text.strip()
    # normalize ISO time
    match = _ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds = [x or '00' for x in g[3:6]]
            z, tzsign, tzhours, tzminutes = g[6:10]
            if z:
                tz = timedelta(hours=int(tzhours or '0'),
                               minutes=int(tzminutes or '0')).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = FixedOffset(tzsign == '-' and -tz or tz,
                                         '%s%s:%s' %
                                         (tzsign, tzhours, tzminutes))
            tm = time.strptime('%s ' * 6 % (years, months, days,
                                            hours, minutes, seconds),
                               '%Y %m %d %H %M %S ')
            dt = tzinfo.localize(datetime(*tm[0:6]))
        except ValueError:
            pass
    if dt is None:
        for format in ['%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c',
                       '%b %d, %Y']:
            try:
                tm = time.strptime(text, format)
                dt = tzinfo.localize(datetime(*tm[0:6]))
                break
            except ValueError:
                continue
    if dt is None:
        dt = _parse_relative_time(text, tzinfo)
    if dt is None:
        hint = {'datetime': get_datetime_format_hint,
                'date': get_date_format_hint}.get(hint, lambda: hint)()
        raise TracError(_('"%(date)s" is an invalid date, or the date format '
                          'is not known. Try "%(hint)s" instead.', 
                          date=text, hint=hint), _('Invalid Date'))
    # Make sure we can convert it to a timestamp and back - fromtimestamp()
    # may raise ValueError if larger than platform C localtime() or gmtime()
    try:
        to_datetime(to_timestamp(dt), tzinfo)
    except ValueError:
        raise TracError(_('The date "%(date)s" is outside valid range. '
                          'Try a date closer to present time.', date=text),
                          _('Invalid Date'))
    return dt
Пример #2
0
def _parse_date_iso8601(text, tzinfo):
    match = _ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds = [x or '00' for x in g[3:6]]
            z, tzsign, tzhours, tzminutes = g[6:10]
            if z:
                tz = timedelta(hours=int(tzhours or '0'),
                               minutes=int(tzminutes or '0')).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = FixedOffset(
                        -tz if tzsign == '-' else tz,
                        '%s%s:%s' % (tzsign, tzhours, tzminutes))
            tm = time.strptime(
                '%s ' * 6 % (years, months, days, hours, minutes, seconds),
                '%Y %m %d %H %M %S ')
            t = tzinfo.localize(datetime(*tm[0:6]))
            return tzinfo.normalize(t)
        except ValueError:
            pass

    return None
Пример #3
0
def _parse_relative_time(text, tzinfo):
    now = tzinfo.localize(datetime.now())
    if text == 'now':
        return now
    if text == 'today':
        return now.replace(microsecond=0, second=0, minute=0, hour=0)
    if text == 'yesterday':
        return now.replace(microsecond=0, second=0, minute=0, hour=0) \
               - timedelta(days=1)
    match = _REL_TIME_RE.match(text)
    if match:
        (value, interval) = match.groups()
        return now - _time_intervals[interval](float(value))
    match = _TIME_START_RE.match(text)
    if match:
        (which, start) = match.groups()
        dt = _time_starts[start](now)
        if which == 'last':
            if start == 'month':
                if dt.month > 1:
                    dt = dt.replace(month=dt.month - 1)
                else:
                    dt = dt.replace(year=dt.year - 1, month=12)
            else:
                dt -= _time_intervals[start](1)
        return dt
    return None
Пример #4
0
    def from_ical(ical, timezone=None):
        """ Parses the data format from ical text format.

        """
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                pass

        try:
            timetuple = map(
                int,
                ((
                    ical[:4],  # year
                    ical[4:6],  # month
                    ical[6:8],  # day
                    ical[9:11],  # hour
                    ical[11:13],  # minute
                    ical[13:15],  # second
                )))
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return datetime(tzinfo=pytz.utc, *timetuple)
            else:
                raise ValueError, ical
        except:
            raise ValueError, 'Wrong datetime format: %s' % ical
Пример #5
0
    def from_ical(ical, timezone=None):
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                pass

        try:
            timetuple = (
                int(ical[:4]),  # year
                int(ical[4:6]),  # month
                int(ical[6:8]),  # day
                int(ical[9:11]),  # hour
                int(ical[11:13]),  # minute
                int(ical[13:15]),  # second
            )
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return datetime(tzinfo=pytz.utc, *timetuple)
            else:
                raise ValueError(ical)
        except:
            raise ValueError('Wrong datetime format: %s' % ical)
Пример #6
0
    def from_ical(ical, timezone=None):
        """ Parses the data format from ical text format.

        """
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                pass

        try:
            timetuple = map(int, ((
                ical[:4],       # year
                ical[4:6],      # month
                ical[6:8],      # day
                ical[9:11],     # hour
                ical[11:13],    # minute
                ical[13:15],    # second
                )))
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return datetime(tzinfo=pytz.utc, *timetuple)
            else:
                raise ValueError, ical
        except:
            raise ValueError, 'Wrong datetime format: %s' % ical
Пример #7
0
def _parse_date_iso8601(text, tzinfo):
    match = _ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds, useconds = [x or '00' for x in g[3:7]]
            useconds = (useconds + '000000')[:6]
            z = g[7]
            if z:
                tzsign = g[8]
                tzhours = int(g[9] or 0)
                tzminutes = int(g[10] or 0)
                if not (0 <= tzhours < 24 and 0 <= tzminutes < 60):
                    return None
                tz = tzhours * 60 + tzminutes
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = FixedOffset(
                        -tz if tzsign == '-' else tz,
                        '%s%02d:%02d' % (tzsign, tzhours, tzminutes))
            tm = [
                int(x) for x in (years, months, days, hours, minutes, seconds,
                                 useconds)
            ]
            t = tzinfo.localize(datetime(*tm))
            return tzinfo.normalize(t)
        except (ValueError, OverflowError):
            pass

    return None
Пример #8
0
def _parse_relative_time(text, tzinfo):
    now = tzinfo.localize(datetime.now())
    if text == 'now':
        return now
    if text == 'today':
        return now.replace(microsecond=0, second=0, minute=0, hour=0)
    if text == 'yesterday':
        return now.replace(microsecond=0, second=0, minute=0, hour=0) \
               - timedelta(days=1)
    match = _REL_TIME_RE.match(text)
    if match:
        (value, interval) = match.groups()
        return now - _time_intervals[interval](float(value))
    match = _TIME_START_RE.match(text)
    if match:
        (which, start) = match.groups()
        dt = _time_starts[start](now)
        if which == 'last':
            if start == 'month':
                if dt.month > 1:
                    dt = dt.replace(month=dt.month - 1)
                else:
                    dt = dt.replace(year=dt.year - 1, month=12)
            else:
                dt -= _time_intervals[start](1)
        return dt
    return None
Пример #9
0
def parse(time_str, tz='America/New_York', now=None):
    """
    Convert a string that could be either number of seconds since
    epoch (unixtime) or a formatted string to a datetime.

    @param time_str: str|datetime|None
    @param now: datetime|None, uses current time by default
    @return datetime
    """
    if not time_str or isinstance(time_str, datetime):
        return time_str

    dt = _as_datetime(time_str) or _as_timedelta(time_str, now)

    if dt is None:
        raise ValueError("unable to convert '%s' to datetime" % time_str)

    if tz:
        try:
            tzinfo = convert_tzinfo(tz)
            if dt.tzinfo:
                localize(dt, tz=tz, normalize=True)
            else:
                dt = tzinfo.localize(dt)
        except pytz.exceptions.UnknownTimeZoneError:
            raise ValueError("unknown timezone '%s'" % tz)

        dt = pytz.timezone('America/New_York').normalize(dt)

    return dt
Пример #10
0
    def from_ical(ical, timezone=None):
        tzinfo = None
        if timezone:
            try:
                tzinfo = pytz.timezone(timezone)
            except pytz.UnknownTimeZoneError:
                tzinfo = _timezone_cache.get(timezone, None)

        try:
            timetuple = (
                int(ical[:4]),  # year
                int(ical[4:6]),  # month
                int(ical[6:8]),  # day
                int(ical[9:11]),  # hour
                int(ical[11:13]),  # minute
                int(ical[13:15]),  # second
            )
            if tzinfo:
                return tzinfo.localize(datetime(*timetuple))
            elif not ical[15:]:
                return datetime(*timetuple)
            elif ical[15:16] == 'Z':
                return pytz.utc.localize(datetime(*timetuple))
            else:
                raise ValueError(ical)
        except:
            raise ValueError('Wrong datetime format: %s' % ical)
Пример #11
0
def _parse_date_iso8601(text, tzinfo):
    match = _ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds = [x or '00' for x in g[3:6]]
            z, tzsign, tzhours, tzminutes = g[6:10]
            if z:
                tz = timedelta(hours=int(tzhours or '0'),
                               minutes=int(tzminutes or '0')).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = FixedOffset(-tz if tzsign == '-' else tz,
                                         '%s%s:%s' %
                                         (tzsign, tzhours, tzminutes))
            tm = time.strptime('%s ' * 6 % (years, months, days,
                                            hours, minutes, seconds),
                               '%Y %m %d %H %M %S ')
            t = tzinfo.localize(datetime(*tm[0:6]))
            return tzinfo.normalize(t)
        except ValueError:
            pass

    return None
Пример #12
0
def _parse_date_iso8601(text, tzinfo):
    match = _ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds, useconds = [x or '00' for x in g[3:7]]
            useconds = (useconds + '000000')[:6]
            z, tzsign, tzhours, tzminutes = g[7:11]
            if z:
                tz = timedelta(hours=int(tzhours or '0'),
                               minutes=int(tzminutes or '0')).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = FixedOffset(-tz if tzsign == '-' else tz,
                                         '%s%s:%s' %
                                         (tzsign, tzhours, tzminutes))
            tm = [int(x) for x in (years, months, days,
                                   hours, minutes, seconds, useconds)]
            t = tzinfo.localize(datetime(*tm))
            return tzinfo.normalize(t)
        except ValueError:
            pass

    return None
Пример #13
0
def _parse_date_iso8601(text, tzinfo):
    match = _ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds, useconds = [x or '00' for x in g[3:7]]
            useconds = (useconds + '000000')[:6]
            z, tzsign, tzhours, tzminutes = g[7:11]
            if z:
                tz = timedelta(hours=int(tzhours or '0'),
                               minutes=int(tzminutes or '0')).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = FixedOffset(-tz if tzsign == '-' else tz,
                                         '%s%s:%s' %
                                         (tzsign, tzhours, tzminutes))
            tm = [int(x) for x in (years, months, days,
                                   hours, minutes, seconds, useconds)]
            t = tzinfo.localize(datetime(*tm))
            return tzinfo.normalize(t)
        except ValueError:
            pass

    return None
Пример #14
0
def parse(time_str, tz='America/New_York', now=None):
    """
    Convert a string that could be either number of seconds since
    epoch (unixtime) or a formatted string to a datetime.

    @param time_str: str|datetime|None
    @param now: datetime|None, uses current time by default
    @return datetime
    """
    if not time_str or isinstance(time_str, datetime):
        return time_str

    dt = _as_datetime(time_str) or _as_timedelta(time_str, now)

    if dt is None:
        raise ValueError("unable to convert '%s' to datetime" % time_str)

    if tz:
        try:
            tzinfo = convert_tzinfo(tz)
            if dt.tzinfo:
                localize(dt, tz=tz, normalize=True)
            else:
                dt = tzinfo.localize(dt)
        except pytz.exceptions.UnknownTimeZoneError:
            raise ValueError("unknown timezone '%s'" % tz)

        dt = pytz.timezone('America/New_York').normalize(dt)

    return dt
Пример #15
0
def _parse_relative_time(text, tzinfo, now=None):
    if now is None:  # now argument for unit tests
        now = datetime_now(tzinfo)
    if text == 'now':
        return now

    dt = None
    if text == 'today':
        dt = _time_starts['day'](now)
    elif text == 'yesterday':
        dt = _time_starts['day'](now) - timedelta(days=1)
    elif text == 'tomorrow':
        dt = _time_starts['day'](now) + timedelta(days=1)
    if dt is None:
        match = _REL_FUTURE_RE.match(text)
        if match:
            (value, interval) = match.groups()
            dt = now + _time_intervals[interval](float(value))
    if dt is None:
        match = _REL_PAST_RE.match(text)
        if match:
            (value, interval) = match.groups()
            dt = now - _time_intervals[interval](float(value))
    if dt is None:
        match = _TIME_START_RE.match(text)
        if match:
            (which, start) = match.groups()
            dt = _time_starts[start](now)
            if which == 'last':
                if start == 'month':
                    if dt.month > 1:
                        dt = dt.replace(month=dt.month - 1)
                    else:
                        dt = dt.replace(year=dt.year - 1, month=12)
                elif start == 'year':
                    dt = dt.replace(year=dt.year - 1)
                else:
                    dt -= _time_intervals[start](1)
            elif which == 'next':
                if start == 'month':
                    if dt.month < 12:
                        dt = dt.replace(month=dt.month + 1)
                    else:
                        dt = dt.replace(year=dt.year + 1, month=1)
                elif start == 'year':
                    dt = dt.replace(year=dt.year + 1)
                else:
                    dt += _time_intervals[start](1)

    if dt is None:
        return None
    if not dt.tzinfo:
        dt = tzinfo.localize(dt)
    return tzinfo.normalize(dt)
Пример #16
0
def _parse_relative_time(text, tzinfo, now=None):
    if now is None:     # now argument for unit tests
        now = datetime.now(tzinfo)
    if text == 'now':
        return now

    dt = None
    if text == 'today':
        dt = _time_starts['day'](now)
    elif text == 'yesterday':
        dt = _time_starts['day'](now) - timedelta(days=1)
    elif text == 'tomorrow':
        dt = _time_starts['day'](now) + timedelta(days=1)
    if dt is None:
        match = _REL_FUTURE_RE.match(text)
        if match:
            (value, interval) = match.groups()
            dt = now + _time_intervals[interval](float(value))
    if dt is None:
        match = _REL_PAST_RE.match(text)
        if match:
            (value, interval) = match.groups()
            dt = now - _time_intervals[interval](float(value))
    if dt is None:
        match = _TIME_START_RE.match(text)
        if match:
            (which, start) = match.groups()
            dt = _time_starts[start](now)
            if which == 'last':
                if start == 'month':
                    if dt.month > 1:
                        dt = dt.replace(month=dt.month - 1)
                    else:
                        dt = dt.replace(year=dt.year - 1, month=12)
                elif start == 'year':
                    dt = dt.replace(year=dt.year - 1)
                else:
                    dt -= _time_intervals[start](1)
            elif which == 'next':
                if start == 'month':
                    if dt.month < 12:
                        dt = dt.replace(month=dt.month + 1)
                    else:
                        dt = dt.replace(year=dt.year + 1, month=1)
                elif start == 'year':
                    dt = dt.replace(year=dt.year + 1)
                else:
                    dt += _time_intervals[start](1)

    if dt is None:
        return None
    if not dt.tzinfo:
        dt = tzinfo.localize(dt)
    return tzinfo.normalize(dt)
Пример #17
0
def _i18n_parse_date_0(text, order, regexp, period_names, month_names, tzinfo):
    matches = regexp.findall(text)
    if not matches:
        return None

    # remove am/pm markers on ahead
    period = None
    for idx, match in enumerate(matches):
        period = period_names.get(match)
        if period is not None:
            del matches[idx]
            break

    # for date+time, use 0 seconds if seconds are missing
    if 's' in order and len(matches) == 5:
        matches.insert(order['s'], 0)

    values = {}
    for key, idx in order.iteritems():
        if idx < len(matches):
            value = matches[idx]
            if key == 'y':
                if len(value) == 2 and value.isdigit():
                    value = '20' + value
            values[key] = value

    if 'y' not in values or 'M' not in values or 'd' not in values:
        raise ValueError

    for key in ('y', 'M', 'd'):
        value = values[key]
        value = month_names.get(value)
        if value is not None:
            if key == 'M':
                values[key] = value
            else:
                values[key], values['M'] = values['M'], value
            break

    values = {key: int(value) for key, value in values.iteritems()}
    values.setdefault('h', 0)
    values.setdefault('m', 0)
    values.setdefault('s', 0)

    if period and values['h'] <= 12:
        if period == 'am':
            values['h'] %= 12
        elif period == 'pm':
            values['h'] = values['h'] % 12 + 12

    t = tzinfo.localize(datetime(*(values[k] for k in 'yMdhms')))
    return tzinfo.normalize(t)
Пример #18
0
def _i18n_parse_date_0(text, order, regexp, period_names, month_names, tzinfo):
    matches = regexp.findall(text)
    if not matches:
        return None

    period = None
    for idx, match in enumerate(matches):
        period = period_names.get(match)
        if period is not None:
            del matches[idx]
            break

    if len(matches) == 5:
        matches.insert(order['s'], 0)

    values = {}
    for key, idx in order.iteritems():
        if idx < len(matches):
            value = matches[idx]
            if key == 'y':
                if len(value) == 2 and value.isdigit():
                    value = '20' + value
            values[key] = value

    if 'y' not in values or 'M' not in values or 'd' not in values:
        raise ValueError

    for key in ('y', 'M', 'd'):
        value = values[key]
        value = month_names.get(value)
        if value is not None:
            if key == 'M':
                values[key] = value
            else:
                values[key], values['M'] = values['M'], value
            break

    values = dict((key, int(value)) for key, value in values.iteritems())
    values.setdefault('h', 0)
    values.setdefault('m', 0)
    values.setdefault('s', 0)

    if period and values['h'] <= 12:
        if period == 'am':
            values['h'] %= 12
        elif period == 'pm':
            values['h'] = values['h'] % 12 + 12

    t = tzinfo.localize(datetime(*(values[k] for k in 'yMdhms')))
    if hasattr(tzinfo, 'normalize'):  # pytz
        t = tzinfo.normalize(t)
    return t
Пример #19
0
def _i18n_parse_date_0(text, order, regexp, period_names, month_names, tzinfo):
    matches = regexp.findall(text)
    if not matches:
        return None

    # remove am/pm markers on ahead
    period = None
    for idx, match in enumerate(matches):
        period = period_names.get(match)
        if period is not None:
            del matches[idx]
            break

    # for date+time, use 0 seconds if seconds are missing
    if 's' in order and len(matches) == 5:
        matches.insert(order['s'], 0)

    values = {}
    for key, idx in order.iteritems():
        if idx < len(matches):
            value = matches[idx]
            if key == 'y':
                if len(value) == 2 and value.isdigit():
                    value = '20' + value
            values[key] = value

    if 'y' not in values or 'M' not in values or 'd' not in values:
        raise ValueError

    for key in ('y', 'M', 'd'):
        value = values[key]
        value = month_names.get(value)
        if value is not None:
            if key == 'M':
                values[key] = value
            else:
                values[key], values['M'] = values['M'], value
            break

    values = dict((key, int(value)) for key, value in values.iteritems())
    values.setdefault('h', 0)
    values.setdefault('m', 0)
    values.setdefault('s', 0)

    if period and values['h'] <= 12:
        if period == 'am':
            values['h'] %= 12
        elif period == 'pm':
            values['h'] = values['h'] % 12 + 12

    t = tzinfo.localize(datetime(*(values[k] for k in 'yMdhms')))
    return tzinfo.normalize(t)
Пример #20
0
def _libc_parse_date(text, tzinfo):
    for format in ('%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c',
                   '%b %d, %Y'):
        try:
            tm = time.strptime(text, format)
            dt = tzinfo.localize(datetime(*tm[0:6]))
            return tzinfo.normalize(dt)
        except (ValueError, OverflowError):
            continue
    try:
        return _i18n_parse_date(text, tzinfo, None)
    except (ValueError, OverflowError):
        pass
    return
Пример #21
0
def _libc_parse_date(text, tzinfo):
    for format in ('%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c',
                   '%b %d, %Y'):
        try:
            tm = time.strptime(text, format)
            dt = tzinfo.localize(datetime(*tm[0:6]))
            return tzinfo.normalize(dt)
        except ValueError:
            continue
    try:
        return _i18n_parse_date(text, tzinfo, None)
    except ValueError:
        pass
    return
Пример #22
0
def parse_time(value, tzinfo):
    """Parse Twitter API time format.
    
    >>> parse_time("Sun Dec 14 11:29:30 +0000 2008", StaticTzInfo(0))
    datetime(2008, 12, 14, 11, 29, 30)
    >>> parse_time("Sun Dec 14 11:29:30 +0000 2008", StaticTzInfo(8))
    datetime(2008, 12, 22, 11, 29, 30)
    """
    if not value:
        return None
    day, month, date, time, timezone, year = value.lower().split()
    hour, min, sec = time.split(u":")
    utc_dt = datetime(int(year), int(MONTHS[month]), int(date), int(hour),
            int(min), int(sec))
    return tzinfo.localize(utc_dt)
Пример #23
0
    def replace_tzinfo(cls, dt: datetime, tzinfo: tzinfo, is_dst=True):
        """
        This method does not convert timezone, it simply set the timezone to specified timezone.
        :param date_time: if this datetime has tzinfo, it will be overridden
        :param tzinfo: timezone
        :rtype: datetime
        """

        # datetime.replace(tzinfo=user_tz)  => sometime this change the datetime value
        # http://stackoverflow.com/questions/27531718/datetime-timezone-conversion-using-pytz
        # use localize instead

        if dt.tzinfo is not None:
            dt = dt.replace(tzinfo=None)

        local = tzinfo.localize(dt, is_dst=is_dst)
        return tzinfo.normalize(local)
Пример #24
0
def parse_date(text, tzinfo=None, locale=None, hint='date'):
    tzinfo = tzinfo or localtz
    text = text.strip()

    dt = _parse_date_iso8601(text, tzinfo)
    if dt is None and locale != 'iso8601':
        if babel and locale:
            dt = _i18n_parse_date(text, tzinfo, locale)
        else:
            for format in [
                    '%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c',
                    '%b %d, %Y'
            ]:
                try:
                    tm = time.strptime(text, format)
                    dt = tzinfo.localize(datetime(*tm[0:6]))
                    if hasattr(tzinfo, 'normalize'):  # pytz
                        dt = tzinfo.normalize(dt)
                    break
                except ValueError:
                    continue
    if dt is None:
        dt = _parse_relative_time(text, tzinfo)
    if dt is None:
        hint = {
            'datetime': get_datetime_format_hint,
            'date': get_date_format_hint
        }.get(hint, lambda (l): hint)(locale)
        raise TracError(
            _(
                '"%(date)s" is an invalid date, or the date format '
                'is not known. Try "%(hint)s" instead.',
                date=text,
                hint=hint), _('Invalid Date'))
    # Make sure we can convert it to a timestamp and back - fromtimestamp()
    # may raise ValueError if larger than platform C localtime() or gmtime()
    try:
        to_datetime(to_timestamp(dt), tzinfo)
    except ValueError:
        raise TracError(
            _(
                'The date "%(date)s" is outside valid range. '
                'Try a date closer to present time.',
                date=text), _('Invalid Date'))
    return dt
Пример #25
0
def parse_date(text, tzinfo=None, locale=None, hint='date'):
    tzinfo = tzinfo or localtz
    text = text.strip()

    dt = _parse_date_iso8601(text, tzinfo)
    if dt is None and locale != 'iso8601':
        if babel and locale:
            dt = _i18n_parse_date(text, tzinfo, locale)
        else:
            for format in ['%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c',
                           '%b %d, %Y']:
                try:
                    tm = time.strptime(text, format)
                    dt = tzinfo.localize(datetime(*tm[0:6]))
                    dt = tzinfo.normalize(dt)
                    break
                except ValueError:
                    continue
    if dt is None:
        dt = _parse_relative_time(text, tzinfo)
    if dt is None:
        hint = {'datetime': get_datetime_format_hint,
                'date': get_date_format_hint,
                'relative': get_datetime_format_hint
               }.get(hint, lambda(l): hint)(locale)
        raise TracError(_('"%(date)s" is an invalid date, or the date format '
                          'is not known. Try "%(hint)s" instead.',
                          date=text, hint=hint), _('Invalid Date'))
    # Make sure we can convert it to a timestamp and back - fromtimestamp()
    # may raise ValueError if larger than platform C localtime() or gmtime()
    try:
        datetime.utcfromtimestamp(to_timestamp(dt))
    except ValueError:
        raise TracError(_('The date "%(date)s" is outside valid range. '
                          'Try a date closer to present time.', date=text),
                          _('Invalid Date'))
    return dt
Пример #26
0
def parse_date(text, tzinfo=None, hint='date'):
    tzinfo = tzinfo or localtz
    dt = None
    text = text.strip()
    # normalize ISO time
    match = _ISO_8601_RE.match(text)
    if match:
        try:
            g = match.groups()
            years = g[0]
            months = g[1] or '01'
            days = g[2] or '01'
            hours, minutes, seconds = [x or '00' for x in g[3:6]]
            z, tzsign, tzhours, tzminutes = g[6:10]
            if z:
                tz = timedelta(hours=int(tzhours or '0'),
                               minutes=int(tzminutes or '0')).seconds / 60
                if tz == 0:
                    tzinfo = utc
                else:
                    tzinfo = FixedOffset(
                        tzsign == '-' and -tz or tz,
                        '%s%s:%s' % (tzsign, tzhours, tzminutes))
            tm = time.strptime(
                '%s ' * 6 % (years, months, days, hours, minutes, seconds),
                '%Y %m %d %H %M %S ')
            dt = tzinfo.localize(datetime(*tm[0:6]))
        except ValueError:
            pass
    if dt is None:
        for format in [
                '%x %X', '%x, %X', '%X %x', '%X, %x', '%x', '%c', '%b %d, %Y'
        ]:
            try:
                tm = time.strptime(text, format)
                dt = tzinfo.localize(datetime(*tm[0:6]))
                break
            except ValueError:
                continue
    if dt is None:
        dt = _parse_relative_time(text, tzinfo)
    if dt is None:
        hint = {
            'datetime': get_datetime_format_hint,
            'date': get_date_format_hint
        }.get(hint, lambda: hint)()
        raise TracError(
            _(
                '"%(date)s" is an invalid date, or the date format '
                'is not known. Try "%(hint)s" instead.',
                date=text,
                hint=hint), _('Invalid Date'))
    # Make sure we can convert it to a timestamp and back - fromtimestamp()
    # may raise ValueError if larger than platform C localtime() or gmtime()
    try:
        to_datetime(to_timestamp(dt), tzinfo)
    except ValueError:
        raise TracError(
            _(
                'The date "%(date)s" is outside valid range. '
                'Try a date closer to present time.',
                date=text), _('Invalid Date'))
    return dt
Пример #27
0
def localize(dt, tzinfo):
    if hasattr(tzinfo, 'localize'):
        return tzinfo.localize(dt)

    return normalize(dt.replace(tzinfo=tzinfo))