Package parsedatetime :: Package pdt_locales :: Module icu
[hide private]
[frames] | no frames]

Source Code for Module parsedatetime.pdt_locales.icu

  1  # -*- encoding: utf-8 -*- 
  2   
  3  """ 
  4  pdt_locales 
  5   
  6  All of the included locale classes shipped with pdt. 
  7  """ 
  8  import datetime 
  9   
 10  try: 
 11      range = xrange 
 12  except NameError: 
 13      pass 
 14   
 15  try: 
 16      import icu as pyicu 
 17  except ImportError: 
 18      try: 
 19          import PyICU as pyicu 
 20      except ImportError: 
 21          pyicu = None 
 22   
 23   
24 -def icu_object(mapping):
25 return type('_icu', (object,), mapping)
26 27
28 -def merge_weekdays(base_wd, icu_wd):
29 result = [] 30 for left, right in zip(base_wd, icu_wd): 31 if left == right: 32 result.append(left) 33 continue 34 left = set(left.split('|')) 35 right = set(right.split('|')) 36 result.append('|'.join(left | right)) 37 return result
38 39
40 -def get_icu(locale):
41 42 def _sanitize_key(k): 43 import re 44 return re.sub("\\.(\\||$)", "\\1", k)
45 46 from . import base 47 result = dict([(key, getattr(base, key)) 48 for key in dir(base) if not key.startswith('_')]) 49 result['icu'] = None 50 51 if pyicu is None: 52 return icu_object(result) 53 54 if locale is None: 55 locale = 'en_US' 56 result['icu'] = icu = pyicu.Locale(locale) 57 58 if icu is None: 59 return icu_object(result) 60 61 # grab spelled out format of all numbers from 0 to 100 62 rbnf = pyicu.RuleBasedNumberFormat(pyicu.URBNFRuleSetTag.SPELLOUT, icu) 63 result['numbers'].update([(rbnf.format(i), i) for i in range(0, 100)]) 64 65 symbols = result['symbols'] = pyicu.DateFormatSymbols(icu) 66 67 # grab ICU list of weekdays, skipping first entry which 68 # is always blank 69 wd = [_sanitize_key(w.lower()) for w in symbols.getWeekdays()[1:]] 70 swd = [_sanitize_key(sw.lower()) for sw in symbols.getShortWeekdays()[1:]] 71 72 # store them in our list with Monday first (ICU puts Sunday first) 73 result['Weekdays'] = merge_weekdays(result['Weekdays'], 74 wd[1:] + wd[0:1]) 75 result['shortWeekdays'] = merge_weekdays(result['shortWeekdays'], 76 swd[1:] + swd[0:1]) 77 result['Months'] = [_sanitize_key(m.lower()) for m in symbols.getMonths()] 78 result['shortMonths'] = [_sanitize_key(sm.lower()) for sm in symbols.getShortMonths()] 79 keys = ['full', 'long', 'medium', 'short'] 80 81 createDateInstance = pyicu.DateFormat.createDateInstance 82 createTimeInstance = pyicu.DateFormat.createTimeInstance 83 icu_df = result['icu_df'] = { 84 'full': createDateInstance(pyicu.DateFormat.kFull, icu), 85 'long': createDateInstance(pyicu.DateFormat.kLong, icu), 86 'medium': createDateInstance(pyicu.DateFormat.kMedium, icu), 87 'short': createDateInstance(pyicu.DateFormat.kShort, icu), 88 } 89 icu_tf = result['icu_tf'] = { 90 'full': createTimeInstance(pyicu.DateFormat.kFull, icu), 91 'long': createTimeInstance(pyicu.DateFormat.kLong, icu), 92 'medium': createTimeInstance(pyicu.DateFormat.kMedium, icu), 93 'short': createTimeInstance(pyicu.DateFormat.kShort, icu), 94 } 95 96 result['dateFormats'] = {} 97 result['timeFormats'] = {} 98 for x in keys: 99 result['dateFormats'][x] = icu_df[x].toPattern() 100 result['timeFormats'][x] = icu_tf[x].toPattern() 101 102 am = pm = ts = '' 103 104 # ICU doesn't seem to provide directly the date or time separator 105 # so we have to figure it out 106 o = result['icu_tf']['short'] 107 s = result['timeFormats']['short'] 108 109 result['usesMeridian'] = 'a' in s 110 result['uses24'] = 'H' in s 111 112 # '11:45 AM' or '11:45' 113 s = o.format(datetime.datetime(2003, 10, 30, 11, 45)) 114 115 # ': AM' or ':' 116 s = s.replace('11', '').replace('45', '') 117 118 if len(s) > 0: 119 ts = s[0] 120 121 if result['usesMeridian']: 122 # '23:45 AM' or '23:45' 123 am = s[1:].strip() 124 s = o.format(datetime.datetime(2003, 10, 30, 23, 45)) 125 126 if result['uses24']: 127 s = s.replace('23', '') 128 else: 129 s = s.replace('11', '') 130 131 # 'PM' or '' 132 pm = s.replace('45', '').replace(ts, '').strip() 133 134 result['timeSep'] = [ts] 135 result['meridian'] = [am, pm] if am and pm else [] 136 137 o = result['icu_df']['short'] 138 s = o.format(datetime.datetime(2003, 10, 30, 11, 45)) 139 s = s.replace('10', '').replace('30', '').replace( 140 '03', '').replace('2003', '') 141 142 if len(s) > 0: 143 ds = s[0] 144 else: 145 ds = '/' 146 147 result['dateSep'] = [ds] 148 s = result['dateFormats']['short'] 149 ll = s.lower().split(ds) 150 dp_order = [] 151 152 for s in ll: 153 if len(s) > 0: 154 dp_order.append(s[:1]) 155 156 result['dp_order'] = dp_order 157 return icu_object(result) 158