Parsing is starting to work with the base locale. BaseTest.php has some
authorChuck Hagenbuch <chuck@horde.org>
Sun, 8 Feb 2009 06:12:34 +0000 (01:12 -0500)
committerChuck Hagenbuch <chuck@horde.org>
Sun, 8 Feb 2009 06:12:34 +0000 (01:12 -0500)
examples, most of which work.

- tags have been completely revamped to simplify localization
- factored out the Tick class from the Time repeater
- removed more tests that have been fully ported
- removed unnecessary Tag subclasses
- added an includes() method to Horde_Date_Span

23 files changed:
framework/Date_Parser/chronic/test/test_Span.rb [deleted file]
framework/Date_Parser/chronic/test/test_Token.rb [deleted file]
framework/Date_Parser/lib/Horde/Date/Parser.php
framework/Date_Parser/lib/Horde/Date/Parser/Handler.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Grabber.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Ordinal.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/OrdinalDay.php [deleted file]
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Pointer.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Repeater.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Scalar.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Separator.php
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Timezone.php
framework/Date_Parser/lib/Horde/Date/Parser/Tag.php [deleted file]
framework/Date_Parser/lib/Horde/Date/Parser/Token.php
framework/Date_Parser/lib/Horde/Date/Repeater/Day.php
framework/Date_Parser/lib/Horde/Date/Repeater/DayPortion.php
framework/Date_Parser/lib/Horde/Date/Repeater/Time.php
framework/Date_Parser/lib/Horde/Date/Span.php
framework/Date_Parser/test/Horde/Date/Parser/Locale/BaseTest.php [new file with mode: 0644]
framework/Date_Parser/test/Horde/Date/Parser/TokenTest.php
framework/Date_Parser/test/Horde/Date/Repeater/TimeTest.php
framework/Date_Parser/test/Horde/Date/SpanTest.php

diff --git a/framework/Date_Parser/chronic/test/test_Span.rb b/framework/Date_Parser/chronic/test/test_Span.rb
deleted file mode 100644 (file)
index 099455a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-require 'chronic'
-require 'test/unit'
-
-class TestSpan < Test::Unit::TestCase
-  
-  def setup
-    # Wed Aug 16 14:00:00 UTC 2006
-    @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
-  end
-
-  def test_span_width
-    span = Chronic::Span.new(Time.local(2006, 8, 16, 0), Time.local(2006, 8, 17, 0))
-    assert_equal (60 * 60 * 24), span.width
-  end
-  
-  def test_span_math
-    s = Chronic::Span.new(1, 2)
-    assert_equal 2, (s + 1).begin
-    assert_equal 3, (s + 1).end
-    assert_equal 0, (s - 1).begin
-    assert_equal 1, (s - 1).end
-  end
-  
-end
\ No newline at end of file
diff --git a/framework/Date_Parser/chronic/test/test_Token.rb b/framework/Date_Parser/chronic/test/test_Token.rb
deleted file mode 100644 (file)
index 80463d1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-require 'chronic'
-require 'test/unit'
-
-class TestToken < Test::Unit::TestCase
-  
-  def setup
-    # Wed Aug 16 14:00:00 UTC 2006
-    @now = Time.local(2006, 8, 16, 14, 0, 0, 0)
-  end
-  
-  def test_token
-    token = Chronic::Token.new('foo')
-    assert_equal 0, token.tags.size
-    assert !token.tagged?
-    token.tag("mytag")
-    assert_equal 1, token.tags.size
-    assert token.tagged?
-    assert_equal String, token.get_tag(String).class
-    token.tag(5)
-    assert_equal 2, token.tags.size
-    token.untag(String)
-    assert_equal 1, token.tags.size
-    assert_equal 'foo', token.word
-  end
-  
-end
\ No newline at end of file
index 4a1b6d3..32fbd62 100644 (file)
@@ -4,8 +4,6 @@
  */
 class Horde_Date_Parser
 {
-    public static $debug = false;
-
     public static function parse($text, $args = array())
     {
         return self::factory($args)->parse($text, $args);
@@ -33,31 +31,4 @@ class Horde_Date_Parser
         return new Horde_Date_Parser_Locale_Base($args);
     }
 
-    /**
-     * @TODO this should be an instance method of one of the base classes, and
-     * should already known the locale
-     */
-    public static function componentFactory($component, $args = array())
-    {
-        $locale = isset($args['locale']) ? $args['locale'] : null;
-        if ($locale && strtolower($locale) != 'base') {
-            $locale = str_replace(' ', '_', ucwords(str_replace('_', ' ', strtolower($locale))));
-            $class = 'Horde_Date_Parser_Locale_' . $locale . '_' . $component;
-            if (class_exists($class)) {
-                return new $class($args);
-            }
-
-            $language = array_shift(explode('_', $locale));
-            if ($language != $locale) {
-                $class = 'Horde_Date_Parser_Locale_' . $language . '_' . $component;
-                if (class_exists($class)) {
-                    return new $class($args);
-                }
-            }
-        }
-
-        $class = 'Horde_Date_Parser_Locale_Base_' . $component;
-        return new $class($args);
-    }
-
 }
