NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

_strptime.py (11746B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\_strptime.py
      2 import time
      3 import locale
      4 import calendar
      5 from re import compile as re_compile
      6 from re import IGNORECASE
      7 from re import escape as re_escape
      8 from datetime import date as datetime_date
      9 try:
     10     from thread import allocate_lock as _thread_allocate_lock
     11 except:
     12     from dummy_thread import allocate_lock as _thread_allocate_lock
     13 
     14 __all__ = []
     15 
     16 def _getlang():
     17     return locale.getlocale(locale.LC_TIME)
     18 
     19 
     20 class LocaleTime(object):
     21 
     22     def __init__(self):
     23         self.lang = _getlang()
     24         self.__calc_weekday()
     25         self.__calc_month()
     26         self.__calc_am_pm()
     27         self.__calc_timezone()
     28         self.__calc_date_time()
     29         if _getlang() != self.lang:
     30             raise ValueError('locale changed during initialization')
     31 
     32     def __pad(self, seq, front):
     33         seq = list(seq)
     34         if front:
     35             seq.insert(0, '')
     36         else:
     37             seq.append('')
     38         return seq
     39 
     40     def __calc_weekday(self):
     41         a_weekday = [ calendar.day_abbr[i].lower() for i in range(7) ]
     42         f_weekday = [ calendar.day_name[i].lower() for i in range(7) ]
     43         self.a_weekday = a_weekday
     44         self.f_weekday = f_weekday
     45 
     46     def __calc_month(self):
     47         a_month = [ calendar.month_abbr[i].lower() for i in range(13) ]
     48         f_month = [ calendar.month_name[i].lower() for i in range(13) ]
     49         self.a_month = a_month
     50         self.f_month = f_month
     51 
     52     def __calc_am_pm(self):
     53         am_pm = []
     54         for hour in (1, 22):
     55             time_tuple = time.struct_time((1999,
     56              3,
     57              17,
     58              hour,
     59              44,
     60              55,
     61              2,
     62              76,
     63              0))
     64             am_pm.append(time.strftime('%p', time_tuple).lower())
     65 
     66         self.am_pm = am_pm
     67 
     68     def __calc_date_time(self):
     69         time_tuple = time.struct_time((1999, 3, 17, 22, 44, 55, 2, 76, 0))
     70         date_time = [None, None, None]
     71         date_time[0] = time.strftime('%c', time_tuple).lower()
     72         date_time[1] = time.strftime('%x', time_tuple).lower()
     73         date_time[2] = time.strftime('%X', time_tuple).lower()
     74         replacement_pairs = [('%', '%%'),
     75          (self.f_weekday[2], '%A'),
     76          (self.f_month[3], '%B'),
     77          (self.a_weekday[2], '%a'),
     78          (self.a_month[3], '%b'),
     79          (self.am_pm[1], '%p'),
     80          ('1999', '%Y'),
     81          ('99', '%y'),
     82          ('22', '%H'),
     83          ('44', '%M'),
     84          ('55', '%S'),
     85          ('76', '%j'),
     86          ('17', '%d'),
     87          ('03', '%m'),
     88          ('3', '%m'),
     89          ('2', '%w'),
     90          ('10', '%I')]
     91         replacement_pairs.extend([ (tz, '%Z') for tz_values in self.timezone for tz in tz_values ])
     92         for offset, directive in ((0, '%c'), (1, '%x'), (2, '%X')):
     93             current_format = date_time[offset]
     94             for old, new in replacement_pairs:
     95                 if old:
     96                     current_format = current_format.replace(old, new)
     97 
     98             time_tuple = time.struct_time((1999, 1, 3, 1, 1, 1, 6, 3, 0))
     99             if '00' in time.strftime(directive, time_tuple):
    100                 U_W = '%W'
    101             else:
    102                 U_W = '%U'
    103             date_time[offset] = current_format.replace('11', U_W)
    104 
    105         self.LC_date_time = date_time[0]
    106         self.LC_date = date_time[1]
    107         self.LC_time = date_time[2]
    108 
    109     def __calc_timezone(self):
    110         try:
    111             time.tzset()
    112         except AttributeError:
    113             pass
    114 
    115         no_saving = frozenset(['utc', 'gmt', time.tzname[0].lower()])
    116         if time.daylight:
    117             has_saving = frozenset([time.tzname[1].lower()])
    118         else:
    119             has_saving = frozenset()
    120         self.timezone = (no_saving, has_saving)
    121 
    122 
    123 class TimeRE(dict):
    124 
    125     def __init__(self, locale_time = None):
    126         if locale_time:
    127             self.locale_time = locale_time
    128         else:
    129             self.locale_time = LocaleTime()
    130         base = super(TimeRE, self)
    131         base.__init__({'d': '(?P<d>3[0-1]|[1-2]\\d|0[1-9]|[1-9]| [1-9])',
    132          'f': '(?P<f>[0-9]{1,6})',
    133          'H': '(?P<H>2[0-3]|[0-1]\\d|\\d)',
    134          'I': '(?P<I>1[0-2]|0[1-9]|[1-9])',
    135          'j': '(?P<j>36[0-6]|3[0-5]\\d|[1-2]\\d\\d|0[1-9]\\d|00[1-9]|[1-9]\\d|0[1-9]|[1-9])',
    136          'm': '(?P<m>1[0-2]|0[1-9]|[1-9])',
    137          'M': '(?P<M>[0-5]\\d|\\d)',
    138          'S': '(?P<S>6[0-1]|[0-5]\\d|\\d)',
    139          'U': '(?P<U>5[0-3]|[0-4]\\d|\\d)',
    140          'w': '(?P<w>[0-6])',
    141          'y': '(?P<y>\\d\\d)',
    142          'Y': '(?P<Y>\\d\\d\\d\\d)',
    143          'A': self.__seqToRE(self.locale_time.f_weekday, 'A'),
    144          'a': self.__seqToRE(self.locale_time.a_weekday, 'a'),
    145          'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'),
    146          'b': self.__seqToRE(self.locale_time.a_month[1:], 'b'),
    147          'p': self.__seqToRE(self.locale_time.am_pm, 'p'),
    148          'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone for tz in tz_names), 'Z'),
    149          '%': '%'})
    150         base.__setitem__('W', base.__getitem__('U').replace('U', 'W'))
    151         base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
    152         base.__setitem__('x', self.pattern(self.locale_time.LC_date))
    153         base.__setitem__('X', self.pattern(self.locale_time.LC_time))
    154 
    155     def __seqToRE(self, to_convert, directive):
    156         to_convert = sorted(to_convert, key=len, reverse=True)
    157         for value in to_convert:
    158             if value != '':
    159                 break
    160         else:
    161             return ''
    162 
    163         regex = '|'.join((re_escape(stuff) for stuff in to_convert))
    164         regex = '(?P<%s>%s' % (directive, regex)
    165         return '%s)' % regex
    166 
    167     def pattern(self, format):
    168         processed_format = ''
    169         regex_chars = re_compile('([\\\\.^$*+?\\(\\){}\\[\\]|])')
    170         format = regex_chars.sub('\\\\\\1', format)
    171         whitespace_replacement = re_compile('\\s+')
    172         format = whitespace_replacement.sub('\\s+', format)
    173         while '%' in format:
    174             directive_index = format.index('%') + 1
    175             processed_format = '%s%s%s' % (processed_format, format[:directive_index - 1], self[format[directive_index]])
    176             format = format[directive_index + 1:]
    177 
    178         return '%s%s' % (processed_format, format)
    179 
    180     def compile(self, format):
    181         return re_compile(self.pattern(format), IGNORECASE)
    182 
    183 
    184 _cache_lock = _thread_allocate_lock()
    185 _TimeRE_cache = TimeRE()
    186 _CACHE_MAX_SIZE = 5
    187 _regex_cache = {}
    188 
    189 def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
    190     first_weekday = datetime_date(year, 1, 1).weekday()
    191     if not week_starts_Mon:
    192         first_weekday = (first_weekday + 1) % 7
    193         day_of_week = (day_of_week + 1) % 7
    194     week_0_length = (7 - first_weekday) % 7
    195     if week_of_year == 0:
    196         return 1 + day_of_week - first_weekday
    197     else:
    198         days_to_week = week_0_length + 7 * (week_of_year - 1)
    199         return 1 + days_to_week + day_of_week
    200 
    201 
    202 def _strptime(data_string, format = '%a %b %d %H:%M:%S %Y'):
    203     global _TimeRE_cache
    204     global _regex_cache
    205     with _cache_lock:
    206         if _getlang() != _TimeRE_cache.locale_time.lang:
    207             _TimeRE_cache = TimeRE()
    208             _regex_cache.clear()
    209         if len(_regex_cache) > _CACHE_MAX_SIZE:
    210             _regex_cache.clear()
    211         locale_time = _TimeRE_cache.locale_time
    212         format_regex = _regex_cache.get(format)
    213         if not format_regex:
    214             try:
    215                 format_regex = _TimeRE_cache.compile(format)
    216             except KeyError as err:
    217                 bad_directive = err.args[0]
    218                 if bad_directive == '\\':
    219                     bad_directive = '%'
    220                 del err
    221                 raise ValueError("'%s' is a bad directive in format '%s'" % (bad_directive, format))
    222             except IndexError:
    223                 raise ValueError("stray %% in format '%s'" % format)
    224 
    225             _regex_cache[format] = format_regex
    226     found = format_regex.match(data_string)
    227     if not found:
    228         raise ValueError('time data %r does not match format %r' % (data_string, format))
    229     if len(data_string) != found.end():
    230         raise ValueError('unconverted data remains: %s' % data_string[found.end():])
    231     year = 1900
    232     month = day = 1
    233     hour = minute = second = fraction = 0
    234     tz = -1
    235     week_of_year = -1
    236     week_of_year_start = -1
    237     weekday = julian = -1
    238     found_dict = found.groupdict()
    239     for group_key in found_dict.iterkeys():
    240         if group_key == 'y':
    241             year = int(found_dict['y'])
    242             if year <= 68:
    243                 year += 2000
    244             else:
    245                 year += 1900
    246         elif group_key == 'Y':
    247             year = int(found_dict['Y'])
    248         elif group_key == 'm':
    249             month = int(found_dict['m'])
    250         elif group_key == 'B':
    251             month = locale_time.f_month.index(found_dict['B'].lower())
    252         elif group_key == 'b':
    253             month = locale_time.a_month.index(found_dict['b'].lower())
    254         elif group_key == 'd':
    255             day = int(found_dict['d'])
    256         elif group_key == 'H':
    257             hour = int(found_dict['H'])
    258         elif group_key == 'I':
    259             hour = int(found_dict['I'])
    260             ampm = found_dict.get('p', '').lower()
    261             if ampm in ('', locale_time.am_pm[0]):
    262                 if hour == 12:
    263                     hour = 0
    264             elif ampm == locale_time.am_pm[1]:
    265                 if hour != 12:
    266                     hour += 12
    267         elif group_key == 'M':
    268             minute = int(found_dict['M'])
    269         elif group_key == 'S':
    270             second = int(found_dict['S'])
    271         elif group_key == 'f':
    272             s = found_dict['f']
    273             s += '0' * (6 - len(s))
    274             fraction = int(s)
    275         elif group_key == 'A':
    276             weekday = locale_time.f_weekday.index(found_dict['A'].lower())
    277         elif group_key == 'a':
    278             weekday = locale_time.a_weekday.index(found_dict['a'].lower())
    279         elif group_key == 'w':
    280             weekday = int(found_dict['w'])
    281             if weekday == 0:
    282                 weekday = 6
    283             else:
    284                 weekday -= 1
    285         elif group_key == 'j':
    286             julian = int(found_dict['j'])
    287         elif group_key in ('U', 'W'):
    288             week_of_year = int(found_dict[group_key])
    289             if group_key == 'U':
    290                 week_of_year_start = 6
    291             else:
    292                 week_of_year_start = 0
    293         elif group_key == 'Z':
    294             found_zone = found_dict['Z'].lower()
    295             for value, tz_values in enumerate(locale_time.timezone):
    296                 if found_zone in tz_values:
    297                     if time.tzname[0] == time.tzname[1] and time.daylight and found_zone not in ('utc', 'gmt'):
    298                         break
    299                     else:
    300                         tz = value
    301                         break
    302 
    303     if julian == -1 and week_of_year != -1 and weekday != -1:
    304         week_starts_Mon = True if week_of_year_start == 0 else False
    305         julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, week_starts_Mon)
    306     if julian == -1:
    307         julian = datetime_date(year, month, day).toordinal() - datetime_date(year, 1, 1).toordinal() + 1
    308     else:
    309         datetime_result = datetime_date.fromordinal(julian - 1 + datetime_date(year, 1, 1).toordinal())
    310         year = datetime_result.year
    311         month = datetime_result.month
    312         day = datetime_result.day
    313     if weekday == -1:
    314         weekday = datetime_date(year, month, day).weekday()
    315     return (time.struct_time((year,
    316       month,
    317       day,
    318       hour,
    319       minute,
    320       second,
    321       weekday,
    322       julian,
    323       tz)), fraction)
    324 
    325 
    326 def _strptime_time(data_string, format = '%a %b %d %H:%M:%S %Y'):
    327     return _strptime(data_string, format)[0]