Пример #1
0
def strpdate(data_string, format='%Y-%m-%d', bc=False):
    _TimeRE_cache = TimeRE()
    _regex_cache = {}
    try:
        format_regex = _TimeRE_cache.compile(format)
    # KeyError raised when a bad format is found; can be specified as
    # \\, in which case it was a stray % but with a space after it
    except KeyError as err:
        bad_directive = err.args[0]
        if bad_directive == "\\":
            bad_directive = "%"
        del err
        raise ValueError("'%s' is a bad directive in format '%s'" %
                         (bad_directive, format))
    # IndexError only occurs when the format string is "%"
    except IndexError:
        raise ValueError("stray %% in format '%s'" % format)
    _regex_cache[format] = format_regex
    found = format_regex.match(data_string)
    if not found:
        raise ValueError("time data %r does not match format %r" %
                         (data_string, format))
    if len(data_string) != found.end():
        raise ValueError("unconverted data remains: %s" %
                         data_string[found.end():])
    date = list(todaydatetuple())
    found_dict = found.groupdict()
    for group_key in found_dict.keys():
        if group_key == 'y':
            date[0] = int(found_dict['y'])
            if date[0] <= 68:
                date[0] += 2000
            else:
                date[0] += 1900
        elif group_key == 'Y':
            date[0] = int(found_dict['Y'])
        elif group_key == 'm':
            date[1] = int(found_dict['m'])
        elif group_key == 'd':
            date[2] = int(found_dict['d'])
    if not (bc and date == [1, 2, 29]):
        datetime(*date)
    return tuple(date)
Пример #2
0
    def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
        """Return a 2-tuple consisting of a time struct and an int containing
        the number of microseconds based on the input string and the
        format string."""

        for index, arg in enumerate([data_string, format]):
            if not isinstance(arg, str):
                msg = "strptime() argument {} must be str, not {}"
                raise TypeError(msg.format(index, type(arg)))

        global _TimeRE_cache, _regex_cache
        with _cache_lock:
            if _getlang() != _TimeRE_cache.locale_time.lang:
                _TimeRE_cache = TimeRE()
                _regex_cache.clear()
            if len(_regex_cache) > _CACHE_MAX_SIZE:
                _regex_cache.clear()
            locale_time = _TimeRE_cache.locale_time
            format_regex = _regex_cache.get(format)
            if not format_regex:
                try:
                    format_regex = _TimeRE_cache.compile(format)
                # KeyError raised when a bad format is found; can be specified as
                # \\, in which case it was a stray % but with a space after it
                except KeyError as err:
                    bad_directive = err.args[0]
                    if bad_directive == "\\":
                        bad_directive = "%"
                    del err
                    raise ValueError("'%s' is a bad directive in format '%s'" %
                                     (bad_directive, format))
                # IndexError only occurs when the format string is "%"
                except IndexError:
                    raise ValueError("stray %% in format '%s'" % format)
                _regex_cache[format] = format_regex
        found = format_regex.match(data_string)
        if not found:
            raise ValueError("time data %r does not match format %r" %
                             (data_string, format))
        if len(data_string) != found.end():
            raise ValueError("unconverted data remains: %s" %
                             data_string[found.end():])

        year = 1900
        month = day = 1
        hour = minute = second = fraction = 0
        tz = -1
        tzoffset = None
        # Default to -1 to signify that values not known; not critical to have,
        # though
        week_of_year = -1
        week_of_year_start = -1
        # weekday and julian defaulted to -1 so as to signal need to calculate
        # values
        weekday = julian = -1
        found_dict = found.groupdict()
        for group_key in found_dict.iterkeys():
            # Directives not explicitly handled below:
            #   c, x, X
            #      handled by making out of other directives
            #   U, W
            #      worthless without day of the week
            if group_key == 'y':
                year = int(found_dict['y'])
                # Open Group specification for strptime() states that a %y
                #value in the range of [00, 68] is in the century 2000, while
                #[69,99] is in the century 1900
                if year <= 68:
                    year += 2000
                else:
                    year += 1900
            elif group_key == 'Y':
                year = int(found_dict['Y'])
            elif group_key == 'm':
                month = int(found_dict['m'])
            elif group_key == 'B':
                month = locale_time.f_month.index(found_dict['B'].lower())
            elif group_key == 'b':
                month = locale_time.a_month.index(found_dict['b'].lower())
            elif group_key == 'd':
                day = int(found_dict['d'])
            elif group_key == 'H':
                hour = int(found_dict['H'])
            elif group_key == 'I':
                hour = int(found_dict['I'])
                ampm = found_dict.get('p', '').lower()
                # If there was no AM/PM indicator, we'll treat this like AM
                if ampm in ('', locale_time.am_pm[0]):
                    # We're in AM so the hour is correct unless we're
                    # looking at 12 midnight.
                    # 12 midnight == 12 AM == hour 0
                    if hour == 12:
                        hour = 0
                elif ampm == locale_time.am_pm[1]:
                    # We're in PM so we need to add 12 to the hour unless
                    # we're looking at 12 noon.
                    # 12 noon == 12 PM == hour 12
                    if hour != 12:
                        hour += 12
            elif group_key == 'M':
                minute = int(found_dict['M'])
            elif group_key == 'S':
                second = int(found_dict['S'])
            elif group_key == 'f':
                s = found_dict['f']
                # Pad to always return microseconds.
                s += "0" * (6 - len(s))
                fraction = int(s)
            elif group_key == 'A':
                weekday = locale_time.f_weekday.index(found_dict['A'].lower())
            elif group_key == 'a':
                weekday = locale_time.a_weekday.index(found_dict['a'].lower())
            elif group_key == 'w':
                weekday = int(found_dict['w'])
                if weekday == 0:
                    weekday = 6
                else:
                    weekday -= 1
            elif group_key == 'j':
                julian = int(found_dict['j'])
            elif group_key in ('U', 'W'):
                week_of_year = int(found_dict[group_key])
                if group_key == 'U':
                    # U starts week on Sunday.
                    week_of_year_start = 6
                else:
                    # W starts week on Monday.
                    week_of_year_start = 0
            elif group_key == 'z':
                z = found_dict['z']
                tzoffset = int(z[1:3]) * 60 + int(z[3:5])
                if z.startswith("-"):
                    tzoffset = -tzoffset
            elif group_key == 'Z':
                # Since -1 is default value only need to worry about setting tz if
                # it can be something other than -1.
                found_zone = found_dict['Z'].lower()
                for value, tz_values in enumerate(locale_time.timezone):
                    if found_zone in tz_values:
                        # Deal with bad locale setup where timezone names are the
                        # same and yet time.daylight is true; too ambiguous to
                        # be able to tell what timezone has daylight savings
                        if (time.tzname[0] == time.tzname[1] and time.daylight
                                and found_zone not in ("utc", "gmt")):
                            break
                        else:
                            tz = value
                            break
        # If we know the week of the year and what day of that week, we can figure
        # out the Julian day of the year.
        if julian == -1 and week_of_year != -1 and weekday != -1:
            week_starts_Mon = True if week_of_year_start == 0 else False
            julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
                                              week_starts_Mon)
        # Cannot pre-calculate datetime_date() since can change in Julian
        # calculation and thus could have different value for the day of the week
        # calculation.
        if julian == -1:
            # Need to add 1 to result since first day of the year is 1, not 0.
            julian = datetime_date(year, month, day).toordinal() - \
                      datetime_date(year, 1, 1).toordinal() + 1
        else:  # Assume that if they bothered to include Julian day it will
            # be accurate.
            datetime_result = datetime_date.fromordinal(
                (julian - 1) + datetime_date(year, 1, 1).toordinal())
            year = datetime_result.year
            month = datetime_result.month
            day = datetime_result.day
        if weekday == -1:
            weekday = datetime_date(year, month, day).weekday()
        # Add timezone info
        tzname = found_dict.get("Z")
        if tzoffset is not None:
            gmtoff = tzoffset * 60
        else:
            gmtoff = None

        return (year, month, day, hour, minute, second, weekday, julian, tz,
                gmtoff, tzname), fraction