index 179f646..4bfbc69 100644 (file)
@@ -13,35 +13,31 @@ class Horde_Date_Parser_Handler
     public function match($tokens, $definitions)
     {
         $tokenIndex = 0;
-        foreach ($this->pattern as $element) {
-            $name = (string)$element;
+        foreach ($this->pattern as $name) {
             $optional = substr($name, -1) == '?';
             if ($optional) { $name = rtrim($name, '?'); }
-            /*
-        if element.instance_of? Symbol
-          klass = constantize(name)
-          match = tokens[token_index] && !tokens[token_index].tags.select { |o| o.kind_of?(klass) }.empty?
-          return false if !match && !optional
-          (token_index += 1; next) if match
-          next if !match && optional
-        elsif element.instance_of? String
-            */
-            if ($optional && $tokenIndex == count($tokens)) { return true; }
-            if (!isset($definitions[$name])) {
-                throw new Horde_Date_Parser_Exception("Invalid subset $name specified");
-            }
-            $subHandlers = $definitions[$name];
-            foreach ($subHandlers as $subHandler) {
-                if ($subHandler->match(array_slice($tokens, $tokenIndex), $definitions)) {
-                    return true;
+
+            $tag = substr($name, 0, 1) == ':';
+            if ($tag) {
+                $name = substr($name, 1);
+                //match = tokens[token_index] && !tokens[token_index].tags.select { |o| o.kind_of?(klass) }.empty?
+                $match = isset($tokens[$tokenIndex]) && $tokens[$tokenIndex]->getTag($name);
+                if (!$match && !$optional) { return false; }
+                if ($match) { $tokenIndex++; continue; }
+                if (!$match && $optional) { continue; }
+            } else {
+                if ($optional && $tokenIndex == count($tokens)) { return true; }
+                if (!isset($definitions[$name])) {
+                    throw new Horde_Date_Parser_Exception("Invalid subset $name specified");
+                }
+                $subHandlers = $definitions[$name];
+                foreach ($subHandlers as $subHandler) {
+                    if ($subHandler->match(array_slice($tokens, $tokenIndex), $definitions)) {
+                        return true;
+                    }
                 }
+                return false;
             }
-            return false;
-            /*
-        else
-          raise(ChronicPain, "Invalid match type: #{element.class}")
-        end
-            */
         }
 
         if ($tokenIndex != count($tokens)) { return false; }
index c243908..526b9fd 100644 (file)
@@ -2,6 +2,12 @@
 class Horde_Date_Parser_Locale_Base
 {
     public $definitions = array();
+    public $args = array();
+
+    public function __construct($args)
+    {
+        $this->args = $args;
+    }
 
     /**
     # Parses a string containing a natural language date or time. If the parser
@@ -47,7 +53,7 @@ class Horde_Date_Parser_Locale_Base
         // get options and set defaults if necessary
         $defaultOptions = array(
             'context' => 'future',
-            'now' => new Horde_Date,
+            'now' => new Horde_Date(time()),
             'guess' => true,
             'ambiguousTimeRange' => 6,
         );
@@ -87,12 +93,6 @@ class Horde_Date_Parser_Locale_Base
         // strip any non-tagged tokens
         $tokens = array_filter($tokens, create_function('$t', 'return $t->tagged();'));
 
-        if (Horde_Date_Parser::$debug) {
-            echo "+---------------------------------------------------\n";
-            echo "| " + implode(', ', $tokens) . "\n";
-            echo "+---------------------------------------------------\n";
-        }
-
         // do the heavy lifting
         $span = $this->tokensToSpan($tokens, $options);
 
@@ -105,6 +105,33 @@ class Horde_Date_Parser_Locale_Base
     }
 
     /**
+     * @TODO this should be an instance method of one of the base classes, and
+     * should already known the locale
+     */
+    public function componentFactory($component, $args = null)
+    {
+        $locale = isset($this->args['locale']) ? $this->args['locale'] : null;
+        if ($locale && strtolower($locale) != 'base') {
+            $locale = str_replace(' ', '_', ucwords(str_replace('_', ' ', strtolower($locale))));
+            $class = 'Horde_Date_Parser_Locale_' . $locale . '_' . $component;
+            if (class_exists($class)) {
+                return new $class($args);
+            }
+
+            $language = array_shift(explode('_', $locale));
+            if ($language != $locale) {
+                $class = 'Horde_Date_Parser_Locale_' . $language . '_' . $component;
+                if (class_exists($class)) {
+                    return new $class($args);
+                }
+            }
+        }
+
+        $class = 'Horde_Date_Parser_Locale_Base_' . $component;
+        return new $class($args);
+    }
+
+    /**
     # Clean up the specified input text by stripping unwanted characters,
     # converting idioms to their canonical form, converting number words
     # to numbers (three => 3), and converting ordinal words to numeric
@@ -112,26 +139,28 @@ class Horde_Date_Parser_Locale_Base
     */
     public function preNormalize($text)
     {
-        $normalizedText = strtolower($text);
-        $normalizedText = $this->numericizeNumbers($normalizedText);
-        $normalizedText = preg_replace('/[\'"\.]/', '', $normalizedText);
-        $normalizedText = preg_replace('/([\/\-\,\@])/', ' \1 ', $normalizedText);
-        $normalizedText = preg_replace('/\btoday\b/', 'this day', $normalizedText);
-        $normalizedText = preg_replace('/\btomm?orr?ow\b/', 'next day', $normalizedText);
-        $normalizedText = preg_replace('/\byesterday\b/', 'last day', $normalizedText);
-        $normalizedText = preg_replace('/\bnoon\b/', '12:00', $normalizedText);
-        $normalizedText = preg_replace('/\bmidnight\b/', '24:00', $normalizedText);
-        $normalizedText = preg_replace('/\bbefore now\b/', 'past', $normalizedText);
-        $normalizedText = preg_replace('/\bnow\b/', 'this second', $normalizedText);
-        $normalizedText = preg_replace('/\b(ago|before)\b/', 'past', $normalizedText);
-        $normalizedText = preg_replace('/\bthis past\b/', 'last', $normalizedText);
-        $normalizedText = preg_replace('/\bthis last\b/', 'last', $normalizedText);
-        $normalizedText = preg_replace('/\b(?:in|during) the (morning)\b/', '\1', $normalizedText);
-        $normalizedText = preg_replace('/\b(?:in the|during the|at) (afternoon|evening|night)\b/', '\1', $normalizedText);
-        $normalizedText = preg_replace('/\btonight\b/', 'this night', $normalizedText);
-        $normalizedText = preg_replace('/(?=\w)([ap]m|oclock)\b/', ' \1', $normalizedText);
-        $normalizedText = preg_replace('/\b(hence|after|from)\b/', 'future', $normalizedText);;
-        $normalizedText = $this->numericizeOrdinals($normalizedText);
+        $text = strtolower($text);
+        $text = $this->numericizeNumbers($text);
+        $text = preg_replace('/[\'"\.]/', '', $text);
+        $text = preg_replace('/([\/\-\,\@])/', ' \1 ', $text);
+        $text = preg_replace('/\btoday\b/', 'this day', $text);
+        $text = preg_replace('/\btomm?orr?ow\b/', 'next day', $text);
+        $text = preg_replace('/\byesterday\b/', 'last day', $text);
+        $text = preg_replace('/\bnoon\b/', '12:00', $text);
+        $text = preg_replace('/\bmidnight\b/', '24:00', $text);
+        $text = preg_replace('/\bbefore now\b/', 'past', $text);
+        $text = preg_replace('/\bnow\b/', 'this second', $text);
+        $text = preg_replace('/\b(ago|before)\b/', 'past', $text);
+        $text = preg_replace('/\bthis past\b/', 'last', $text);
+        $text = preg_replace('/\bthis last\b/', 'last', $text);
+        $text = preg_replace('/\b(?:in|during) the (morning)\b/', '\1', $text);
+        $text = preg_replace('/\b(?:in the|during the|at) (afternoon|evening|night)\b/', '\1', $text);
+        $text = preg_replace('/\btonight\b/', 'this night', $text);
+        $text = preg_replace('/(?=\w)([ap]m|oclock)\b/', ' \1', $text);
+        $text = preg_replace('/\b(hence|after|from)\b/', 'future', $text);;
+        $text = $this->numericizeOrdinals($text);
+
+        return $text;
     }
 
     /**
@@ -139,7 +168,7 @@ class Horde_Date_Parser_Locale_Base
      */
     public function numericizeNumbers($text)
     {
-        return Horde_Support_Numerizer::numerize($normalizedText, array('locale' => $this->locale));
+        return Horde_Support_Numerizer::numerize($text, $this->args);
     }
 
     /**
@@ -166,8 +195,8 @@ class Horde_Date_Parser_Locale_Base
         if (empty($span)) {
             return null;
         }
-        if ($span->width > 1) {
-            return $span->begin + ($span->width() / 2);
+        if ($span->width() > 1) {
+            return $span->begin->add($span->width() / 2);
         } else {
             return $span->begin;
         }
@@ -179,54 +208,53 @@ class Horde_Date_Parser_Locale_Base
 
         $this->definitions = array(
             'time' => array(
-                new Horde_Date_Parser_Handler(array('repeater_time', 'repeater_day_portion?'), null),
+                new Horde_Date_Parser_Handler(array(':repeater_time', ':repeater_day_portion?'), null),
             ),
 
             'date' => array(
-                new Horde_Date_Parser_Handler(array('repeater_day_name', 'repeater_month_name', 'scalar_day', 'repeater_time', 'time_zone', 'scalar_year'), 'handle_rdn_rmn_sd_t_tz_sy'),
-                new Horde_Date_Parser_Handler(array('repeater_month_name', 'scalar_day', 'scalar_year'), 'handle_rmn_sd_sy'),
-                new Horde_Date_Parser_Handler(array('repeater_month_name', 'scalar_day', 'scalar_year', 'separator_at?', 'time?'), 'handle_rmn_sd_sy'),
-                new Horde_Date_Parser_Handler(array('repeater_month_name', 'scalar_day', 'separator_at?', 'time?'), 'handle_rmn_sd'),
-                new Horde_Date_Parser_Handler(array('repeater_month_name', 'ordinal_day', 'separator_at?', 'time?'), 'handle_rmn_od'),
-                new Horde_Date_Parser_Handler(array('repeater_month_name', 'scalar_year'), 'handle_rmn_sy'),
-                new Horde_Date_Parser_Handler(array('scalar_day', 'repeater_month_name', 'scalar_year', 'separator_at?', 'time?'), 'handle_sd_rmn_sy'),
-                new Horde_Date_Parser_Handler(array('scalar_month', 'separator_slash_or_dash', 'scalar_day', 'separator_slash_or_dash', 'scalar_year', 'separator_at?', 'time?'), 'handle_sm_sd_sy'),
-                new Horde_Date_Parser_Handler(array('scalar_day', 'separator_slash_or_dash', 'scalar_month', 'separator_slash_or_dash', 'scalar_year', 'separator_at?', 'time?'), 'handle_sd_sm_sy'),
-                new Horde_Date_Parser_Handler(array('scalar_year', 'separator_slash_or_dash', 'scalar_month', 'separator_slash_or_dash', 'scalar_day', 'separator_at?', 'time?'), 'handle_sy_sm_sd'),
-                new Horde_Date_Parser_Handler(array('scalar_month', 'separator_slash_or_dash', 'scalar_year'), 'handle_sm_sy'),
+                new Horde_Date_Parser_Handler(array(':repeater_day_name', ':repeater_month_name', ':scalar_day', ':repeater_time', ':time_zone', ':scalar_year'), 'handle_rdn_rmn_sd_t_tz_sy'),
+                new Horde_Date_Parser_Handler(array(':repeater_month_name', ':scalar_day', ':scalar_year'), 'handle_rmn_sd_sy'),
+                new Horde_Date_Parser_Handler(array(':repeater_month_name', ':scalar_day', ':scalar_year', ':separator_at?', 'time?'), 'handle_rmn_sd_sy'),
+                new Horde_Date_Parser_Handler(array(':repeater_month_name', ':scalar_day', ':separator_at?', 'time?'), 'handle_rmn_sd'),
+                new Horde_Date_Parser_Handler(array(':repeater_month_name', ':ordinal_day', ':separator_at?', 'time?'), 'handle_rmn_od'),
+                new Horde_Date_Parser_Handler(array(':repeater_month_name', ':scalar_year'), 'handle_rmn_sy'),
+                new Horde_Date_Parser_Handler(array(':scalar_day', ':repeater_month_name', ':scalar_year', ':separator_at?', 'time?'), 'handle_sd_rmn_sy'),
+                new Horde_Date_Parser_Handler(array(':scalar_month', ':separator_slash_or_dash', ':scalar_day', ':separator_slash_or_dash', ':scalar_year', ':separator_at?', 'time?'), 'handle_sm_sd_sy'),
+                new Horde_Date_Parser_Handler(array(':scalar_day', ':separator_slash_or_dash', ':scalar_month', ':separator_slash_or_dash', ':scalar_year', ':separator_at?', 'time?'), 'handle_sd_sm_sy'),
+                new Horde_Date_Parser_Handler(array(':scalar_year', ':separator_slash_or_dash', ':scalar_month', ':separator_slash_or_dash', ':scalar_day', ':separator_at?', 'time?'), 'handle_sy_sm_sd'),
+                new Horde_Date_Parser_Handler(array(':scalar_month', ':separator_slash_or_dash', ':scalar_year'), 'handle_sm_sy'),
             ),
 
             // tonight at 7pm
             'anchor' => array(
-                new Horde_Date_Parser_Handler(array('grabber?', 'repeater', 'separator_at?', 'repeater?', 'repeater?'), 'handle_r'),
-                new Horde_Date_Parser_Handler(array('grabber?', 'repeater', 'repeater', 'separator_at?', 'repeater?', 'repeater?'), 'handle_r'),
-                new Horde_Date_Parser_Handler(array('repeater', 'grabber', 'repeater'), 'handle_r_g_r'),
+                new Horde_Date_Parser_Handler(array(':grabber?', ':repeater', ':separator_at?', ':repeater?', ':repeater?'), 'handle_r'),
+                new Horde_Date_Parser_Handler(array(':grabber?', ':repeater', ':repeater', ':separator_at?', ':repeater?', ':repeater?'), 'handle_r'),
+                new Horde_Date_Parser_Handler(array(':repeater', ':grabber', ':repeater'), 'handle_r_g_r'),
             ),
 
             // 3 weeks from now, in 2 months
             'arrow' => array(
-                new Horde_Date_Parser_Handler(array('scalar', 'repeater', 'pointer'), 'handle_s_r_p'),
-                new Horde_Date_Parser_Handler(array('pointer', 'scalar', 'repeater'), 'handle_p_s_r'),
-                new Horde_Date_Parser_Handler(array('scalar', 'repeater', 'pointer', 'anchor'), 'handle_s_r_p_a'),
+                new Horde_Date_Parser_Handler(array(':scalar', ':repeater', ':pointer'), 'handle_s_r_p'),
+                new Horde_Date_Parser_Handler(array(':pointer', ':scalar', ':repeater'), 'handle_p_s_r'),
+                new Horde_Date_Parser_Handler(array(':scalar', ':repeater', ':pointer', 'anchor'), 'handle_s_r_p_a'),
             ),
 
             // 3rd week in march
             'narrow' => array(
-                new Horde_Date_Parser_Handler(array('ordinal', 'repeater', 'separator_in', 'repeater'), 'handle_o_r_s_r'),
-                new Horde_Date_Parser_Handler(array('ordinal', 'repeater', 'grabber', 'repeater'), 'handle_o_r_g_r'),
+                new Horde_Date_Parser_Handler(array(':ordinal', ':repeater', ':separator_in', ':repeater'), 'handle_o_r_s_r'),
+                new Horde_Date_Parser_Handler(array(':ordinal', ':repeater', ':grabber', ':repeater'), 'handle_o_r_g_r'),
             ),
         );
     }
 
-    public function tokensToSpans($tokens, $options)
+    public function tokensToSpan($tokens, $options)
     {
         $this->initDefinitions();
 
         // maybe it's a specific date
         foreach ($this->definitions['date'] as $handler) {
             if ($handler->match($tokens, $this->definitions)) {
-                if (Horde_Date_Parser::$debug) { echo "-date\n"; }
-                $goodTokens = array_filter($tokens, create_function('$o', 'return !$o->getTag("Separator");'));
+                $goodTokens = array_filter($tokens, create_function('$o', 'return !$o->getTag("separator");'));
                 return call_user_func(array($this, $handler->handlerMethod), $goodTokens, $options);
             }
         }
@@ -234,8 +262,7 @@ class Horde_Date_Parser_Locale_Base
         // I guess it's not a specific date, maybe it's just an anchor
         foreach ($this->definitions['anchor'] as $handler) {
             if ($handler->match($tokens, $this->definitions)) {
-                if (Horde_Date_Parser::$debug) { echo "-anchor\n"; }
-                $goodTokens = array_filter($tokens, create_function('$o', 'return !$o->getTag("Separator");'));
+                $goodTokens = array_filter($tokens, create_function('$o', 'return !$o->getTag("separator");'));
                 return call_user_func(array($this, $handler->handlerMethod), $goodTokens, $options);
             }
         }
@@ -243,8 +270,7 @@ class Horde_Date_Parser_Locale_Base
         // not an anchor, perhaps it's an arrow
         foreach ($this->definitions['arrow'] as $handler) {
             if ($handler->match($tokens, $this->definitions)) {
-                if (Horde_Date_Parser::$debug) { echo "-arrow\n"; }
-                $goodTokens = array_filter($tokens, create_function('$o', 'return !$o->getTag("SeparatorAt") && !$o->getTag("SeparatorSlashOrDash") && !$o->getTag("SeparatorComma");'));
+                $goodTokens = array_filter($tokens, create_function('$o', 'return !$o->getTag("separator_at") && !$o->getTag("separator_slash_or_dash") && !$o->getTag("separator_comma");'));
                 return call_user_func(array($this, $handler->handlerMethod), $goodTokens, $options);
             }
         }
@@ -252,21 +278,19 @@ class Horde_Date_Parser_Locale_Base
         // not an arrow, let's hope it's a narrow
         foreach ($this->definitions['narrow'] as $handler) {
             if ($handler->match($tokens, $this->definitions)) {
-                if (Horde_Date_Parser::$debug) { echo "-narrow\n"; }
                 //good_tokens = tokens.select { |o| !o.get_tag Separator }
                 return call_user_func(array($this, $handler->handlerMethod), $tokens, $options);
             }
         }
 
         // I guess you're out of luck!
-        if (Horde_Date_Parser::$debug) { echo "-none\n"; }
         return null;
     }
 
 
     public function dayOrTime($dayStart, $timeTokens, $options)
     {
-        $outerSpan = new Horde_Date_Span($dayStart, $dayStart + (24 * 60 * 60));
+        $outerSpan = new Horde_Date_Span($dayStart, $dayStart->add(array('day' => 1)));
 
         if (!empty($timeTokens)) {
             $this->now = $outerSpan->begin;
@@ -288,18 +312,18 @@ class Horde_Date_Parser_Locale_Base
 
     public function handle_rmn_sd($tokens, $options)
     {
-        return $this->handle_m_d($tokens[0]->getTag('RepeaterMonthName'), $tokens[1]->getTag('ScalarDay')->type, array_slice($tokens, 2), $options);
+        return $this->handle_m_d($tokens[0]->getTag('repeater_month_name'), $tokens[1]->getTag('scalar_day'), array_slice($tokens, 2), $options);
     }
 
     public function handle_rmn_od($tokens, $options)
     {
-        return $this->handle_m_d($tokens[0]->getTag('RepeaterMonthName'), $tokens[1]->getTag('OrdinalDay')->type, array_slice($tokens, 2), $options);
+        return $this->handle_m_d($tokens[0]->getTag('repeater_month_name'), $tokens[1]->getTag('ordinal_day'), array_slice($tokens, 2), $options);
     }
 
     public function handle_rmn_sy($tokens, $options)
     {
-        $month = $tokens[0]->getTag('RepeaterMonthName')->index();
-        $year = $tokens[1]->getTag('ScalarYear')->type;
+        $month = $tokens[0]->getTag('repeater_month_name')->index();
+        $year = $tokens[1]->getTag('scalar_year');
 
         try {
             return new Horde_Date_Span(new Horde_Date(array('year' => $year, 'month' => $month)), new Horde_Date(array('year' => $year, 'month' => $month + 1)));
@@ -310,9 +334,9 @@ class Horde_Date_Parser_Locale_Base
 
     public function handle_rdn_rmn_sd_t_tz_sy($tokens, $options)
     {
-        $month = $tokens[1]->getTag('RepeaterMonthName')->index();
-        $day = $tokens[2]->getTag('ScalarDay')->type;
-        $year = $tokens[5]->getTag('ScalarYear')->type;
+        $month = $tokens[1]->getTag('repeater_month_name')->index();
+        $day = $tokens[2]->getTag('scalar_day');
+        $year = $tokens[5]->getTag('scalar_year');
 
         try {
             $dayStart = new Horde_Date(array('year' => $year, 'month' => $month, 'day' => $day));
@@ -324,9 +348,9 @@ class Horde_Date_Parser_Locale_Base
 
     public function handle_rmn_sd_sy($tokens, $options)
     {
-        $month = $tokens[0]->getTag('RepeaterMonthName')->index();
-        $day = $tokens[1]->getTag('ScalarDay')->type;
-        $year = $tokens[2]->getTag('ScalarYear')->type;
+        $month = $tokens[0]->getTag('repeater_month_name')->index();
+        $day = $tokens[1]->getTag('scalar_day');
+        $year = $tokens[2]->getTag('scalar_year');
 
         $timeTokens = array_slice($tokens, 3);
 
@@ -347,9 +371,9 @@ class Horde_Date_Parser_Locale_Base
 
     public function handle_sm_sd_sy($tokens, $options)
     {
-        $month = $tokens[0]->getTag('ScalarMonth')->type;
-        $day = $tokens[1]->getTag('ScalarDay')->type;
-        $year = $tokens[2]->getTag('ScalarYear')->type;
+        $month = $tokens[0]->getTag('scalar_month');
+        $day = $tokens[1]->getTag('scalar_day');
+        $year = $tokens[2]->getTag('scalar_year');
 
         $timeTokens = array_slice($tokens, 3);
 
@@ -377,8 +401,8 @@ class Horde_Date_Parser_Locale_Base
 
     public function handle_sm_sy($tokens, $options)
     {
-        $month = $tokens[0]->getTag('ScalarMonth')->type;
-        $year = $tokens[1]->getTag('ScalarYear')->type;
+        $month = $tokens[0]->getTag('scalar_month');
+        $year = $tokens[1]->getTag('scalar_year');
 
         try {
             return new Horde_Date_Span(new Horde_Date(array('year' => $year, 'month' => $month)), new Horde_Date(array('year' => $year, 'month' => $month = 1)));
@@ -411,9 +435,9 @@ class Horde_Date_Parser_Locale_Base
 
     public function handle_srp($tokens, $span, $options)
     {
-        $distance = $tokens[0]->getTag('Scalar')->type;
-        $repeater = $tokens[1]->getTag('Repeater');
-        $pointer = $tokens[2]->getTag('Pointer')->type;
+        $distance = $tokens[0]->getTag('scalar');
+        $repeater = $tokens[1]->getTag('repeater');
+        $pointer = $tokens[2]->getTag('pointer');
 
         return $repeater->offset($span, $distance, $pointer);
     }
@@ -443,9 +467,9 @@ class Horde_Date_Parser_Locale_Base
 
     public function handle_orr($tokens, $outerSpan, $options)
     {
-        $repeater = $tokens[1]->getTag('Repeater');
-        $repeater->now = $outerSpan->begin - 1;
-        $ordinal = $tokens[0]->getTag('Ordinal')->type;
+        $repeater = $tokens[1]->getTag('repeater');
+        $repeater->now = $outerSpan->begin->sub(1);
+        $ordinal = $tokens[0]->getTag('ordinal');
         $span = null;
 
         for ($i = 0; $i < $ordinal; $i++) {
@@ -477,7 +501,7 @@ class Horde_Date_Parser_Locale_Base
 
     public function getAnchor($tokens, $options)
     {
-        $grabber = $this->componentFactory('Grabber', array('this'));
+        $grabber = 'this';
         $pointer = 'future';
 
         $repeaters = $this->getRepeaters($tokens);
@@ -485,15 +509,15 @@ class Horde_Date_Parser_Locale_Base
             array_pop($tokens);
         }
 
-        if (count($tokens) && $tokens[0]->getTag('Grabber')) {
-            $grabber = $tokens[0]->getTag('Grabber');
+        if (count($tokens) && $tokens[0]->getTag('grabber')) {
+            $grabber = $tokens[0]->getTag('grabber');
             array_pop($tokens);
         }
 
         $head = array_shift($repeaters);
         $head->now = $this->now;
 
-        switch ($grabber->type) {
+        switch ($grabber) {
         case 'last':
             $outerSpan = $head->next('past');
             break;
@@ -511,10 +535,9 @@ class Horde_Date_Parser_Locale_Base
             break;
 
         default:
-            throw new Horde_Date_Parser_Exception('Invalid grabber ' . $grabber->type);
+            throw new Horde_Date_Parser_Exception('Invalid grabber ' . $grabber);
         }
 
-        if (Horde_Date_Parser::$debug) { echo "--$outerSpan\n"; }
         return $this->findWithin($repeaters, $outerSpan, $pointer);
     }
 
@@ -522,7 +545,7 @@ class Horde_Date_Parser_Locale_Base
     {
         $repeaters = array();
         foreach ($tokens as $token) {
-            if ($t = $token->getTag('Repeater')) {
+            if ($t = $token->getTag('repeater')) {
                 $repeaters[] = $t;
             }
         }
@@ -538,7 +561,6 @@ class Horde_Date_Parser_Locale_Base
      */
     public function findWithin($tags, $span, $pointer)
     {
-        if (Horde_Date_Parser::$debug) { echo "--$span\n"; }
         if (empty($tags)) { return $span; }
 
         $head = array_shift($tags);
@@ -546,7 +568,7 @@ class Horde_Date_Parser_Locale_Base
         $head->now = ($pointer == 'future') ? $span->begin : $span->end;
         $h = $head->this('none');
 
-        if ($span->include($h->begin) || $span->include($h->end)) {
+        if ($span->includes($h->begin) || $span->includes($h->end)) {
             return $this->findWithin($rest, $h, $pointer);
         } else {
             return null;
@@ -562,7 +584,7 @@ class Horde_Date_Parser_Locale_Base
     {
         $dayPortionIndex = null;
         foreach ($tokens as $i => $t) {
-            if ($t->getTag('RepeaterDayPortion')) {
+            if ($t->getTag('repeater_day_portion')) {
                 $dayPortionIndex = $i;
                 break;
             }
@@ -570,7 +592,7 @@ class Horde_Date_Parser_Locale_Base
 
         $timeIndex = null;
         foreach ($tokens as $i => $t) {
-            if ($t->getTag('RepeaterTime')) {
+            if ($t->getTag('repeater_time')) {
                 $timeIndex = $i;
                 break;
             }
@@ -578,45 +600,26 @@ class Horde_Date_Parser_Locale_Base
 
         if ($dayPortionIndex && $timeIndex) {
             $t1 = $tokens[$dayPortionIndex];
-            $t1tag = $t1->getTag('RepeaterDayPortion');
-
-            if ($t1tag->type == 'morning') {
-                if (Horde_Date_Parser::$debug) { echo "--morning->am\n"; }
-                $t1->untag('RepeaterDayPortion');
-                $t1->tag($this->componentFactory('RepeaterDayPortion', array('am')));
-            } elseif (in_array($t1tag->type, array('afternoon', 'evening', 'night'))) {
-                if (Horde_Date_Parser::$debug) { echo "--{$t1tag->type}->pm\n"; }
-                $t1->untag('RepeaterDayPortion');
-                $t1->tag($this->componentFactory('RepeaterDayPortion', array('pm')));
+            $t1tag = $t1->getTag('repeater_day_portion');
+
+            if ($t1tag == 'morning') {
+                $t1->untag('repeater_day_portion');
+                $t1->tag('repeater_day_portion', new Horde_Date_Repeater_DayPortion('am'));
+            } elseif (in_array($t1tag, array('afternoon', 'evening', 'night'))) {
+                $t1->untag('repeater_day_portion');
+                $t1->tag('repeater_day_portion', new Horde_Date_Repeater_DayPortion('pm'));
             }
         }
 
-        /*
-          # tokens.each_with_index do |t0, i|
-          #   t1 = tokens[i + 1]
-          #   if t1 && (t1tag = t1.get_tag(RepeaterDayPortion)) && t0.get_tag(RepeaterTime)
-          #     if [:morning].include?(t1tag.type)
-          #       puts '--morning->am' if Chronic.debug
-          #       t1.untag(RepeaterDayPortion)
-          #       t1.tag(RepeaterDayPortion.new(:am))
-          #     elsif [:afternoon, :evening, :night].include?(t1tag.type)
-          #       puts "--#{t1tag.type}->pm" if Chronic.debug
-          #       t1.untag(RepeaterDayPortion)
-          #       t1.tag(RepeaterDayPortion.new(:pm))
-          #     end
-          #   end
-          # end
-        */
-
-        // handle ambiguous times if :ambiguousTimeRange is specified
+        // handle ambiguous times if ambiguousTimeRange is specified
         if ($options['ambiguousTimeRange'] != 'none') {
             $ttokens = array();
             foreach ($tokens as $i => $t0) {
                 $ttokens[] = $t0;
                 $t1 = isset($tokens[$i + 1]) ? $tokens[$i + 1] : null;
-                if ($t0->getTag('RepeaterTime') && $t0->getTag('RepeaterTime')->type->ambiguous() && (!$t1 || !$t1->getTag('RepeaterDayPortion'))) {
+                if ($t0->getTag('repeater_time') && $t0->getTag('repeater_time')->ambiguous && (!$t1 || !$t1->getTag('repeater_day_portion'))) {
                     $distoken = new Horde_Date_Parser_Token('disambiguator');
-                    $distoken->tag($this->componentFactory('RepeaterDayPortion', array($options['ambiguousTimeRange'])));
+                    $distoken->tag('repeater_day_portion', new Horde_Date_Repeater_DayPortion($options['ambiguousTimeRange']));
                     $ttokens[] = $distoken;
                 }
             }
index ba81bd6..b5b33c6 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class Horde_Date_Parser_Locale_Base_Grabber extends Horde_Date_Parser_Tag
+class Horde_Date_Parser_Locale_Base_Grabber
 {
     /**
      * Regex tokens
@@ -14,7 +14,7 @@ class Horde_Date_Parser_Locale_Base_Grabber extends Horde_Date_Parser_Tag
     {
         foreach ($tokens as &$token) {
             if ($t = $this->scanForAll($token)) {
-                $token->tag($t);
+                $token->tag('grabber', $t);
             }
         }
         return $tokens;
@@ -24,14 +24,9 @@ class Horde_Date_Parser_Locale_Base_Grabber extends Horde_Date_Parser_Tag
     {
         foreach ($this->scanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                return new self($scannerTag);
+                return $scannerTag;
             }
         }
     }
 
-    public function __toString()
-    {
-        return 'grabber-' . $this->type;
-    }
-
 }
index 710f793..f9dde86 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class Horde_Date_Parser_Locale_Base_Ordinal extends Horde_Date_Parser_Tag
+class Horde_Date_Parser_Locale_Base_Ordinal
 {
     public $ordinalRegex = '/^(\d*)(st|nd|rd|th)$/';
     public $ordinalDayRegex = '/^(\d*)(st|nd|rd|th)$/';
@@ -7,11 +7,11 @@ class Horde_Date_Parser_Locale_Base_Ordinal extends Horde_Date_Parser_Tag
     public function scan($tokens)
     {
         foreach ($tokens as &$token) {
-            if ($t = $this->scanForOrdinals($token)) {
-                $token->tag($t);
+            if (!is_null($t = $this->scanForOrdinals($token))) {
+                $token->tag('ordinal', $t);
             }
-            if ($t = $this->scanForDays($token)) {
-                $token->tag($t);
+            if (!is_null($t = $this->scanForDays($token))) {
+                $token->tag('ordinal_day', $t);
             }
         }
 
@@ -21,7 +21,7 @@ class Horde_Date_Parser_Locale_Base_Ordinal extends Horde_Date_Parser_Tag
     public function scanForOrdinals($token)
     {
         if (preg_match($this->ordinalRegex, $token->word, $matches)) {
-            return new self((int)$matches[1]);
+            return (int)$matches[1];
         }
     }
 
@@ -29,15 +29,9 @@ class Horde_Date_Parser_Locale_Base_Ordinal extends Horde_Date_Parser_Tag
     {
         if (preg_match($this->ordinalDayRegex, $token->word, $matches)) {
             if ($matches[1] <= 31) {
-                /* FIXME - hardcoded class name */
-                return new Horde_Date_Parser_Locale_Base_OrdinalDay((int)$m[1]);
+                return (int)$matches[1];
             }
         }
     }
 
-    public function __toString()
-    {
-        return 'ordinal';
-    }
-
 }
diff --git a/framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/OrdinalDay.php b/framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/OrdinalDay.php
deleted file mode 100644 (file)
index 8cf8626..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?php
-class Horde_Date_Parser_Locale_Base_OrdinalDay extends Horde_Date_Parser_Locale_Base_Ordinal
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-day-' . $this->type;
-    }
-
-}
index 9a54883..c4b83b8 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class Horde_Date_Parser_Locale_Base_Pointer extends Horde_Date_Parser_Tag
+class Horde_Date_Parser_Locale_Base_Pointer
 {
     public $scanner = array(
         '/\bpast\b/' => 'past',
@@ -11,7 +11,7 @@ class Horde_Date_Parser_Locale_Base_Pointer extends Horde_Date_Parser_Tag
     {
         foreach ($tokens as &$token) {
             if ($t = $this->scanForAll($token)) {
-                $token->tag($t);
+                $token->tag('pointer', $t);
             }
         }
         return $tokens;
@@ -21,14 +21,9 @@ class Horde_Date_Parser_Locale_Base_Pointer extends Horde_Date_Parser_Tag
     {
         foreach ($this->scanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                return new self($scannerTag);
+                return $scannerTag;
             }
         }
     }
 
-    public function __toString()
-    {
-        return 'pointer-' . $this->type;
-    }
-
 }
index d63c136..5806193 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class Horde_Date_Parser_Locale_Base_Repeater extends Horde_Date_Parser_Tag
+class Horde_Date_Parser_Locale_Base_Repeater
 {
     public $monthNameScanner = array(
         '/^jan\.?(uary)?$/' => 'january',
@@ -57,15 +57,15 @@ class Horde_Date_Parser_Locale_Base_Repeater extends Horde_Date_Parser_Tag
     {
         foreach ($tokens as &$token) {
             if ($t = $this->scanForMonthNames($token)) {
-                $token->tag($t);
+                $token->tag('repeater_month_name', $t);
             } elseif ($t = $this->scanForDayNames($token)) {
-                $token->tag($t);
+                $token->tag('repeater_day_name', $t);
             } elseif ($t = $this->scanForDayPortions($token)) {
-                $token->tag($t);
+                $token->tag('repeater_day_portion', $t);
             } elseif ($t = $this->scanForTimes($token, $options)) {
-                $token->tag($t);
+                $token->tag('repeater_time', $t);
             } elseif ($t = $this->scanForUnits($token)) {
-                $token->tag($t);
+                $token->tag(strtolower(str_replace('Horde_Date_', '', get_class($t))), $t);
             }
         }
         return $tokens;
@@ -75,7 +75,7 @@ class Horde_Date_Parser_Locale_Base_Repeater extends Horde_Date_Parser_Tag
     {
         foreach ($this->monthNameScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                return new Horde_Date_Parser_Locale_Base_Repeater_MonthName($scannerTag);
+                return new Horde_Date_Repeater_MonthName($scannerTag);
             }
         }
     }
@@ -84,7 +84,7 @@ class Horde_Date_Parser_Locale_Base_Repeater extends Horde_Date_Parser_Tag
     {
         foreach ($this->dayNameScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                return new Horde_Date_Parser_Locale_Base_Repeater_DayName($scannerTag);
+                return new Horde_Date_Repeater_DayName($scannerTag);
             }
         }
     }
@@ -93,7 +93,7 @@ class Horde_Date_Parser_Locale_Base_Repeater extends Horde_Date_Parser_Tag
     {
         foreach ($this->dayPortionScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                return new Horde_Date_Parser_Locale_Base_Repeater_DayPortion($scannerTag);
+                return new Horde_Date_Repeater_DayPortion($scannerTag);
             }
         }
     }
@@ -101,15 +101,15 @@ class Horde_Date_Parser_Locale_Base_Repeater extends Horde_Date_Parser_Tag
     public function scanForTimes($token, $options)
     {
         if (preg_match($this->timeRegex, $token->word)) {
-            return new Horde_Date_Parser_Locale_Base_Repeater_Time($token->word, $options);
+            return new Horde_Date_Repeater_Time($token->word, $options);
         }
     }
 
     public function scanForUnits($token)
     {
-        foreach ($this->uniScanner as $scannerItem => $scannerTag) {
+        foreach ($this->unitScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                $class = 'Horde_Date_Parser_Locale_Base_Repeater_' . ucfirst($scannerTag);
+                $class = 'Horde_Date_Repeater_' . ucfirst($scannerTag);
                 return new $class($scannerTag);
             }
         }
index 5403882..0130dc3 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class Horde_Date_Parser_Locale_Base_Scalar extends Horde_Date_Parser_Tag
+class Horde_Date_Parser_Locale_Base_Scalar
 {
     public $scalarRegex = '/^\d*$/';
     public $dayRegex = '/^\d\d?$/';
@@ -10,18 +10,18 @@ class Horde_Date_Parser_Locale_Base_Scalar extends Horde_Date_Parser_Tag
     public function scan($tokens)
     {
         foreach ($tokens as $i => &$token) {
-            $postToken = isset($tokens[$i + 1]) ? $tokens[$i + 1] : null;
-            if ($t = $this->scanForScalars($token, $postToken)) {
-                $token->tag($t);
+            $postToken = isset($tokens[$i + 1]) ? $tokens[$i + 1]->word : null;
+            if (!is_null($t = $this->scanForScalars($token, $postToken))) {
+                $token->tag('scalar', $t);
             }
-            if ($t = $this->scanForDays($token, $postToken)) {
-                $token->tag($t);
+            if (!is_null($t = $this->scanForDays($token, $postToken))) {
+                $token->tag('scalar_day', $t);
             }
-            if ($t = $this->scanForMonths($token, $postToken)) {
-                $token->tag($t);
+            if (!is_null($t = $this->scanForMonths($token, $postToken))) {
+                $token->tag('scalar_month', $t);
             }
-            if ($t = $this->scanForYears($token, $postToken)) {
-                $token->tag($t);
+            if (!is_null($t = $this->scanForYears($token, $postToken))) {
+                $token->tag('scalar_year', $t);
             }
         }
         return $tokens;
@@ -31,7 +31,7 @@ class Horde_Date_Parser_Locale_Base_Scalar extends Horde_Date_Parser_Tag
     {
         if (preg_match($this->scalarRegex, $token->word)) {
             if (!in_array($postToken, $this->timeSignifiers)) {
-                return new self((int)$token->word);
+                return (int)$token->word;
             }
         }
     }
@@ -40,7 +40,7 @@ class Horde_Date_Parser_Locale_Base_Scalar extends Horde_Date_Parser_Tag
     {
         if (preg_match($this->dayRegex, $token->word)) {
             if ((int)$token->word <= 31 && !in_array($postToken, $this->timeSignifiers)) {
-                return new Horde_Date_Parser_Locale_Base_ScalarDay((int)$token->word);
+                return (int)$token->word;
             }
         }
     }
@@ -49,7 +49,7 @@ class Horde_Date_Parser_Locale_Base_Scalar extends Horde_Date_Parser_Tag
     {
         if (preg_match($this->monthRegex, $token->word)) {
             if ((int)$token->word <= 12 && !in_array($postToken, $this->timeSignifiers)) {
-                return new Horde_Date_Parser_Locale_Base_ScalarMonth((int)$token->word);
+                return (int)$token->word;
             }
         }
     }
@@ -58,41 +58,9 @@ class Horde_Date_Parser_Locale_Base_Scalar extends Horde_Date_Parser_Tag
     {
         if (preg_match($this->yearRegex, $token->word)) {
             if (!in_array($postToken, $this->timeSignifiers)) {
-                return new Horde_Date_Parser_Locale_Base_ScalarYear((int)$token->word);
+                return (int)$token->word;
             }
         }
     }
 
-    public function __toString()
-    {
-        return 'scalar';
-    }
-
-}
-
-class Horde_Date_Parser_Locale_Base_ScalarDay extends Horde_Date_Parser_Locale_Base_Scalar
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-day-' . $this->type;
-    }
-
-}
-
-class Horde_Date_Parser_Locale_Base_ScalarMonth extends Horde_Date_Parser_Locale_Base_Scalar
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-month-' . $this->type;
-    }
-
-}
-
-class Horde_Date_Parser_Locale_Base_ScalarYear extends Horde_Date_Parser_Locale_Base_Scalar
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-year-' . $this->type;
-    }
-
 }
index 6914bfa..47e9826 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class Horde_Date_Parser_Locale_Base_Separator extends Horde_Date_Parser_Tag
+class Horde_Date_Parser_Locale_Base_Separator
 {
     public $commaScanner = array(
         '/^,$/' => 'comma',
@@ -22,13 +22,13 @@ class Horde_Date_Parser_Locale_Base_Separator extends Horde_Date_Parser_Tag
     {
         foreach ($tokens as &$token) {
             if ($t = $this->scanForCommas($token)) {
-                $token->tag($t);
+                $token->tag('separator_comma', $t);
             } elseif ($t = $this->scanForSlashOrDash($token)) {
-                $token->tag($t);
+                $token->tag('separator_slash_or_dash', $t);
             } elseif ($t = $this->scanForAt($token)) {
-                $token->tag($t);
+                $token->tag('separator_at', $t);
             } elseif ($t = $this->scanForIn($token)) {
-                $token->tag($t);
+                $token->tag('separator_in', $t);
             }
         }
         return $tokens;
@@ -38,8 +38,7 @@ class Horde_Date_Parser_Locale_Base_Separator extends Horde_Date_Parser_Tag
     {
         foreach ($this->commaScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                /* FIXME */
-                return new Horde_Date_Parser_Locale_Base_SeparatorComma($scannerTag);
+                return $scannerTag;
             }
         }
     }
@@ -48,8 +47,7 @@ class Horde_Date_Parser_Locale_Base_Separator extends Horde_Date_Parser_Tag
     {
         foreach ($this->slashOrDashScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                /* FIXME */
-                return new Horde_Date_Parser_Locale_Base_SeparatorSlashOrDash($scannerTag);
+                return $scannerTag;
             }
         }
     }
@@ -58,8 +56,7 @@ class Horde_Date_Parser_Locale_Base_Separator extends Horde_Date_Parser_Tag
     {
         foreach ($this->atScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                /* FIXME */
-                return new Horde_Date_Parser_Locale_Base_SeparatorAt($scannerTag);
+                return $scannerTag;
             }
         }
     }
@@ -68,51 +65,9 @@ class Horde_Date_Parser_Locale_Base_Separator extends Horde_Date_Parser_Tag
     {
         foreach ($this->inScanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                /* FIXME */
-                return new Horde_Date_Parser_Locale_Base_SeparatorIn($scannerTag);
+                return $scannerTag;
             }
         }
     }
 
-    public function __toString()
-    {
-        return 'separator';
-    }
-
-}
-
-class Horde_Date_Parser_Locale_Base_SeparatorComma extends Horde_Date_Parser_Locale_Base_Separator
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-comma';
-    }
-
-}
-
-class Horde_Date_Parser_Locale_Base_SeparatorSlashOrDash extends Horde_Date_Parser_Locale_Base_Separator
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-slashordash-' . $this->type;
-    }
-
-}
-
-class Horde_Date_Parser_Locale_Base_SeparatorAt extends Horde_Date_Parser_Locale_Base_Separator
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-at';
-    }
-
-}
-
-class Horde_Date_Parser_Locale_Base_SeparatorIn extends Horde_Date_Parser_Locale_Base_Separator
-{
-    public function __toString()
-    {
-        return parent::__toString() . '-in';
-    }
-
 }
index bd7d155..d4651f6 100644 (file)
@@ -1,5 +1,5 @@
 <?php
-class Horde_Date_Parser_Locale_Base_Timezone extends Horde_Date_Parser_Tag
+class Horde_Date_Parser_Locale_Base_Timezone
 {
     public $scanner = array(
         '/[PMCE][DS]T/i' => 'tz',
@@ -9,7 +9,7 @@ class Horde_Date_Parser_Locale_Base_Timezone extends Horde_Date_Parser_Tag
     {
         foreach ($tokens as &$token) {
             if ($t = $this->scanForAll($token)) {
-                $token->tag($t);
+                $token->tag('timezone', $t);
             }
         }
         return $tokens;
@@ -19,14 +19,9 @@ class Horde_Date_Parser_Locale_Base_Timezone extends Horde_Date_Parser_Tag
     {
         foreach ($this->scanner as $scannerItem => $scannerTag) {
             if (preg_match($scannerItem, $token->word)) {
-                return new self($scannerTag);
+                return $scannerTag;
             }
         }
     }
 
-    public function __toString()
-    {
-        return 'timezone';
-    }
-
 }
diff --git a/framework/Date_Parser/lib/Horde/Date/Parser/Tag.php b/framework/Date_Parser/lib/Horde/Date/Parser/Tag.php
deleted file mode 100644 (file)
index af46685..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
-/**
- */
-
-/**
- * Tokens are tagged with subclassed instances of this class when they match
- * specific criteria.
- */
-class Horde_Date_Parser_Tag
-{
-    public $type;
-    public $now;
-
-    public function __construct($type)
-    {
-        $this->type = $type;
-    }
-
-}
index 9019d25..ec2542f 100644 (file)
@@ -13,9 +13,9 @@ class Horde_Date_Parser_Token
     /**
      * Tag this token with the specified tag
      */
-    public function tag($tag)
+    public function tag($tagClass, $tag)
     {
-        $this->tags[] = $tag;
+        $this->tags[] = array($tagClass, $tag);
     }
 
     /**
@@ -23,7 +23,7 @@ class Horde_Date_Parser_Token
      */
     public function untag($tagClass)
     {
-        $this->tags = array_filter($this->tags, create_function('$t', 'return $t instanceof ' . $tagClass . ';'));
+        $this->tags = array_filter($this->tags, create_function('$t', 'return substr($t[0], 0, ' . strlen($tagClass) . ') != "' . $tagClass . '";'));
     }
 
     /**
@@ -39,8 +39,9 @@ class Horde_Date_Parser_Token
      */
     public function getTag($tagClass)
     {
-        $matches = array_filter($this->tags, create_function('$t', 'return $t instanceof ' . $tagClass . ';'));
-        return array_shift($matches);
+        $matches = array_filter($this->tags, create_function('$t', 'return substr($t[0], 0, ' . strlen($tagClass) . ') == "' . $tagClass . '";'));
+        $match = array_shift($matches);
+        return $match[1];
     }
 
     /**
index 6b6ef05..08cad13 100644 (file)
@@ -29,18 +29,18 @@ class Horde_Date_Repeater_Day extends Horde_Date_Repeater
 
         switch ($pointer) {
         case 'future':
-            $dayBegin = new Horde_Date(array('year' => $now->year, 'month' => $now->month, 'day' => $now->day, 'hour' => $now->hour + 1));
-            $dayEnd = new Horde_Date(array('year' => $now->year, 'month' => $now->month, 'day' => $now->day + 1));
+            $dayBegin = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'hour' => $this->now->hour + 1));
+            $dayEnd = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day + 1));
             break;
 
         case 'past':
-            $dayBegin = new Horde_Date(array('year' => $now->year, 'month' => $now->month, 'day' => $now->day));
-            $dayBegin = new Horde_Date(array('year' => $now->year, 'month' => $now->month, 'day' => $now->day, 'hour' => $now->hour));
+            $dayBegin = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day));
+            $dayBegin = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'hour' => $this->now->hour));
             break;
 
         case 'none':
-            $dayBegin = new Horde_Date(array('year' => $now->year, 'month' => $now->month, 'day' => $now->day));
-            $dayEnd = new Horde_Date(array('year' => $now->year, 'month' => $now->month, 'day' => $now->day + 1));
+            $dayBegin = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day));
+            $dayEnd = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day + 1));
             break;
         }
 
index ec872fd..36ff50d 100644 (file)
@@ -106,7 +106,7 @@ class Horde_Date_Repeater_DayPortion extends Horde_Date_Repeater
 
     public function this($context = 'future')
     {
-        parent::super($context);
+        parent::this($context);
 
         $rangeStart = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day, 'sec' => $this->range[0]));
         $rangeEnd = new Horde_Date(array('year' => $rangeStart->year, 'month' => $rangeStart->month, 'day' => $rangeStart->day, 'sec' => $this->range[1] - $this->range[0]));
index 2afd38f..405cd66 100644 (file)
@@ -3,6 +3,7 @@ class Horde_Date_Repeater_Time extends Horde_Date_Repeater
 {
     public $currentTime;
     public $type;
+    public $ambiguous;
 
     public function __construct($time, $options = array())
     {
@@ -12,33 +13,34 @@ class Horde_Date_Repeater_Time extends Horde_Date_Repeater
         case 1:
         case 2:
             $hours = (int)$t;
-            $this->type = ($hours == 12) ?
-                new Horde_Date_Tick(0, true) :
-                new Horde_Date_Tick($hours * 3600, true);
+            $this->ambiguous = true;
+            $this->type = ($hours == 12) ? 0 : $hours * 3600;
             break;
 
         case 3:
-            $this->type = new Horde_Date_Tick($t[0] * 3600 + (int)substr($t, 1, 2) * 60, true);
+            $this->ambiguous = true;
+            $this->type = $t[0] * 3600 + (int)substr($t, 1, 2) * 60;
             break;
 
         case 4:
-            $ambiguous = (strpos($time, ':') !== false) && ($t[0] != 0) && ((int)substr($t, 0, 2) <= 12);
+            $this->ambiguous = (strpos($time, ':') !== false) && ($t[0] != 0) && ((int)substr($t, 0, 2) <= 12);
             $hours = (int)substr($t, 0, 2);
             $this->type = ($hours == 12) ?
-                new Horde_Date_Tick((int)substr($t, 2, 2) * 60, $ambiguous) :
-                new Horde_Date_Tick($hours * 60 * 60 + (int)substr($t, 2, 2) * 60, $ambiguous);
+                ((int)substr($t, 2, 2) * 60) :
+                ($hours * 60 * 60 + (int)substr($t, 2, 2) * 60);
             break;
 
         case 5:
-            $this->type = new Horde_Date_Tick($t[0] * 3600 + (int)substr($t, 1, 2) * 60 + (int)substr($t, 3, 2), true);
+            $this->ambiguous = true;
+            $this->type = $t[0] * 3600 + (int)substr($t, 1, 2) * 60 + (int)substr($t, 3, 2);
             break;
 
         case 6:
-            $ambiguous = (strpos($time, ':') !== false) && ($t[0] != 0) && ((int)substr($t, 0, 2) <= 12);
+            $this->ambiguous = (strpos($time, ':') !== false) && ($t[0] != 0) && ((int)substr($t, 0, 2) <= 12);
             $hours = (int)substr($t, 0, 2);
             $this->type = ($hours == 12) ?
-                new Horde_Date_Tick((int)substr($t, 2, 2) * 60 + (int)substr($t, 4, 2), $ambiguous) :
-                new Horde_Date_Tick($hours * 60 * 60 + (int)substr($t, 2, 2) * 60 + (int)substr($t, 4, 2), $ambiguous);
+                ((int)substr($t, 2, 2) * 60 + (int)substr($t, 4, 2)) :
+                ($hours * 60 * 60 + (int)substr($t, 2, 2) * 60 + (int)substr($t, 4, 2));
             break;
 
         default:
@@ -67,15 +69,15 @@ class Horde_Date_Repeater_Time extends Horde_Date_Repeater
             $tomorrowMidnight = new Horde_Date(array('year' => $this->now->year, 'month' => $this->now->month, 'day' => $this->now->day + 1));
 
             if ($pointer == 'future') {
-                if ($this->type->ambiguous) {
-                    foreach (array($midnight->add($this->type->time), $midnight->add($halfDay + $this->type->time), $tomorrowMidnight->add($this->type->time)) as $t) {
+                if ($this->ambiguous) {
+                    foreach (array($midnight->add($this->type), $midnight->add($halfDay + $this->type), $tomorrowMidnight->add($this->type)) as $t) {
                         if ($t->compareDateTime($this->now) >= 0) {
                             $this->currentTime = $t;
                             break;
                         }
                     }
                 } else {
-                    foreach (array($midnight->add($this->type->time), $tomorrowMidnight->add($this->type->time)) as $t) {
+                    foreach (array($midnight->add($this->type), $tomorrowMidnight->add($this->type)) as $t) {
                         if ($t->compareDateTime($this->now) >= 0) {
                             $this->currentTime = $t;
                             break;
@@ -83,15 +85,15 @@ class Horde_Date_Repeater_Time extends Horde_Date_Repeater
                     }
                 }
             } elseif ($pointer == 'past') {
-                if ($this->type->ambiguous) {
-                    foreach (array($midnight->add($halfDay + $this->type->time), $midnight->add($this->type->time), $yesterdayMidnight->add($this->type->time * 2)) as $t) {
+                if ($this->ambiguous) {
+                    foreach (array($midnight->add($halfDay + $this->type), $midnight->add($this->type), $yesterdayMidnight->add($this->type * 2)) as $t) {
                         if ($t->compareDateTime($this->now) <= 0) {
                             $this->currentTime = $t;
                             break;
                         }
                     }
                 } else {
-                    foreach (array($midnight->add($this->type->time), $yesterdayMidnight->add($this->type->time)) as $t) {
+                    foreach (array($midnight->add($this->type), $yesterdayMidnight->add($this->type)) as $t) {
                         if ($t->compareDateTime($this->now) <= 0) {
                             $this->currentTime = $t;
                             break;
@@ -106,7 +108,7 @@ class Horde_Date_Repeater_Time extends Horde_Date_Repeater
         }
 
         if (!$first) {
-            $increment = $this->type->ambiguous ? $halfDay : $fullDay;
+            $increment = $this->ambiguous ? $halfDay : $fullDay;
             $this->currentTime->sec += ($pointer == 'future') ? $increment : -$increment;
         }
 
@@ -132,26 +134,3 @@ class Horde_Date_Repeater_Time extends Horde_Date_Repeater
     }
 
 }
-
-class Horde_Date_Tick
-{
-    public $time;
-    public $ambiguous;
-
-    public function __construct($time, $ambiguous = false)
-    {
-        $this->time = $time;
-        $this->ambiguous = $ambiguous;
-    }
-
-    public function mult($other)
-    {
-        return new Horde_Date_Tick($this->time * $other, $this->ambiguous);
-    }
-
-    public function __toString()
-    {
-        return $this->time . ($this->ambiguous ? '?' : '');
-    }
-
-}
\ No newline at end of file
index 11bea96..6af2c7e 100644 (file)
@@ -35,6 +35,16 @@ class Horde_Date_Span
     }
 
     /**
+     * Is a Horde_Date within this span?
+     *
+     * @param Horde_Date $date
+     */
+    public function includes($date)
+    {
+        return ($this->begin->compareDateTime($date) <= 0) && ($this->end->compareDateTime($date) >= 0);
+    }
+
+    /**
      * Add a number of seconds to this span, returning the new span
      */
     public function add($factor)
diff --git a/framework/Date_Parser/test/Horde/Date/Parser/Locale/BaseTest.php b/framework/Date_Parser/test/Horde/Date/Parser/Locale/BaseTest.php
new file mode 100644 (file)
index 0000000..11a530e
--- /dev/null
@@ -0,0 +1,30 @@
+<?php
+/**
+ * @category   Horde
+ * @package    Horde_Date
+ * @subpackage UnitTests
+ */
+
+/**
+ * @category   Horde
+ * @package    Horde_Date
+ * @subpackage UnitTests
+ */
+class Horde_Date_Parser_Locale_BaseTest extends PHPUnit_Framework_TestCase
+{
+    public function testToday()
+    {
+        var_dump((string)Horde_Date_Parser::parse('today at 11'));
+        var_dump((string)Horde_Date_Parser::parse('tomorrow'));
+        var_dump((string)Horde_Date_Parser::parse('may 27'));
+        var_dump((string)Horde_Date_Parser::parse('thursday'));
+        var_dump((string)Horde_Date_Parser::parse('next month'));
+        var_dump((string)Horde_Date_Parser::parse('last week tuesday'));
+        var_dump((string)Horde_Date_Parser::parse('3 years ago'));
+        var_dump((string)Horde_Date_Parser::parse('6 in the morning'));
+        var_dump((string)Horde_Date_Parser::parse('afternoon yesterday'));
+        var_dump((string)Horde_Date_Parser::parse('3rd wednesday in november'));
+        var_dump((string)Horde_Date_Parser::parse('4th day last week'));
+    }
+
+}
index 71953dc..9cf62d2 100644 (file)
@@ -19,24 +19,18 @@ class Horde_Date_Parser_TokenTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(0, count($token->tags));
         $this->assertFalse($token->tagged());
 
-        $token->tag(new FooTag('mytag'));
+        $token->tag('foo', 'mytag');
         $this->assertEquals(1, count($token->tags));
         $this->assertTrue($token->tagged());
-        $this->assertType('FooTag', $token->getTag('FooTag'));
+        $this->assertType('string', $token->getTag('foo'));
 
-        $token->tag(new BarTag(5));
+        $token->tag('bar', 5);
         $this->assertEquals(2, count($token->tags));
+        $this->assertType('int', $token->getTag('bar'));
 
-        $token->untag('FooTag');
+        $token->untag('foo');
         $this->assertEquals(1, count($token->tags));
+        $this->assertType('int', $token->getTag('bar'));
     }
 
 }
-
-class FooTag extends Horde_Date_Parser_Tag
-{
-}
-
-class BarTag extends Horde_Date_Parser_Tag
-{
-}
index 4fd84ea..e345455 100644 (file)
@@ -54,28 +54,28 @@ class Horde_Date_Repeater_TimeTest extends PHPUnit_Framework_TestCase
     public function testType()
     {
         $t = new Horde_Date_Repeater_Time('4');
-        $this->assertEquals(14400, $t->type->time);
+        $this->assertEquals(14400, $t->type);
 
         $t = new Horde_Date_Repeater_Time('14');
-        $this->assertEquals(50400, $t->type->time);
+        $this->assertEquals(50400, $t->type);
 
         $t = new Horde_Date_Repeater_Time('4:00');
-        $this->assertEquals(14400, $t->type->time);
+        $this->assertEquals(14400, $t->type);
 
         $t = new Horde_Date_Repeater_Time('4:30');
-        $this->assertEquals(16200, $t->type->time);
+        $this->assertEquals(16200, $t->type);
 
         $t = new Horde_Date_Repeater_Time('1400');
-        $this->assertEquals(50400, $t->type->time);
+        $this->assertEquals(50400, $t->type);
 
         $t = new Horde_Date_Repeater_Time('0400');
-        $this->assertEquals(14400, $t->type->time);
+        $this->assertEquals(14400, $t->type);
 
         $t = new Horde_Date_Repeater_Time('04');
-        $this->assertEquals(14400, $t->type->time);
+        $this->assertEquals(14400, $t->type);
 
         $t = new Horde_Date_Repeater_Time('400');
-        $this->assertEquals(14400, $t->type->time);
+        $this->assertEquals(14400, $t->type);
     }
 
 }
index f0722b7..c6424bb 100644 (file)
  */
 class Horde_Date_SpanTest extends PHPUnit_Framework_TestCase
 {
-    public function testSpanWidth()
+    public function testWidth()
     {
         $s = new Horde_Date_Span(new Horde_Date('2006-08-16 00:00:00'), new Horde_Date('2006-08-17 00:00:00'));
         $this->assertEquals(60 * 60 * 24, $s->width());
     }
 
+    public function testIncludes()
+    {
+        $s = new Horde_Date_Span(new Horde_Date('2006-08-16 00:00:00'), new Horde_Date('2006-08-17 00:00:00'));
+        $this->assertTrue($s->includes(new Horde_Date('2006-08-16 12:00:00')));
+        $this->assertFalse($s->includes(new Horde_Date('2006-08-15 00:00:00')));
+        $this->assertFalse($s->includes(new Horde_Date('2006-08-18 00:00:00')));
+    }
+
     public function testSpanMath()
     {
         $s = new Horde_Date_Span(new Horde_Date(1), new Horde_Date(2));