PKñžC8Úú²?JŽJŽparsedatetime/parsedatetime.pyc;ò ÀÒEc@s½dZdZeZdkZdkZdkZdkZdkZd„Z d„Z d„Z d„Z hdd<d d <d d <d d<dd\d\d\d\d)(?:(?P-|)(?:(?P\d\d\d)|(?P\d\d)(?:(?P=dsep)(?P\d\d))?))?s;(?P[-+](?P\d\d)(?::?(?P\d\d))|Z)sW(?P\d\d)(?P:|)(?P\d\d)(?:(?P=tsep)(?P\d\d(?:[.,]\d+)?))?s %s(?:T%s)?i(s __extract_tzds __date_res__tzd_resrescompiles__tzd_rxs __time_res __datetime_res __datetime_rxsmatchs dateStringsmsNonesgroups _extract_dates _extract_time( s dateStrings__tzd_res __datetime_resms __date_res __datetime_rxs __time_res__tzd_rxs __extract_tzd((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys_parse_date_w3dtfns   cCs÷|iƒ}|ddddfjp|diƒtijo |d=nt|ƒdjof|d}|idƒ}|djo || ||dg|d)n|i d ƒd i |ƒ}nt|ƒd jo|d 7}nti |ƒSd S(s8Parse an RFC822, RFC1123, RFC2822, or asctime-style dateiiÿÿÿÿs,s.iis+iss is 00:00:00 GMTN( s dateStringssplitsdataslowersrfc822s _daynamesslensssfindsisappendsjoins parsedate_tz(s dateStringsisssdata((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys_parse_date_rfc822šs 5     sATipþÿÿsETi þÿÿsCTi¨ýÿÿsMTiDýÿÿsPTiàüÿÿsCalendarcBsŒtZdZed„Zd„Zd„Zd„Zd„Zed„Z d„Z d„Z d „Z ed „Z ed „Zeed „ZRS( sž A collection of routines to input, parse and manipulate date and times. The text can either be 'normal' date values or it can be human readable. cCs¢|tjotiƒ|_n ||_t|_t|_t|_ t|_ t|_ t|_ t|_ t|_t|_t|_t|_d|_d|_dS(só Default constructor for the L{Calendar} class. @type constants: object @param constants: Instance of the class L{parsedatetime_consts.Constants} @rtype: object @return: L{Calendar} instance iN(s constantssNonesparsedatetime_constss ConstantssselfsptcsFalses weekdyFlags dateStdFlags dateStrFlags timeStdFlags meridianFlags dayStrFlags timeStrFlags modifierFlags modifier2Flags unitsFlags qunitsFlagstimeFlagsdateFlag(sselfs constants((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys__init__¹s"               cCsdS(sz Converts text units into their number value Five = 5 Twenty Five = 25 Two hundred twenty five = 225 Two thousand and twenty five = 2025 Two thousand twenty five = 2025 @type unitText: string @param unitText: number text to convert @rtype: integer @return: numerical value of unitText N((sselfsunitText((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys_convertUnitAsWordsÙsc Cs»tod|||fGHn|tjotiƒ}n|tjo d}n |iƒ}t |ƒdjo d}n-yt |ƒ}Wnt j o d}nX||iijo<||ii|}|tjp |djo d}qõn|\ } }} }} }} } } ti| || || |ƒ}|} |idƒo"|i|d|ƒ} d|_nB|idƒp |id ƒo"|i|d |ƒ} d|_n|id ƒo#|tid |ƒ} d|_nÍ|id ƒo#|tid|ƒ} d|_nš|idƒo#|tid|ƒ} d|_ng|idƒo#|tid|ƒ} d|_n4|idƒo#|tid|ƒ} d|_n| i ƒSdS(s€ Take C{quantity}, C{modifier} and C{unit} strings and convert them into values. After converting, calcuate the time and return the adjusted sourceTime. @type source: time @param source: time to use as the base (or source) @type quantity: string @param quantity: quantity string @type modifier: string @param modifier: how quantity and units modify the source time @type units: string @param units: unit of the quantity (i.e. hours, days, months, etc) @rtype: struct_time @return: C{struct_time} of the calculated time s_buildTime: [%s][%s][%s]siisdysysyearsthsthssmonthsdsdaysshshoursismsminutesssssecondsswsweeksN(!s_debugsquantitysmodifiersunitsssourcesNonestimes localtimesstripslensqtysints ValueErrorsselfsptcs Modifierssyrsmthsdyshrsmnssecs_sdatetimesstartstargets startswithsincsdateFlagsendswiths timedeltastimeFlags timetuple(sselfssourcesquantitysmodifiersunitsssecsqtysstartshrsdysyrs_stargetsmnsmth((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys _buildTimeísV      !        c Cs¯tiƒ\ } }} }}}}}}d} d} d} |}|iii|ƒ}|tj o.|iƒ}t|| ƒ} ||d}n|iii|ƒ}|tj o4|iƒ}t|| ƒ} t||dƒ} nt|iƒƒ} | | | g}hd|<d| <d| <}xLtddƒD];}||}|ii|}|djo||||djo||d}n|djo||}n|djoö|djog|tjo-||jo||}qÖd||}qX||jo||}qXd||}q\|djog|tjo-||jo||}qJ||d}qX||jo||}qX||d}q\||}ntod||||fGHn|SdS(s Based on the C{style} and C{currentDayStyle} determine what day-of-week value is to be returned. @type wd: integer @param wd: day-of-week value for the current day @type wkdy: integer @param wkdy: day-of-week value for the parsed day @type offset: integer @param offset: offset direction for any modifiers (-1, 0, 1) @type style: integer @param style: normally the value set in C{Constants.DOWParseStyle} @type currentDayStyle: integer @param currentDayStyle: normally the value set in C{Constants.CurrentDOWParseStyle} @rtype: integer @return: calculated day-of-week iiiÿÿÿÿiis$wd %s, wkdy %s, offset %d, style %d N(soffsetswdswkdysdiffsstylescurrentDayStylesTrues_debug(sselfswdswkdysoffsetsstylescurrentDayStylesdiff((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys_CalculateDOWDeltaWs8            c Cs*|ii|}|tj o%|\ }}}}}}}}} n(tiƒ\ }}}}}}}}} |iii|ƒ}|tj o.|iƒd} ||iƒ } || }n |} d}t}| djp| djp | djo|djo9|ii|d}|||ddd||| f }n¿|djor||ii|djo|ii|}nti|||dddƒ} |i| ddƒ}|iƒ}n@ti||ddddƒ} |i| d|ƒ}|iƒ}t }d|_!n| d jp| d jp | d joÓ|djoHti|||d ddƒ} | ti"d d|ƒ}|iƒ}nl|djoDti|||dddƒ} | ti"d dƒ}|iƒ}n|i#||d||ƒSt }d|_!n| djp| djp | djoß|djo.|||d dd||| f }d|_%n’|djoDti||||||ƒ} | ti"d dƒ}|iƒ}nAti|||dddƒ} | ti"d |ƒ}|iƒ}t }d|_!n| djp | djo…|djo%||||dd||| f }nAti||||ddƒ} | ti"d|ƒ}|iƒ}t }d|_%n| djp| djp | djo |djo%|dd|||||| f }n\|djo)|d|||||||| f }n&||ddddd||| f }t }d|_!n|tjo-|ii&i'| ƒ}|tj o|i(ƒ}d|_!|djo[t|_*|i+||ƒ\}}|ii-|ƒ}d|_%||jo||}q’nx|ii/|}|i0||||ii1|ii2ƒ}ti|||dddƒ} | ti"d |ƒ}|iƒ}t }d|_!q©n| o'|ii4i'| ƒ}|tj oƒt|_*|i+| ƒ\\ }}}}}}}}} }ti||||||ƒ} | ti"d |ƒ}|iƒ}t }qØt|_*|i+d|| f|ƒ\}} | djo |}n|ii-|ƒ}||jo||}t }d|_%qØn| o/|djod| } nd| |f}nt|_*d||fSd S(!sÜ Evaluate the C{modifier} string and following text (passed in as C{chunk1} and C{chunk2}) and if they match any known modifiers calculate the delta and apply it to C{sourceTime}. @type modifier: string @param modifier: modifier text to apply to sourceTime @type chunk1: string @param chunk1: first text chunk that followed modifier (if any) @type chunk2: string @param chunk2: second text chunk that followed modifier (if any) @type sourceTime: struct_time @param sourceTime: C{struct_time} value to use as the base @rtype: tuple @return: tuple of: remaining text and the modified sourceTime issmonthsmthsmii isweekswkswisdaysiismonday sdaysdysdshourshrshourssyearsyrsyi iseods%s %ss-%ss%sN(7sselfsptcs Modifierssmodifiersoffsets sourceTimesNonesyrsmthsdyshrsmnssecswdsydsisdststimes localtimes CRE_REMAININGssearchschunk2smsstartsindexsunitsFalsesflagsDaysInMonthListsdatetimesincstargets timetuplesTruesdateFlags timedeltas _evalModifierschunk1stimeFlags CRE_WEEKDAYsmatchsgroupswkdys modifierFlagsparses_s buildSourcesssourcessWeekdayOffsetss_CalculateDOWDeltas DOWParseStylesCurrentDOWParseStylesdiffsCRE_TIMEstsflag2(sselfsmodifierschunk1schunk2s sourceTimesoffsetssourcesssecsdiffsunitsindexsisdstsstartsflag2swdshrsydsflagsdysyrs_stargetsmnsmsmthstswkdy((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys _evalModifierŸsä %' ' %   '   ' !     %  ' % )%             0   "      cCsé|ii|} d}t|_|djo¯| djoct i ||i ƒƒ}|t j o:t|iƒƒd}||iƒ}d||f}qœn|i||ƒ\}} | djo t} nt} t} nt} |djož| djoct i||i ƒƒ}|t j o:t|iƒƒd}||iƒ}d||f}q^n|i} |i}|i||ƒ\} } n|| o| fS| tjo | dj o | }n||_| |_|| o| fSdS(sß Evaluate the C{modifier} string and following text (passed in as C{chunk1} and C{chunk2}) and if they match any known modifiers calculate the delta and apply it to C{sourceTime}. @type modifier: string @param modifier: modifier text to apply to C{sourceTime} @type chunk1: string @param chunk1: first text chunk that followed modifier (if any) @type chunk2: string @param chunk2: second text chunk that followed modifier (if any) @type sourceTime: struct_time @param sourceTime: C{struct_time} value to use as the base @rtype: tuple @return: tuple of: remaining text and the modified sourceTime s\d+siiÿÿÿÿs%d%sN(sselfsptcs ModifierssmodifiersoffsetsdigitsFalses modifier2Flagschunk2sresmatchsstripsmsNonesintsgroupsqtysendsparses sourceTimesflag1sTruesflag2schunk1ssearchsdateFlags tempDateFlagstimeFlags tempTimeFlags sourceTime2(sselfsmodifierschunk1schunk2s sourceTimesdigits tempTimeFlagsmsqtysflag2sflag1soffsets tempDateFlags sourceTime2((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys_evalModifier2^sB              c Cs|iƒ}tiƒ}|tjo£t|ƒ}|tj o†|\ }} }}}}}}}}d|_|djo|djo |djo d|_n|| |||||||f }qÈn|tjo3t|ƒ}|tj od|_d|_qn|tjo|iƒ}n|io|tjo%|\ }} }}}}}}}n"|\ }} }}}}}}}|iii|ƒ}|tj o<||idƒ iƒ}t|ƒdjot |ƒ}d}d}nt!|ƒ\}}}|djo d}n|| |||||||f }|i"dƒiƒ} | |ii$jo |djo%|| |d|||||f }n| |ii%jo |djo)|| ||d|||||f }qàn|djp|djp |djo|}d|_d|_nt&|_n|i'o|tjo%|\ }} }}}}}}}n"|\ }} }}}}}}}|ii(i|ƒ}|tj ot!|ƒ\}}}n|djo d}n|djp|djp |djo|}d|_d|_n"|| |||||||f }t&|_'n|i)o|i*|ƒ}t&|_)n|i+o|i,|ƒ}t&|_+n|i-oã|\ }} }}}}}}}t.i.|| ||||ƒ} |ii/|}||jo+|i1||d|ii2|ii3ƒ}n(|i1||d|ii2|ii3ƒ}| t.i5d|ƒ}|}|i7ƒ}t&|_-n|i8os||ii9d jo |}nF|ii:|ƒ}||jo||}n|}d|_d|_t&|_8n|i<o²|tjo |}n|\ }} }}}}}}}||ii=jo|ii=|} nd} t.i.|| |d ddƒ} | t.i5d| ƒ}|i7ƒ}t&|_<n|i?oŠd }|tjo |}n|iiAi|ƒ}|tj o&|i"d ƒ} ||id ƒ }n|iD|||| ƒ}t&|_?n|iEoŠd }|tjo |}n|iiFi|ƒ}|tj o&|i"d ƒ} ||id ƒ }n|iD|||| ƒ}t&|_En|tjo|}d|_d|_n|SdS(s‚ Calculate the datetime based on flags set by the L{parse()} routine Examples handled:: RFC822, W3CDTF formatted dates HH:MM[:SS][ am/pm] MM/DD/YYYY DD MMMM YYYY @type datetimeString: string @param datetimeString: text to try and parse as more "traditional" date/time text @type sourceTime: struct_time @param sourceTime: C{struct_time} value to use as the base @rtype: datetime @return: calculated C{struct_time} value or current C{struct_time} if not parsed iiismeridianii i;sdayssnowi ssunitssqunitsN(GsdatetimeStringsstripssstimes localtimesnows sourceTimesNones_parse_date_rfc822syrsmthsdyshrsmnssecswdsydsisdsts_sselfsdateFlagstimeFlags_parse_date_w3dtfslowers meridianFlagsptcs CRE_TIMEHMS2ssearchsmsstartsdtslensints _extract_timesgroupsmeridiansamspmsFalses timeStdFlags CRE_TIMEHMSs dateStdFlags parseDates dateStrFlags parseDateTexts weekdyFlagsdatetimesWeekdayOffsetsswkdys_CalculateDOWDeltas DOWParseStylesCurrentDOWParseStylesqtys timedeltastargets timetuples timeStrFlags re_valuess buildSourcesssourcess dayStrFlags dayOffsetssoffsets unitsFlagsmodifiers CRE_UNITSsunitssquantitys _buildTimes qunitsFlags CRE_QUNITS(sselfsdatetimeStrings sourceTimeswkdyssourcesssecsnowsisdstsqtysmthsoffsetsstartsunitssmeridianswdshrsydsdysdtsyrs_stargetsmnsmsssmodifiersquantity((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys _evalString¨sú     $ ' )       %!     ! % -'     %!   '  !      !              !               cCsD |olt|tiƒo to dGHn|iƒ}qst|tiƒ ot|tƒ otdƒ‚qsn|i ƒi ƒ} d}|}| djo9|tj o||i|ifSq×tiƒdfSnd|_d|_x t| ƒdjoð t}d} d}tod| |fGHn|djoš|iii| ƒ} | tj ott|_| idƒ| joK| idƒ}| | i dƒ i ƒ} | | i!dƒi ƒ}t}qÎ| }qÒn|djoš|ii"i| ƒ} | tj ott|_#| idƒ| joK| idƒ}| | i dƒ i ƒ} | | i!dƒi ƒ}t}qu| }qyn|djo§|ii$i| ƒ} | tj ot|_%d|_| idƒ| joO| idƒ}| | i dƒ } | | i!dƒ}d | |f} t}q)| }q-n|djo§|ii&i| ƒ} | tj ot|_'d|_| idƒ| joO| idƒ}| | i dƒ } | | i!dƒ}d | |f} t}qÝ| }qán|djo§|ii(i| ƒ} | tj ot|_)d|_| id ƒ| joO| id ƒ}| | i d ƒ } | | i!d ƒ}d | |f} t}q‘| }q•n|djoÓ|ii*i| ƒ} | tj o­t|_+| id ƒ| jo„| id ƒ}| | i d ƒ i ƒ} | | i!d ƒi ƒ}| d d jod|}| d } nd | |f} t}qq| }qun|djoÓ|ii,i| ƒ} | tj o­t|_-| id ƒ| jo„| id ƒ}| | i d ƒ i ƒ} | | i!d ƒi ƒ}| d d jod|}| d } nd | |f} t}qQ| }qUn|djo§|ii.i| ƒ} | tj ot|_/d|_| idƒ| joO| idƒ}| | i dƒ } | | i!dƒ}d | |f} t}q| }q n|djo§|ii0i| ƒ} | tj ot|_1d|_| idƒ| joO| idƒ}| | i dƒ } | | i!dƒ}d | |f} t}q¹| }q½n|djo6|ii2i| ƒ} | tj ot|_3d|_| idƒtj o†| idƒtj o>d| idƒ| idƒ| idƒ| idƒf}q¼d| idƒ| idƒ| idƒf}n#d | idƒ| idƒf}| | i dƒ } | | i!dƒ}d | |f} t}q n|djo|ii4i| ƒ} | tj oât|_5d|_| idƒtj oXd| idƒ| idƒ| idƒf}| | i dƒ } | | i!dƒ}nId| idƒ| idƒf}| | i dƒ } | | i!dƒ}d | |f} t}q n| o d} ntomd| || |fGHd|i/|i'|i%|i5|i1|i3fGHd|i)|i|i#|i+|i-fGHn|djoC|itjoÂ|i6|| ||ƒ\} }| djo | tjo†|i}|i}|i:| |ƒ\}}|djo |tj o*||_||_||i|ifSqv ||i|ifSqç që |i#tjoE|i<|| ||ƒ\}} | tjod|_d|_qç që |i>||ƒ}d}qìqìW|tjp ||jo"tiƒ}d|_d|_n||i|ifSdS(sÞ Splits the given C{datetimeString} into tokens, finds the regex patterns that match and then calculates a C{struct_time} value from the chunks. If C{sourceTime} is given then the C{struct_time} value will be calculated from that value, otherwise from the current date/time. If the C{datetimeString} is parsed and date/time value found then the second item of the returned tuple will be a flag to let you know what kind of C{struct_time} value is being returned:: 0 = not parsed at all 1 = parsed as a C{date} 2 = parsed as a C{time} 3 = parsed as a C{datetime} @type datetimeString: string @param datetimeString: date/time text to evaluate @type sourceTime: struct_time @param sourceTime: C{struct_time} value to use as the base @rtype: tuple @return: tuple of: modified C{sourceTime} and the result flag scoercing datetime to timetuplessourceTime is not a struct_timesisparse (top of loop): [%s][%s]smodifierisdates%s %ssdaysqtyiÿÿÿÿs-s-%ssweekdayistimesminutesssecondss %s:%s:%s %sshourssmeridians%s:%s %ss%s:%s:%ss%s:%ssparse (bottom) [%s][%s][%s][%s]sDweekday %s, dateStd %s, dateStr %s, time %s, timeStr %s, meridian %ss9dayStr %s, modifier %s, modifier2 %s, units %s, qunits %sN(?s sourceTimes isinstancesdatetimes_debugs timetuplestimes struct_timestuples ExceptionsdatetimeStringsstripslowersssparseStrs totalTimesNonesselfsdateFlagstimeFlags localtimeslensFalsesflagschunk1schunk2sptcs CRE_MODIFIERssearchsmsTrues modifierFlagsgroupsstartsends CRE_MODIFIER2s modifier2Flags CRE_DATE3s dateStrFlagsCRE_DATEs dateStdFlagsCRE_DAYs dayStrFlags CRE_UNITSs unitsFlags CRE_QUNITSs qunitsFlags CRE_WEEKDAYs weekdyFlagsCRE_TIMEs timeStrFlags CRE_TIMEHMS2s meridianFlags CRE_TIMEHMSs timeStdFlags _evalModifiersts tempDateFlags tempTimeFlagsparses totalTime2s_evalModifier2s invalidFlags _evalString(sselfsdatetimeStrings sourceTimes totalTime2s tempTimeFlags totalTimesflags tempDateFlagschunk2schunk1smsssts invalidFlagsparseStr((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pysparses| %                                                   >2"    ." -+          c Cs|i} |i} |i}|o:yt|ƒ}Wnt j o d}nX| |7} n|oüyt|ƒ}Wnt j o d}nXt |ƒ}|d} |d}|djo3| |} | djo| d8} | d7} qn0| |} | djo| d7} | d8} n| | 7} ||ii| djo|ii| d}q_n|id| d| d|ƒ}|||SdS(s© Takes the given C{source} date, or current date if none is passed, and increments it according to the values passed in by month and/or year. This routine is needed because Python's C{timedelta()} function does not allow for month or year increments. @type source: struct_time @param source: C{struct_time} value to increment @type month: integer @param month: optional number of months to increment @type year: integer @param year: optional number of years to increment @rtype: datetime @return: C{source} incremented by the number of months and/or years ii isyearsmonthsdayN(ssourcesyearsyrsmonthsmthsdaysdysintsyis ValueErrorsmisabssmsysselfsptcsDaysInMonthListsreplacesd( sselfssourcesmonthsyearsyisdsmsdysmismthsysyr((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pysinc²s@                (s__name__s __module__s__doc__sNones__init__s_convertUnitAsWordss _buildTimes parseDates parseDateTexts evalRangess_CalculateDOWDeltas _evalModifiers_evalModifier2s _evalStringsparsesinc(((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pysCalendar³s   K J 6 Ÿ H ¿ J × ÿ4(s__doc__s __license__sFalses_debugsrestimesdatetimesrfc822sparsedatetime_constss _extract_dates _extract_times_parse_date_w3dtfs_parse_date_rfc822s_additional_timezoness _timezonessupdatesCalendar( s_additional_timezoness __license__s_debugsrfc822s_parse_date_rfc822sdatetimesresparsedatetime_constsstimes _extract_datesCalendars _extract_times_parse_date_w3dtf((s?build/bdist.darwin-8.0.1-x86/egg/parsedatetime/parsedatetime.pys?s      -  , 3PK{N6EÍòW¨¨parsedatetime/__init__.py""" parsedatetime.py contains the C{Calendar} class where the C{parse()} method can be found. parsedatetime_consts.py contains the C{Constants} class that builds the various regex values using locale information if available. """ version = '0.8.4' author = 'Mike Taylor and Darshana Chhajed' license = """ Copyright (c) 2004-2007 Mike Taylor Copyright (c) 2006-2007 Darshana Chhajed All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ PK‡V6ˆ\ë“uŒuŒ%parsedatetime/parsedatetime_consts.py#!/usr/bin/env python """ parsedatetime constants and helper functions to determine regex values from Locale information if present. Also contains the internal Locale classes to give some sane defaults if PyICU is not found. """ __license__ = """ Copyright (c) 2004-2007 Mike Taylor Copyright (c) 2006-2007 Darshana Chhajed All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ try: import PyICU as pyicu except: pyicu = None import datetime import time import re class pdtLocale_en: """ en_US Locale constants This class will be used to initialize L{Constants} if PyICU is not located. Defined as class variables are the lists and strings needed by parsedatetime to evaluate strings for USA """ localeID = 'en_US' # don't use a unicode string dateSep = [ u'/', u'.' ] timeSep = [ u':' ] meridian = [ u'AM', u'PM' ] usesMeridian = True uses24 = False Weekdays = [ u'monday', u'tuesday', u'wednesday', u'thursday', u'friday', u'saturday', u'sunday', ] shortWeekdays = [ u'mon', u'tues', u'wed', u'thu', u'fri', u'sat', u'sun', ] Months = [ u'january', u'february', u'march', u'april', u'may', u'june', u'july', u'august', u'september', u'october', u'november', u'december', ] shortMonths = [ u'jan', u'feb', u'mar', u'apr', u'may', u'jun', u'jul', u'aug', u'sep', u'oct', u'nov', u'dec', ] dateFormats = { 'full': 'EEEE, MMMM d, yyyy', 'long': 'MMMM d, yyyy', 'medium': 'MMM d, yyyy', 'short': 'M/d/yy', } timeFormats = { 'full': 'h:mm:ss a z', 'long': 'h:mm:ss a z', 'medium': 'h:mm:ss a', 'short': 'h:mm a', } dp_order = [ u'm', u'd', u'y' ] # this will be added to re_consts later units = { 'seconds': [ 'second', 'sec' ], 'minutes': [ 'minute', 'min' ], 'hours': [ 'hour', 'hr' ], 'days': [ 'day', 'dy' ], 'weeks': [ 'week', 'wk' ], 'months': [ 'month', 'mth' ], 'years': [ 'year', 'yr' ], } # text constants to be used by regex's later re_consts = { 'specials': 'in|on|of|at', 'timeseperator': ':', 'rangeseperator': '-', 'daysuffix': 'rd|st|nd|th', 'meridian': 'am|pm|a.m.|p.m.|a|p', 'qunits': 'h|m|s|d|w|m|y', 'now': [ 'now' ], } # Used to adjust the returned date before/after the source modifiers = { 'from': 1, 'before': -1, 'after': 1, 'ago': -1, 'prior': -1, 'prev': -1, 'last': -1, 'next': 1, 'this': 0, 'previous': -1, 'in a': 2, 'end of': 0, 'eod': 0, 'eo': 0 } dayoffsets = { 'tomorrow': 1, 'today': 0, 'yesterday': -1, } # special day and/or times, i.e. lunch, noon, evening # each element in the dictionary is a dictionary that is used # to fill in any value to be replace - the current date/time will # already have been populated by the method buildSources re_sources = { 'noon': { 'hr': 12, 'mn': 0, 'sec': 0 }, 'lunch': { 'hr': 12, 'mn': 0, 'sec': 0 }, 'morning': { 'hr': 6, 'mn': 0, 'sec': 0 }, 'breakfast': { 'hr': 8, 'mn': 0, 'sec': 0 }, 'dinner': { 'hr': 19, 'mn': 0, 'sec': 0 }, 'evening': { 'hr': 18, 'mn': 0, 'sec': 0 }, 'midnight': { 'hr': 0, 'mn': 0, 'sec': 0 }, 'night': { 'hr': 21, 'mn': 0, 'sec': 0 }, 'tonight': { 'hr': 21, 'mn': 0, 'sec': 0 }, 'eod': { 'hr': 17, 'mn': 0, 'sec': 0 }, } class pdtLocale_au: """ en_AU Locale constants This class will be used to initialize L{Constants} if PyICU is not located. Defined as class variables are the lists and strings needed by parsedatetime to evaluate strings for Australia """ localeID = 'en_AU' # don't use a unicode string dateSep = [ u'-', u'/' ] timeSep = [ u':' ] meridian = [ u'AM', u'PM' ] usesMeridian = True uses24 = False Weekdays = [ u'monday', u'tuesday', u'wednesday', u'thursday', u'friday', u'saturday', u'sunday', ] shortWeekdays = [ u'mon', u'tues', u'wed', u'thu', u'fri', u'sat', u'sun', ] Months = [ u'january', u'february', u'march', u'april', u'may', u'june', u'july', u'august', u'september', u'october', u'november', u'december', ] shortMonths = [ u'jan', u'feb', u'mar', u'apr', u'may', u'jun', u'jul', u'aug', u'sep', u'oct', u'nov', u'dec', ] dateFormats = { 'full': 'EEEE, d MMMM yyyy', 'long': 'd MMMM yyyy', 'medium': 'dd/MM/yyyy', 'short': 'd/MM/yy', } timeFormats = { 'full': 'h:mm:ss a z', 'long': 'h:mm:ss a', 'medium': 'h:mm:ss a', 'short': 'h:mm a', } dp_order = [ u'd', u'm', u'y' ] # this will be added to re_consts later units = { 'seconds': [ 'second', 'sec' ], 'minutes': [ 'minute', 'min' ], 'hours': [ 'hour', 'hr' ], 'days': [ 'day', 'dy' ], 'weeks': [ 'week', 'wk' ], 'months': [ 'month', 'mth' ], 'years': [ 'year', 'yr' ], } # text constants to be used by regex's later re_consts = { 'specials': 'in|on|of|at', 'timeseperator': ':', 'rangeseperator': '-', 'daysuffix': 'rd|st|nd|th', 'meridian': 'am|pm|a.m.|p.m.|a|p', 'qunits': 'h|m|s|d|w|m|y', 'now': [ 'now' ], } # Used to adjust the returned date before/after the source modifiers = { 'from': 1, 'before': -1, 'after': 1, 'ago': 1, 'prior': -1, 'prev': -1, 'last': -1, 'next': 1, 'this': 0, 'previous': -1, 'in a': 2, 'end of': 0, 'eo': 0, } dayoffsets = { 'tomorrow': 1, 'today': 0, 'yesterday': -1, } # special day and/or times, i.e. lunch, noon, evening # each element in the dictionary is a dictionary that is used # to fill in any value to be replace - the current date/time will # already have been populated by the method buildSources re_sources = { 'noon': { 'hr': 12, 'mn': 0, 'sec': 0 }, 'lunch': { 'hr': 12, 'mn': 0, 'sec': 0 }, 'morning': { 'hr': 6, 'mn': 0, 'sec': 0 }, 'breakfast': { 'hr': 8, 'mn': 0, 'sec': 0 }, 'dinner': { 'hr': 19, 'mn': 0, 'sec': 0 }, 'evening': { 'hr': 18, 'mn': 0, 'sec': 0 }, 'midnight': { 'hr': 0, 'mn': 0, 'sec': 0 }, 'night': { 'hr': 21, 'mn': 0, 'sec': 0 }, 'tonight': { 'hr': 21, 'mn': 0, 'sec': 0 }, 'eod': { 'hr': 17, 'mn': 0, 'sec': 0 }, } class pdtLocale_es: """ es Locale constants This class will be used to initialize L{Constants} if PyICU is not located. Defined as class variables are the lists and strings needed by parsedatetime to evaluate strings in Spanish Note that I don't speak Spanish so many of the items below are still in English """ localeID = 'es' # don't use a unicode string dateSep = [ u'/' ] timeSep = [ u':' ] meridian = [] usesMeridian = False uses24 = True Weekdays = [ u'lunes', u'martes', u'mi\xe9rcoles', u'jueves', u'viernes', u's\xe1bado', u'domingo', ] shortWeekdays = [ u'lun', u'mar', u'mi\xe9', u'jue', u'vie', u's\xe1b', u'dom', ] Months = [ u'enero', u'febrero', u'marzo', u'abril', u'mayo', u'junio', u'julio', u'agosto', u'septiembre', u'octubre', u'noviembre', u'diciembre' ] shortMonths = [ u'ene', u'feb', u'mar', u'abr', u'may', u'jun', u'jul', u'ago', u'sep', u'oct', u'nov', u'dic' ] dateFormats = { 'full': "EEEE d' de 'MMMM' de 'yyyy", 'long': "d' de 'MMMM' de 'yyyy", 'medium': "dd-MMM-yy", 'short': "d/MM/yy", } timeFormats = { 'full': "HH'H'mm' 'ss z", 'long': "HH:mm:ss z", 'medium': "HH:mm:ss", 'short': "HH:mm", } dp_order = [ u'd', u'm', u'y' ] # this will be added to re_consts later units = { 'seconds': [ 'second', 'sec' ], 'minutes': [ 'minute', 'min' ], 'hours': [ 'hour', 'hr' ], 'days': [ 'day', 'dy' ], 'weeks': [ 'week', 'wk' ], 'months': [ 'month', 'mth' ], 'years': [ 'year', 'yr' ], } # text constants to be used by regex's later re_consts = { 'specials': 'in|on|of|at', 'timeseperator': timeSep, 'dateseperator': dateSep, 'rangeseperator': '-', 'daysuffix': 'rd|st|nd|th', 'qunits': 'h|m|s|d|w|m|y', 'now': [ 'now' ], } # Used to adjust the returned date before/after the source modifiers = { 'from': 1, 'before': -1, 'after': 1, 'ago': 1, 'prior': -1, 'prev': -1, 'last': -1, 'next': 1, 'this': 0, 'previous': -1, 'in a': 2, 'end of': 0, 'eo': 0, } dayoffsets = { 'tomorrow': 1, 'today': 0, 'yesterday': -1, } # special day and/or times, i.e. lunch, noon, evening # each element in the dictionary is a dictionary that is used # to fill in any value to be replace - the current date/time will # already have been populated by the method buildSources re_sources = { 'noon': { 'hr': 12, 'mn': 0, 'sec': 0 }, 'lunch': { 'hr': 12, 'mn': 0, 'sec': 0 }, 'morning': { 'hr': 6, 'mn': 0, 'sec': 0 }, 'breakfast': { 'hr': 8, 'mn': 0, 'sec': 0 }, 'dinner': { 'hr': 19, 'mn': 0, 'sec': 0 }, 'evening': { 'hr': 18, 'mn': 0, 'sec': 0 }, 'midnight': { 'hr': 0, 'mn': 0, 'sec': 0 }, 'night': { 'hr': 21, 'mn': 0, 'sec': 0 }, 'tonight': { 'hr': 21, 'mn': 0, 'sec': 0 }, 'eod': { 'hr': 17, 'mn': 0, 'sec': 0 }, } pdtLocales = { 'en_US': pdtLocale_en, 'en_AU': pdtLocale_au, 'es': pdtLocale_es, } def _initLocale(ptc): """ Helper function to initialize the different lists and strings from either PyICU or one of the internal pdt Locales and store them into ptc. """ def lcase(x): return x.lower() if pyicu and ptc.usePyICU: ptc.icuLocale = None if ptc.localeID is not None: ptc.icuLocale = pyicu.Locale(ptc.localeID) if ptc.icuLocale is None: for id in range(0, len(ptc.fallbackLocales)): ptc.localeID = ptc.fallbackLocales[id] ptc.icuLocale = pyicu.Locale(ptc.localeID) if ptc.icuLocale is not None: break ptc.icuSymbols = pyicu.DateFormatSymbols(ptc.icuLocale) # grab ICU list of weekdays, skipping first entry which # is always blank wd = map(lcase, ptc.icuSymbols.getWeekdays()[1:]) swd = map(lcase, ptc.icuSymbols.getShortWeekdays()[1:]) # store them in our list with Monday first (ICU puts Sunday first) ptc.Weekdays = wd[1:] + wd[0:1] ptc.shortWeekdays = swd[1:] + swd[0:1] ptc.Months = map(lcase, ptc.icuSymbols.getMonths()) ptc.shortMonths = map(lcase, ptc.icuSymbols.getShortMonths()) # not quite sure how to init this so for now # set it to none so it will be set to the en_US defaults for now ptc.re_consts = None ptc.icu_df = { 'full': pyicu.DateFormat.createDateInstance(pyicu.DateFormat.kFull, ptc.icuLocale), 'long': pyicu.DateFormat.createDateInstance(pyicu.DateFormat.kLong, ptc.icuLocale), 'medium': pyicu.DateFormat.createDateInstance(pyicu.DateFormat.kMedium, ptc.icuLocale), 'short': pyicu.DateFormat.createDateInstance(pyicu.DateFormat.kShort, ptc.icuLocale), } ptc.icu_tf = { 'full': pyicu.DateFormat.createTimeInstance(pyicu.DateFormat.kFull, ptc.icuLocale), 'long': pyicu.DateFormat.createTimeInstance(pyicu.DateFormat.kLong, ptc.icuLocale), 'medium': pyicu.DateFormat.createTimeInstance(pyicu.DateFormat.kMedium, ptc.icuLocale), 'short': pyicu.DateFormat.createTimeInstance(pyicu.DateFormat.kShort, ptc.icuLocale), } ptc.dateFormats = { 'full': ptc.icu_df['full'].toPattern(), 'long': ptc.icu_df['long'].toPattern(), 'medium': ptc.icu_df['medium'].toPattern(), 'short': ptc.icu_df['short'].toPattern(), } ptc.timeFormats = { 'full': ptc.icu_tf['full'].toPattern(), 'long': ptc.icu_tf['long'].toPattern(), 'medium': ptc.icu_tf['medium'].toPattern(), 'short': ptc.icu_tf['short'].toPattern(), } else: if not ptc.localeID in pdtLocales: for id in range(0, len(ptc.fallbackLocales)): ptc.localeID = ptc.fallbackLocales[id] if ptc.localeID in pdtLocales: break ptc.locale = pdtLocales[ptc.localeID] ptc.usePyICU = False ptc.Weekdays = ptc.locale.Weekdays ptc.shortWeekdays = ptc.locale.shortWeekdays ptc.Months = ptc.locale.Months ptc.shortMonths = ptc.locale.shortMonths ptc.dateFormats = ptc.locale.dateFormats ptc.timeFormats = ptc.locale.timeFormats # these values are used to setup the various bits # of the regex values used to parse # # check if a local set of constants has been # provided, if not use en_US as the default if ptc.localeID in pdtLocales: ptc.re_sources = pdtLocales[ptc.localeID].re_sources ptc.re_values = pdtLocales[ptc.localeID].re_consts units = pdtLocales[ptc.localeID].units ptc.Modifiers = pdtLocales[ptc.localeID].modifiers ptc.dayOffsets = pdtLocales[ptc.localeID].dayoffsets # for now, pull over any missing keys from the US set for key in pdtLocales['en_US'].re_consts: if not key in ptc.re_values: ptc.re_values[key] = pdtLocales['en_US'].re_consts[key] else: ptc.re_sources = pdtLocales['en_US'].re_sources ptc.re_values = pdtLocales['en_US'].re_consts ptc.Modifiers = pdtLocales['en_US'].modifiers ptc.dayOffsets = pdtLocales['en_US'].dayoffsets units = pdtLocales['en_US'].units # escape any regex special characters that may be found wd = tuple(map(re.escape, ptc.Weekdays)) swd = tuple(map(re.escape, ptc.shortWeekdays)) mth = tuple(map(re.escape, ptc.Months)) smth = tuple(map(re.escape, ptc.shortMonths)) ptc.re_values['months'] = '%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s' % mth ptc.re_values['shortmonths'] = '%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s' % smth ptc.re_values['days'] = '%s|%s|%s|%s|%s|%s|%s' % wd ptc.re_values['shortdays'] = '%s|%s|%s|%s|%s|%s|%s' % swd l = [] for unit in units: l.append('|'.join(units[unit])) ptc.re_values['units'] = '|'.join(l) ptc.Units = ptc.re_values['units'].split('|') def _initSymbols(ptc): """ Helper function to initialize the single character constants and other symbols needed. """ ptc.timeSep = [ u':' ] ptc.dateSep = [ u'/' ] ptc.meridian = [ u'AM', u'PM' ] ptc.usesMeridian = True ptc.uses24 = False if pyicu and ptc.usePyICU: am = u'' pm = u'' ts = '' # ICU doesn't seem to provide directly the # date or time seperator - so we have to # figure it out o = ptc.icu_tf['short'] s = ptc.timeFormats['short'] ptc.usesMeridian = u'a' in s ptc.uses24 = u'H' in s # '11:45 AM' or '11:45' s = o.format(datetime.datetime(2003, 10, 30, 11, 45)) # ': AM' or ':' s = s.replace('11', '').replace('45', '') if len(s) > 0: ts = s[0] if ptc.usesMeridian: # '23:45 AM' or '23:45' am = s[1:].strip() s = o.format(datetime.datetime(2003, 10, 30, 23, 45)) if ptc.uses24: s = s.replace('23', '') else: s = s.replace('11', '') # 'PM' or '' pm = s.replace('45', '').replace(ts, '').strip() ptc.timeSep = [ ts ] ptc.meridian = [ am, pm ] o = ptc.icu_df['short'] s = o.format(datetime.datetime(2003, 10, 30, 11, 45)) s = s.replace('10', '').replace('30', '').replace('03', '').replace('2003', '') if len(s) > 0: ds = s[0] else: ds = '/' ptc.dateSep = [ ds ] s = ptc.dateFormats['short'] l = s.lower().split(ds) dp_order = [] for s in l: if len(s) > 0: dp_order.append(s[:1]) ptc.dp_order = dp_order else: ptc.timeSep = ptc.locale.timeSep ptc.dateSep = ptc.locale.dateSep ptc.meridian = ptc.locale.meridian ptc.usesMeridian = ptc.locale.usesMeridian ptc.uses24 = ptc.locale.uses24 ptc.dp_order = ptc.locale.dp_order # build am and pm lists to contain # original case, lowercase and first-char # versions of the meridian text if len(ptc.meridian) > 0: am = ptc.meridian[0] ptc.am = [ am ] if len(am) > 0: ptc.am.append(am[0]) am = am.lower() ptc.am.append(am) ptc.am.append(am[0]) else: am = '' ptc.am = [ '', '' ] if len(ptc.meridian) > 1: pm = ptc.meridian[1] ptc.pm = [ pm ] if len(pm) > 0: ptc.pm.append(pm[0]) pm = pm.lower() ptc.pm.append(pm) ptc.pm.append(pm[0]) else: pm = '' ptc.pm = [ '', '' ] def _initPatterns(ptc): """ Helper function to take the different localized bits from ptc and create the regex strings. """ # TODO add code to parse the date formats and build the regexes up from sub-parts # TODO find all hard-coded uses of date/time seperators # I refactored DATE3 to fix Issue 16 http://code.google.com/p/parsedatetime/issues/detail?id=16 # I suspect the final line was for a trailing time - but testing shows it's not needed # ptc.RE_DATE3 = r'''(?P((?P(%(months)s|%(shortmonths)s))\s? # ((?P\d\d?)(\s?|%(daysuffix)s|$)+)? # (,\s?(?P\d\d(\d\d)?))?)) # (\s?|$|[^0-9a-zA-Z])''' % ptc.re_values ptc.RE_DATE3 = r'''(?P((?P(%(months)s|%(shortmonths)s))\s? ((?P\d\d?)(?P%(daysuffix)s)?)? ((,)?(\s)?(?P\d\d(\d\d)?))? ) )''' % ptc.re_values ptc.RE_MONTH = r'''(\s?|^) (?P( (?P(%(months)s|%(shortmonths)s)) (\s?(?P(\d\d\d\d)))? )) (\s?|$|[^0-9a-zA-Z])''' % ptc.re_values ptc.RE_WEEKDAY = r'''(\s?|^) (?P(%(days)s|%(shortdays)s)) (\s?|$|[^0-9a-zA-Z])''' % ptc.re_values ptc.RE_SPECIAL = r'(?P^[%(specials)s]+)\s+' % ptc.re_values ptc.RE_UNITS = r'''(?P(-?\d+\s* (?P((%(units)s)s?)) ))''' % ptc.re_values ptc.RE_QUNITS = r'''(?P(-?\d+\s? (?P%(qunits)s) (\s?|,|$) ))''' % ptc.re_values ptc.RE_MODIFIER = r'''(\s?|^) (?P (previous|prev|last|next|this|eod|eo|(end\sof)|(in\sa)))''' % ptc.re_values ptc.RE_MODIFIER2 = r'''(\s?|^) (?P (from|before|after|ago|prior)) (\s?|$|[^0-9a-zA-Z])''' % ptc.re_values ptc.RE_TIMEHMS = r'''(\s?|^) (?P\d\d?) (?P%(timeseperator)s|) (?P\d\d) (?:(?P=tsep)(?P\d\d(?:[.,]\d+)?))?''' % ptc.re_values ptc.RE_TIMEHMS2 = r'''(?P(\d\d?)) ((?P%(timeseperator)s|) (?P(\d\d?)) (?:(?P=tsep) (?P\d\d? (?:[.,]\d+)?))?)?''' % ptc.re_values if 'meridian' in ptc.re_values: ptc.RE_TIMEHMS2 += r'\s?(?P(%(meridian)s))' % ptc.re_values dateSeps = ''.join(ptc.dateSep) + '.' ptc.RE_DATE = r'''(\s?|^) (?P(\d\d?[%s]\d\d?([%s]\d\d(\d\d)?)?)) (\s?|$|[^0-9a-zA-Z])''' % (dateSeps, dateSeps) ptc.RE_DATE2 = r'[%s]' % dateSeps ptc.RE_DAY = r'''(\s?|^) (?P(today|tomorrow|yesterday)) (\s?|$|[^0-9a-zA-Z])''' % ptc.re_values ptc.RE_TIME = r'''(\s?|^) (?P