_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]