|
| 1 | +""" strptime version 1.3, Time-stamp: <96/09/23 21:22:24 flognat> |
| 2 | + The reverse of strftime. |
| 3 | +
|
| 4 | + Copyright (C) 1996 Andy Eskilsson, [email protected] |
| 5 | +
|
| 6 | + This is free software; unrestricted redistribution is allowed under the |
| 7 | + terms of the GPL. For full details of the license conditions of this |
| 8 | + software, see the GNU General Public License. |
| 9 | +
|
| 10 | + And here comes the documentation: |
| 11 | +
|
| 12 | + Throw a string and a format specification at strptime and if everything |
| 13 | + is ok you will get a tuple containing 9 items that are compatible with |
| 14 | + pythons time-module. |
| 15 | +
|
| 16 | + interface: |
| 17 | + strptime(inputstring, formatstring) |
| 18 | +
|
| 19 | + Little errorchecking... so you'd better know what you are doing. |
| 20 | +
|
| 21 | + example: |
| 22 | + from strptime import * |
| 23 | + mktime(strptime("26/6 1973", "%d/%m %Y")) |
| 24 | +
|
| 25 | + And voila you have the second when the author of this function was born. |
| 26 | +
|
| 27 | + The supported format identifiers are: |
| 28 | + %a weekday in short text-form, e.g. Mon |
| 29 | + %A weekday in long text-form, e.g. Monday |
| 30 | + %b month in short text-form, e.g. Jul |
| 31 | + %B month in long text-form e.g. July |
| 32 | + %c the format specified by DateAndTimeRepresentation |
| 33 | + %d the day in month in numeric form, e.g. 24 |
| 34 | + %H hour in 24 hour form |
| 35 | + %j julian day (day of year) |
| 36 | + %m month in numeric format |
| 37 | + %M minute |
| 38 | + %S second |
| 39 | + %T Time in '%H:%M:%S'-format |
| 40 | + %w weekday, 0=monday |
| 41 | + %x date in format represented by DateRepresentation |
| 42 | + %X time in format represented by TimeRepresentation |
| 43 | + %y year in short form |
| 44 | + %Y year in long form |
| 45 | + %% %-sign |
| 46 | +
|
| 47 | + I have done some thinking here (*REALLY*) and it is possible to configure |
| 48 | + this module so it uses other languages by adding their names to the |
| 49 | + dictionaries first in the file, and setting the variable LANGUAGE. |
| 50 | +
|
| 51 | + For your exercise I have inserted the swedish names ;-) |
| 52 | +
|
| 53 | + The lfind, name, complex, numbers and parse functions are for internal |
| 54 | + use, called by strptime. |
| 55 | +
|
| 56 | + Uh.. oh yeah.. if you want to get in touch with me.. I am reachable |
| 57 | + at [email protected], the newest version of this file can probably |
| 58 | + be found somewhere close to http://www.fukt.hk-r.se/~flognat |
| 59 | +
|
| 60 | + If you like it, send a postcard to Andy Eskilsson |
| 61 | + Kämnärsv. 3b228 |
| 62 | + S-226 46 Lund |
| 63 | + Sweden |
| 64 | +
|
| 65 | + Uhm be gentle with the bug-reports, its the first time for me ;-) |
| 66 | +
|
| 67 | + """ |
| 68 | + |
| 69 | +import string |
| 70 | + |
| 71 | +LongDayNames={ 'English' : [ 'Monday', 'Tuesday', 'Wednesday', |
| 72 | + 'Thursday', 'Friday', 'Saturday', 'Sunday'], |
| 73 | + 'Swedish' : [ 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', |
| 74 | + 'Fredag', 'Lördag', 'Söndag']} |
| 75 | +ShortDayNames={ 'English' : [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
| 76 | + 'Swedish' : [ 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör', 'Sön']} |
| 77 | + |
| 78 | +LongMonthNames={ 'English' : ['none', 'January', 'February', 'March', 'April', |
| 79 | + 'May', 'June', 'July', 'August', 'September', |
| 80 | + 'October', 'November', 'December'], |
| 81 | + 'Swedish' : ['none', 'Januari', 'Februari', 'Mars', 'April', |
| 82 | + 'Maj', 'Juni', 'Juli', 'Augusti','September', |
| 83 | + 'Oktober', 'November', 'December'] } |
| 84 | +ShortMonthNames={ 'English' : ['none', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', |
| 85 | + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], |
| 86 | + 'Swedish' : ['none', 'Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', |
| 87 | + 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']} |
| 88 | +DateAndTimeRepresentation={ 'English' : '%a %b %d %H:%m:%S %Y', |
| 89 | + 'Swedish' : '%a %d %b %Y %H:%m:%S' } |
| 90 | + |
| 91 | +DateRepresentation = { 'English' : '%m/%d/%y', |
| 92 | + 'Swedish' : '%d/%m/%y'} |
| 93 | + |
| 94 | +TimeRepresentation = { 'English' : '%H:%M:%S', |
| 95 | + 'Swedish' : '%H:%M:%S'} |
| 96 | + |
| 97 | +LANGUAGE='English' |
| 98 | + |
| 99 | +BadFormatter='An illegal formatter was given' |
| 100 | + |
| 101 | +#Check if strinf begins with substr |
| 102 | +def lfind(str, substr): |
| 103 | + return string.lower(str[:len(substr)])==string.lower(substr) |
| 104 | + |
| 105 | +#atoms consisting of other atoms |
| 106 | +def complex(str, format, base): |
| 107 | + code=format[:1] |
| 108 | + if code=='c': |
| 109 | + string=DateAndTimeRepresentation[LANGUAGE] |
| 110 | + elif code=='T': |
| 111 | + string='%H:%M:%S' |
| 112 | + elif code=='x': |
| 113 | + string=DateRepresentation[LANGUAGE] |
| 114 | + elif code=='X': |
| 115 | + string=TimeRepresentation[LANGUAGE] |
| 116 | + |
| 117 | + return parse(str, string, base) |
| 118 | + |
| 119 | +#string based names |
| 120 | +def names(str, format, base): |
| 121 | + code=format[:1] |
| 122 | + if code=='a': |
| 123 | + selection=ShortDayNames[LANGUAGE] |
| 124 | + result='weekd' |
| 125 | + elif code=='A': |
| 126 | + selection=LongDayNames[LANGUAGE] |
| 127 | + result='weekd' |
| 128 | + elif code=='b': |
| 129 | + selection=ShortMonthNames[LANGUAGE] |
| 130 | + result='month' |
| 131 | + elif code=='B': |
| 132 | + selection=LongMonthNames[LANGUAGE] |
| 133 | + result='month' |
| 134 | + |
| 135 | + match=None |
| 136 | + for i in selection: |
| 137 | + if lfind(str, i): |
| 138 | + match=i |
| 139 | + break |
| 140 | + |
| 141 | + base[result]=selection.index(match) |
| 142 | + return len(match) |
| 143 | + |
| 144 | +#numeric stuff |
| 145 | +def numeric(str, format, base): |
| 146 | + code=format[:1] |
| 147 | + if code=='d': result='day' |
| 148 | + elif code=='H': result='hour' |
| 149 | + elif code=='j': result='juliand' |
| 150 | + elif code=='m': result='month' |
| 151 | + elif code=='M': result='min' |
| 152 | + elif code=='S': result='sec' |
| 153 | + elif code=='w': result='weekd' |
| 154 | + elif code=='y': result='shortYear' |
| 155 | + elif code=='Y': result='year' |
| 156 | + |
| 157 | + i=0 |
| 158 | + while str[i] in string.whitespace: i=i+1 |
| 159 | + j=i |
| 160 | + if len(format)>1: |
| 161 | + while not str[j] in string.whitespace and str[j]!=format[1]: j=j+1 |
| 162 | + else: |
| 163 | + try: |
| 164 | + while not str[j] in string.whitespace: j=j+1 |
| 165 | + except IndexError: |
| 166 | + pass |
| 167 | + |
| 168 | + # hmm could check exception here, but what could I add? |
| 169 | + base[result]=string.atoi(str[i:j]) |
| 170 | + |
| 171 | + return j |
| 172 | + |
| 173 | +parseFuns={ 'a':names, 'A':names, 'b':names, 'B':names, 'c':complex, 'd':numeric, |
| 174 | + 'H':numeric, 'j':numeric, 'm':numeric, 'M':numeric, 'S':numeric, |
| 175 | + 'T':complex, 'w':numeric, 'x':complex, 'y':numeric, 'Y':numeric} |
| 176 | + |
| 177 | +# Well split up in atoms, reason to why this is separated from atrptime |
| 178 | +# is to be able to reparse complex atoms |
| 179 | +def parse(str, format, base): |
| 180 | + atoms=string.split(format, '%') |
| 181 | + charCounter=0 |
| 182 | + atomCounter=0 |
| 183 | + |
| 184 | + # Hey I am laazy and think that the format is exactly what the string is! |
| 185 | + charCounter=charCounter+len(atoms[atomCounter]) |
| 186 | + atomCounter=atomCounter+1 |
| 187 | + |
| 188 | + while atomCounter < len(atoms) and charCounter < len(str): |
| 189 | + atom=atoms[atomCounter] |
| 190 | + |
| 191 | + if atom=='': # escaped |
| 192 | + charCounter=charCounter+1 |
| 193 | + atomCounter=atomCounter+1 |
| 194 | + charCounter=charCounter+len(atoms[atomCounter]) |
| 195 | + else: |
| 196 | + try: |
| 197 | + parsefunction=parseFuns[atom[:1]] |
| 198 | + except KeyError: |
| 199 | + raise BadFormatter, atom[:1] |
| 200 | + grabbed=apply(parsefunction, (str[charCounter:], atom, base)) |
| 201 | + charCounter=charCounter+grabbed+len(atom)-1 |
| 202 | + |
| 203 | + atomCounter=atomCounter+1 |
| 204 | + |
| 205 | + return charCounter |
| 206 | + |
| 207 | +# Ok here we go, tadaaa --> STRPTIME <-- at last.. |
| 208 | +def strptime(str, format): |
| 209 | + """Converts str specified by format to tuple useable by the time module""" |
| 210 | + returnTime={} |
| 211 | + returnTime['year']=0 |
| 212 | + returnTime['shortYear']=None |
| 213 | + returnTime['month']=0 |
| 214 | + returnTime['day']=0 |
| 215 | + returnTime['hour']=0 |
| 216 | + returnTime['min']=0 |
| 217 | + returnTime['sec']=0 |
| 218 | + returnTime['weekd']=0 |
| 219 | + returnTime['juliand']=0 |
| 220 | + returnTime['dst']=0 |
| 221 | + |
| 222 | + parse(str, format, returnTime) |
| 223 | + |
| 224 | + if returnTime['shortYear']!=None: |
| 225 | + returnTime['year']=returnTime['shortYear']+1900 |
| 226 | + |
| 227 | + return (returnTime['year'], returnTime['month'], returnTime['day'], |
| 228 | + returnTime['hour'], returnTime['min'], returnTime['sec'], |
| 229 | + returnTime['weekd'], returnTime['juliand'], returnTime['dst']) |
| 230 | + |
| 231 | +# just for my convenience |
| 232 | +def strpdebug(): |
| 233 | + import pdb |
| 234 | + pdb.run('strptime("% Tue 3 Feb", "%% %a %d %b")') |
| 235 | + |
| 236 | +def test(): |
| 237 | + from time import * |
| 238 | + a=asctime(localtime(time())) |
| 239 | + print a |
| 240 | + b=strptime(a, '%a %b %d %H:%M:%S %Y') |
| 241 | + print asctime(b) |
| 242 | + print strptime("%% % Tue 3 Feb", "%%%% %% %a %d %b") |
| 243 | + print strptime('Thu, 12 Sep 1996 19:42:06 GMT', '%a, %d %b %Y %T GMT') |
| 244 | + print strptime('Thu, 12 Sep 1996 19:42:06 GMT', '%a, %d %b %Y %T') |
| 245 | + print strptime('Thu, 12 Sep 1996 19:42:06', '%a, %d %b %Y %T') |
| 246 | + |
| 247 | +if __name__ == '__main__': |
| 248 | + test() |
| 249 | + |
| 250 | + |
0 commit comments