public function testGuess() { $result = new Horde_Date_Parser_Result(null, null); $result->span = new Horde_Date_Span(new Horde_Date('2006-08-16 00:00:00'), new Horde_Date('2006-08-17 00:00:00')); $this->assertEquals(new Horde_Date('2006-08-16 12:00:00'), $result->guess()); $result->span = new Horde_Date_Span(new Horde_Date('2006-08-16 00:00:00'), new Horde_Date('2006-08-17 00:00:01')); $this->assertEquals(new Horde_Date('2006-08-16 12:00:00'), $result->guess()); $result->span = new Horde_Date_Span(new Horde_Date('2006-11-01 00:00:00'), new Horde_Date('2006-12-01 00:00:00')); $this->assertEquals(new Horde_Date('2006-11-16 00:00:00'), $result->guess()); }
/** # Parses a string containing a natural language date or time. If the parser # can find a date or time, either a Horde_Date or Horde_Date_Span will be returned # (depending on the value of <tt>:return</tt>). If no date or time can be found, # +nil+ will be returned. # # Options are: # # [<tt>:context</tt>] # <tt>:past</tt> or <tt>:future</tt> (defaults to <tt>:future</tt>) # # If your string represents a birthday, you can set <tt>:context</tt> to <tt>:past</tt> # and if an ambiguous string is given, it will assume it is in the # past. Specify <tt>:future</tt> or omit to set a future context. # # [<tt>:now</tt>] # Time (defaults to time()) # # By setting <tt>:now</tt> to a Horde_Date, all computations will be based off # of that time instead of time(). # # [<tt>:return</tt>] # 'result', 'span', or 'date' (defaults to 'date') # # By default, the parser will guess a single point in time for the # given date or time. If you'd rather have the entire time span returned, # set <tt>:return</tt> to 'span' and a Horde_Date_Span will be returned. # If you want the entire result, including tokens (for retrieving the text # that was or was not tagged, for example), set <tt>:return</tt> to 'result' # and you will get a result object. # # [<tt>:ambiguousTimeRange</tt>] # Integer or <tt>:none</tt> (defaults to <tt>6</tt> (6am-6pm)) # # If an Integer is given, ambiguous times (like 5:00) will be # assumed to be within the range of that time in the AM to that time # in the PM. For example, if you set it to <tt>7</tt>, then the parser will # look for the time between 7am and 7pm. In the case of 5:00, it would # assume that means 5:00pm. If <tt>:none</tt> is given, no assumption # will be made, and the first matching instance of that time will # be used. */ public function parse($text, $specifiedOptions = array()) { // get options and set defaults if necessary $defaultOptions = array('context' => 'future', 'now' => new Horde_Date(time()), 'return' => 'date', 'ambiguousTimeRange' => 6); $options = array_merge($defaultOptions, $this->args, $specifiedOptions); // ensure the specified options are valid foreach (array_keys($specifiedOptions) as $key) { if (!isset($defaultOptions[$key])) { throw new InvalidArgumentException("{$key} is not a valid option key"); } } if (!in_array($options['context'], array('past', 'future', 'none'))) { throw new InvalidArgumentException("Invalid value " . $options['context'] . " for 'context' specified. Valid values are 'past', 'future', and 'none'"); } // store now for later =) $this->now = $options['now']; // put the text into a normal format to ease scanning $text = $this->preNormalize($text); // get base tokens for each word $tokens = $this->preTokenize($text); // scan the tokens with each token scanner foreach (array('Repeater') as $tokenizer) { $tokenizer = $this->componentFactory($tokenizer); $tokens = $tokenizer->scan($tokens, $options); } foreach (array('Grabber', 'Pointer', 'Scalar', 'Ordinal', 'Separator', 'Timezone') as $tokenizer) { $tokenizer = $this->componentFactory($tokenizer); $tokens = $tokenizer->scan($tokens); } // strip any non-tagged tokens $taggedTokens = array_values(array_filter($tokens, create_function('$t', 'return $t->tagged();'))); // Remove tokens we know we don't want - for example, if the first token // is a separator, drop it. $taggedTokens = $this->postTokenize($taggedTokens); // do the heavy lifting $span = $this->tokensToSpan($taggedTokens, $options); // generate the result and return it, the span, or a guessed time within the span $result = new Horde_Date_Parser_Result($span, $tokens); switch ($options['return']) { case 'result': return $result; case 'span': return $result->span; case 'date': return $result->guess(); } }