def evalRanges(self, datetimeString, sourceTime=None):
rangeFlag = retFlag = <NUM_LIT:0><EOL>startStr = endStr = '<STR_LIT>'<EOL>s = datetimeString.strip().lower()<EOL>if self.ptc.rangeSep in s:<EOL><INDENT>s = s.replace(self.ptc.rangeSep, '<STR_LIT>' % self.ptc.rangeSep)<EOL>s = s.replace('<STR_LIT:U+0020>', '<STR_LIT:U+0020>')<EOL><DEDENT>for cre, rflag in [(self.ptc.CRE_TIMERNG1, <NUM_LIT:1>),<EOL>(self.ptc.CRE_TIMERNG2, <NUM_LIT:2>),<EOL>(self.ptc.CRE_TIMERNG4, <NUM_LIT:7>),<EOL>(self.ptc.CRE_TIMERNG3, <NUM_LIT:3>),<EOL>(self.ptc.CRE_DATERNG1, <NUM_LIT:4>),<EOL>(self.ptc.CRE_DATERNG2, <NUM_LIT:5>),<EOL>(self.ptc.CRE_DATERNG3, <NUM_LIT:6>)]:<EOL><INDENT>m = cre.search(s)<EOL>if m is not None:<EOL><INDENT>rangeFlag = rflag<EOL>break<EOL><DEDENT><DEDENT>debug and log.debug('<STR_LIT>', rangeFlag, s)<EOL>if m is not None:<EOL><INDENT>if (m.group() != s):<EOL><INDENT>parseStr = m.group()<EOL>chunk1 = s[:m.start()]<EOL>chunk2 = s[m.end():]<EOL>s = '<STR_LIT>' % (chunk1, chunk2)<EOL>sourceTime, ctx = self.parse(s, sourceTime,<EOL>VERSION_CONTEXT_STYLE)<EOL>if not ctx.hasDateOrTime:<EOL><INDENT>sourceTime = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>parseStr = s<EOL><DEDENT><DEDENT>if rangeFlag in (<NUM_LIT:1>, <NUM_LIT:2>):<EOL><INDENT>m = re.search(self.ptc.rangeSep, parseStr)<EOL>startStr = parseStr[:m.start()]<EOL>endStr = parseStr[m.start() + <NUM_LIT:1>:]<EOL>retFlag = <NUM_LIT:2><EOL><DEDENT>elif rangeFlag in (<NUM_LIT:3>, <NUM_LIT:7>):<EOL><INDENT>m = re.search(self.ptc.rangeSep, parseStr)<EOL>if self.ptc.usesMeridian:<EOL><INDENT>ampm = re.search(self.ptc.am[<NUM_LIT:0>], parseStr)<EOL>if ampm is not None:<EOL><INDENT>startStr = parseStr[:m.start()] + self.ptc.meridian[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>startStr = parseStr[:m.start()] + self.ptc.meridian[<NUM_LIT:1>]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>startStr = parseStr[:m.start()]<EOL><DEDENT>endStr = parseStr[m.start() + <NUM_LIT:1>:]<EOL>retFlag = <NUM_LIT:2><EOL><DEDENT>elif rangeFlag == <NUM_LIT:4>:<EOL><INDENT>m = re.search(self.ptc.rangeSep, parseStr)<EOL>startStr = parseStr[:m.start()]<EOL>endStr = parseStr[m.start() + <NUM_LIT:1>:]<EOL>retFlag = <NUM_LIT:1><EOL><DEDENT>elif rangeFlag == <NUM_LIT:5>:<EOL><INDENT>m = re.search(self.ptc.rangeSep, parseStr)<EOL>endStr = parseStr[m.start() + <NUM_LIT:1>:]<EOL>date = self.ptc.CRE_DATE3.search(endStr)<EOL>endYear = date.group('<STR_LIT>')<EOL>if endYear is not None:<EOL><INDENT>startStr = (parseStr[:m.start()]).strip()<EOL>date = self.ptc.CRE_DATE3.search(startStr)<EOL>startYear = date.group('<STR_LIT>')<EOL>if startYear is None:<EOL><INDENT>startStr = startStr + '<STR_LIT:U+002CU+0020>' + endYear<EOL><DEDENT><DEDENT>else:<EOL><INDENT>startStr = parseStr[:m.start()]<EOL><DEDENT>retFlag = <NUM_LIT:1><EOL><DEDENT>elif rangeFlag == <NUM_LIT:6>:<EOL><INDENT>m = re.search(self.ptc.rangeSep, parseStr)<EOL>startStr = parseStr[:m.start()]<EOL>mth = self.ptc.CRE_DATE3.search(startStr)<EOL>mth = mth.group('<STR_LIT>')<EOL>endStr = mth + parseStr[(m.start() + <NUM_LIT:1>):]<EOL>retFlag = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>startDT = endDT = time.localtime()<EOL><DEDENT>if retFlag:<EOL><INDENT>startDT, sctx = self.parse(startStr, sourceTime,<EOL>VERSION_CONTEXT_STYLE)<EOL>endDT, ectx = self.parse(endStr, sourceTime,<EOL>VERSION_CONTEXT_STYLE)<EOL>if not sctx.hasDateOrTime or not ectx.hasDateOrTime:<EOL><INDENT>retFlag = <NUM_LIT:0><EOL><DEDENT><DEDENT>return startDT, endDT, retFlag<EOL>
Evaluate the C{datetimeString} text and determine if
it represents a date or time range.

@type  datetimeString: string
@param datetimeString: datetime text to evaluate
@type  sourceTime:     struct_time
@param sourceTime:     C{struct_time} value to use as the base

@rtype:  tuple
@return: tuple of: start datetime, end datetime and the invalid flag