Пример #3
0
    def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
        """Return a 2-tuple consisting of a time struct and an int containing
        the number of microseconds based on the input string and the
        format string."""

        for index, arg in enumerate([data_string, format]):
            if not isinstance(arg, str):
                msg = "strptime() argument {} must be str, not {}"
                raise TypeError(msg.format(index, type(arg)))

        global _TimeRE_cache, _regex_cache
        with _cache_lock:
            if _getlang() != _TimeRE_cache.locale_time.lang:
                _TimeRE_cache = TimeRE()
                _regex_cache.clear()
            if len(_regex_cache) > _CACHE_MAX_SIZE:
                _regex_cache.clear()
            locale_time = _TimeRE_cache.locale_time
            format_regex = _regex_cache.get(format)
            if not format_regex:
                try:
                    format_regex = _TimeRE_cache.compile(format)
                # KeyError raised when a bad format is found; can be specified as
                # \\, in which case it was a stray % but with a space after it
                except KeyError as err:
                    bad_directive = err.args[0]
                    if bad_directive == "\\":
                        bad_directive = "%"
                    del err
                    raise ValueError("'%s' is a bad directive in format '%s'" %
                                        (bad_directive, format))
                # IndexError only occurs when the format string is "%"
                except IndexError:
                    raise ValueError("stray %% in format '%s'" % format)
                _regex_cache[format] = format_regex
        found = format_regex.match(data_string)
        if not found:
            raise ValueError("time data %r does not match format %r" %
                             (data_string, format))
        if len(data_string) != found.end():
            raise ValueError("unconverted data remains: %s" %
                              data_string[found.end():])

        year = 1900
        month = day = 1
        hour = minute = second = fraction = 0
        tz = -1
        tzoffset = None
        # Default to -1 to signify that values not known; not critical to have,
        # though
        week_of_year = -1
        week_of_year_start = -1
        # weekday and julian defaulted to -1 so as to signal need to calculate
        # values
        weekday = julian = -1
        found_dict = found.groupdict()
        for group_key in found_dict.iterkeys():
            # Directives not explicitly handled below:
            #   c, x, X
            #      handled by making out of other directives
            #   U, W
            #      worthless without day of the week
            if group_key == 'y':
                year = int(found_dict['y'])
                # Open Group specification for strptime() states that a %y
                #value in the range of [00, 68] is in the century 2000, while
                #[69,99] is in the century 1900
                if year <= 68:
                    year += 2000
                else:
                    year += 1900
            elif group_key == 'Y':
                year = int(found_dict['Y'])
            elif group_key == 'm':
                month = int(found_dict['m'])
            elif group_key == 'B':
                month = locale_time.f_month.index(found_dict['B'].lower())
            elif group_key == 'b':
                month = locale_time.a_month.index(found_dict['b'].lower())
            elif group_key == 'd':
                day = int(found_dict['d'])
            elif group_key == 'H':
                hour = int(found_dict['H'])
            elif group_key == 'I':
                hour = int(found_dict['I'])
                ampm = found_dict.get('p', '').lower()
                # If there was no AM/PM indicator, we'll treat this like AM
                if ampm in ('', locale_time.am_pm[0]):
                    # We're in AM so the hour is correct unless we're
                    # looking at 12 midnight.
                    # 12 midnight == 12 AM == hour 0
                    if hour == 12:
                        hour = 0
                elif ampm == locale_time.am_pm[1]:
                    # We're in PM so we need to add 12 to the hour unless
                    # we're looking at 12 noon.
                    # 12 noon == 12 PM == hour 12
                    if hour != 12:
                        hour += 12
            elif group_key == 'M':
                minute = int(found_dict['M'])
            elif group_key == 'S':
                second = int(found_dict['S'])
            elif group_key == 'f':
                s = found_dict['f']
                # Pad to always return microseconds.
                s += "0" * (6 - len(s))
                fraction = int(s)
            elif group_key == 'A':
                weekday = locale_time.f_weekday.index(found_dict['A'].lower())
            elif group_key == 'a':
                weekday = locale_time.a_weekday.index(found_dict['a'].lower())
            elif group_key == 'w':
                weekday = int(found_dict['w'])
                if weekday == 0:
                    weekday = 6
                else:
                    weekday -= 1
            elif group_key == 'j':
                julian = int(found_dict['j'])
            elif group_key in ('U', 'W'):
                week_of_year = int(found_dict[group_key])
                if group_key == 'U':
                    # U starts week on Sunday.
                    week_of_year_start = 6
                else:
                    # W starts week on Monday.
                    week_of_year_start = 0
            elif group_key == 'z':
                z = found_dict['z']
                tzoffset = int(z[1:3]) * 60 + int(z[3:5])
                if z.startswith("-"):
                    tzoffset = -tzoffset
            elif group_key == 'Z':
                # Since -1 is default value only need to worry about setting tz if
                # it can be something other than -1.
                found_zone = found_dict['Z'].lower()
                for value, tz_values in enumerate(locale_time.timezone):
                    if found_zone in tz_values:
                        # Deal with bad locale setup where timezone names are the
                        # same and yet time.daylight is true; too ambiguous to
                        # be able to tell what timezone has daylight savings
                        if (time.tzname[0] == time.tzname[1] and
                           time.daylight and found_zone not in ("utc", "gmt")):
                            break
                        else:
                            tz = value
                            break
        # If we know the week of the year and what day of that week, we can figure
        # out the Julian day of the year.
        if julian == -1 and week_of_year != -1 and weekday != -1:
            week_starts_Mon = True if week_of_year_start == 0 else False
            julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
                                                week_starts_Mon)
        # Cannot pre-calculate datetime_date() since can change in Julian
        # calculation and thus could have different value for the day of the week
        # calculation.
        if julian == -1:
            # Need to add 1 to result since first day of the year is 1, not 0.
            julian = datetime_date(year, month, day).toordinal() - \
                      datetime_date(year, 1, 1).toordinal() + 1
        else:  # Assume that if they bothered to include Julian day it will
               # be accurate.
            datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal())
            year = datetime_result.year
            month = datetime_result.month
            day = datetime_result.day
        if weekday == -1:
            weekday = datetime_date(year, month, day).weekday()
        # Add timezone info
        tzname = found_dict.get("Z")
        if tzoffset is not None:
            gmtoff = tzoffset * 60
        else:
            gmtoff = None

        return (year, month, day,
                hour, minute, second,
                weekday, julian, tz, gmtoff, tzname), fraction