chronic 0.6.7 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/HISTORY.md +10 -0
  2. data/README.md +5 -0
  3. data/chronic.gemspec +3 -0
  4. data/lib/chronic.rb +49 -43
  5. data/lib/chronic/chronic.rb +72 -62
  6. data/lib/chronic/grabber.rb +9 -7
  7. data/lib/chronic/handler.rb +10 -12
  8. data/lib/chronic/handlers.rb +33 -1
  9. data/lib/chronic/ordinal.rb +12 -9
  10. data/lib/chronic/pointer.rb +9 -7
  11. data/lib/chronic/repeater.rb +28 -18
  12. data/lib/chronic/repeaters/repeater_day_portion.rb +25 -11
  13. data/lib/chronic/scalar.rb +30 -23
  14. data/lib/chronic/season.rb +1 -12
  15. data/lib/chronic/separator.rb +21 -15
  16. data/lib/chronic/tag.rb +5 -11
  17. data/lib/chronic/time_zone.rb +9 -7
  18. data/lib/chronic/token.rb +12 -10
  19. data/test/helper.rb +7 -1
  20. data/test/{test_Chronic.rb → test_chronic.rb} +6 -6
  21. data/test/{test_DaylightSavings.rb → test_daylight_savings.rb} +1 -1
  22. data/test/{test_Handler.rb → test_handler.rb} +1 -1
  23. data/test/{test_MiniDate.rb → test_mini_date.rb} +9 -9
  24. data/test/{test_Numerizer.rb → test_numerizer.rb} +1 -1
  25. data/test/test_parsing.rb +68 -10
  26. data/test/{test_RepeaterDayName.rb → test_repeater_day_name.rb} +1 -1
  27. data/test/test_repeater_day_portion.rb +254 -0
  28. data/test/{test_RepeaterFortnight.rb → test_repeater_fortnight.rb} +1 -1
  29. data/test/{test_RepeaterHour.rb → test_repeater_hour.rb} +1 -1
  30. data/test/{test_RepeaterMinute.rb → test_repeater_minute.rb} +1 -1
  31. data/test/{test_RepeaterMonth.rb → test_repeater_month.rb} +1 -1
  32. data/test/{test_RepeaterMonthName.rb → test_repeater_month_name.rb} +1 -1
  33. data/test/{test_RepeaterSeason.rb → test_repeater_season.rb} +1 -1
  34. data/test/{test_RepeaterTime.rb → test_repeater_time.rb} +1 -1
  35. data/test/{test_RepeaterWeek.rb → test_repeater_week.rb} +1 -1
  36. data/test/{test_RepeaterWeekday.rb → test_repeater_weekday.rb} +1 -1
  37. data/test/{test_RepeaterWeekend.rb → test_repeater_weekend.rb} +1 -1
  38. data/test/{test_RepeaterYear.rb → test_repeater_year.rb} +1 -1
  39. data/test/{test_Span.rb → test_span.rb} +1 -1
  40. data/test/{test_Token.rb → test_token.rb} +1 -1
  41. metadata +76 -44
  42. data/.gemtest +0 -0
  43. data/.yardopts +0 -3
data/HISTORY.md CHANGED
@@ -1,3 +1,13 @@
1
+ # HEAD
2
+
3
+ * Support parsing EXIF date format (#112)
4
+ * Start using minitest for testing
5
+ * Ensure periods are interpreted as colons (#81).
6
+ * Support month/day and day/month parsing (#59).
7
+ * Support day(scalar)-month(name)-year(scalar) (#99).
8
+ * Handle text starting with 'a' or 'an' (#101, @steveburkett).
9
+ * Ensure post medium timestamps are correctly formatted (#89)
10
+
1
11
  # 0.6.7 / 2012-01-31
2
12
 
3
13
  * Handle day, month names with scalar day and year (Joe Fiorini)
data/README.md CHANGED
@@ -46,6 +46,10 @@ You can parse strings containing a natural language date using the
46
46
 
47
47
  Chronic.parse('may 27th', :guess => false)
48
48
  #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
49
+
50
+ Chronic.parse('6/4/2012', :endian_precedence => :little)
51
+ #=> Fri Apr 06 00:00:00 PDT 2012
52
+
49
53
 
50
54
  See `Chronic.parse` for detailed usage instructions.
51
55
 
@@ -86,6 +90,7 @@ Simple
86
90
  Complex
87
91
 
88
92
  * 3 years ago
93
+ * a year ago
89
94
  * 5 months before now
90
95
  * 7 hours ago
91
96
  * 7 days from now
@@ -14,4 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.extra_rdoc_files = %w[README.md HISTORY.md LICENSE]
15
15
  s.files = `git ls-files`.split("\n")
16
16
  s.test_files = `git ls-files -- test`.split("\n")
17
+
18
+ s.add_development_dependency 'rake'
19
+ s.add_development_dependency 'minitest'
17
20
  end
@@ -1,9 +1,10 @@
1
1
  require 'time'
2
2
  require 'date'
3
3
 
4
- # Parse natural language dates and times into Time or {Chronic::Span} objects
4
+ # Parse natural language dates and times into Time or Chronic::Span objects.
5
+ #
6
+ # Examples:
5
7
  #
6
- # @example
7
8
  # require 'chronic'
8
9
  #
9
10
  # Time.now #=> Sun Aug 27 23:18:25 PDT 2006
@@ -25,17 +26,16 @@ require 'date'
25
26
  #
26
27
  # Chronic.parse('may 27th', :guess => false)
27
28
  # #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
28
- #
29
- # @author Tom Preston-Werner, Lee Jarvis
30
29
  module Chronic
31
- VERSION = "0.6.7"
30
+ VERSION = "0.7.0"
32
31
 
33
32
  class << self
34
33
 
35
- # @return [Boolean] true when debug mode is enabled
34
+ # Returns true when debug mode is enabled.
36
35
  attr_accessor :debug
37
36
 
38
- # @example
37
+ # Examples:
38
+ #
39
39
  # require 'chronic'
40
40
  # require 'active_support/time'
41
41
  #
@@ -44,61 +44,66 @@ module Chronic
44
44
  # Chronic.parse('June 15 2006 at 5:54 AM')
45
45
  # # => Thu, 15 Jun 2006 05:45:00 UTC +00:00
46
46
  #
47
- # @return [Time] The time class Chronic uses internally
47
+ # Returns The Time class Chronic uses internally.
48
48
  attr_accessor :time_class
49
49
 
50
- # The current Time Chronic is using to base from
50
+ # The current Time Chronic is using to base from.
51
+ #
52
+ # Examples:
51
53
  #
52
- # @example
53
54
  # Time.now #=> 2011-06-06 14:13:43 +0100
54
55
  # Chronic.parse('yesterday') #=> 2011-06-05 12:00:00 +0100
55
56
  #
56
57
  # now = Time.local(2025, 12, 24)
57
58
  # Chronic.parse('tomorrow', :now => now) #=> 2025-12-25 12:00:00 +0000
58
59
  #
59
- # @return [Time, nil]
60
+ # Returns a Time object.
60
61
  attr_accessor :now
61
62
  end
62
63
 
63
64
  self.debug = false
64
65
  self.time_class = Time
66
+
67
+ autoload :Handler, 'chronic/handler'
68
+ autoload :Handlers, 'chronic/handlers'
69
+ autoload :MiniDate, 'chronic/mini_date'
70
+ autoload :Tag, 'chronic/tag'
71
+ autoload :Span, 'chronic/span'
72
+ autoload :Token, 'chronic/token'
73
+ autoload :Grabber, 'chronic/grabber'
74
+ autoload :Pointer, 'chronic/pointer'
75
+ autoload :Scalar, 'chronic/scalar'
76
+ autoload :Ordinal, 'chronic/ordinal'
77
+ autoload :OrdinalDay, 'chronic/ordinal'
78
+ autoload :Separator, 'chronic/separator'
79
+ autoload :TimeZone, 'chronic/time_zone'
80
+ autoload :Numerizer, 'chronic/numerizer'
81
+ autoload :Season, 'chronic/season'
82
+
83
+ autoload :Repeater, 'chronic/repeater'
84
+ autoload :RepeaterYear, 'chronic/repeaters/repeater_year'
85
+ autoload :RepeaterSeason, 'chronic/repeaters/repeater_season'
86
+ autoload :RepeaterSeasonName, 'chronic/repeaters/repeater_season_name'
87
+ autoload :RepeaterMonth, 'chronic/repeaters/repeater_month'
88
+ autoload :RepeaterMonthName, 'chronic/repeaters/repeater_month_name'
89
+ autoload :RepeaterFortnight, 'chronic/repeaters/repeater_fortnight'
90
+ autoload :RepeaterWeek, 'chronic/repeaters/repeater_week'
91
+ autoload :RepeaterWeekend, 'chronic/repeaters/repeater_weekend'
92
+ autoload :RepeaterWeekday, 'chronic/repeaters/repeater_weekday'
93
+ autoload :RepeaterDay, 'chronic/repeaters/repeater_day'
94
+ autoload :RepeaterDayName, 'chronic/repeaters/repeater_day_name'
95
+ autoload :RepeaterDayPortion, 'chronic/repeaters/repeater_day_portion'
96
+ autoload :RepeaterHour, 'chronic/repeaters/repeater_hour'
97
+ autoload :RepeaterMinute, 'chronic/repeaters/repeater_minute'
98
+ autoload :RepeaterSecond, 'chronic/repeaters/repeater_second'
99
+ autoload :RepeaterTime, 'chronic/repeaters/repeater_time'
100
+
65
101
  end
66
102
 
67
103
  require 'chronic/chronic'
68
- require 'chronic/handler'
69
- require 'chronic/handlers'
70
- require 'chronic/mini_date'
71
- require 'chronic/tag'
72
- require 'chronic/span'
73
- require 'chronic/token'
74
- require 'chronic/grabber'
75
- require 'chronic/pointer'
76
- require 'chronic/scalar'
77
- require 'chronic/ordinal'
78
- require 'chronic/separator'
79
- require 'chronic/time_zone'
80
- require 'chronic/numerizer'
81
- require 'chronic/season'
82
-
83
- require 'chronic/repeater'
84
- require 'chronic/repeaters/repeater_year'
85
- require 'chronic/repeaters/repeater_season'
86
- require 'chronic/repeaters/repeater_season_name'
87
- require 'chronic/repeaters/repeater_month'
88
- require 'chronic/repeaters/repeater_month_name'
89
- require 'chronic/repeaters/repeater_fortnight'
90
- require 'chronic/repeaters/repeater_week'
91
- require 'chronic/repeaters/repeater_weekend'
92
- require 'chronic/repeaters/repeater_weekday'
93
- require 'chronic/repeaters/repeater_day'
94
- require 'chronic/repeaters/repeater_day_name'
95
- require 'chronic/repeaters/repeater_day_portion'
96
- require 'chronic/repeaters/repeater_hour'
97
- require 'chronic/repeaters/repeater_minute'
98
- require 'chronic/repeaters/repeater_second'
99
- require 'chronic/repeaters/repeater_time'
100
104
 
101
105
  class Time
106
+
102
107
  def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
103
108
  warn "Time.construct will be deprecated in version 0.7.0. Please use Chronic.construct instead"
104
109
  Chronic.construct(year, month, day, hour, minute, second)
@@ -108,4 +113,5 @@ class Time
108
113
  warn "Time.to_minidate will be deprecated in version 0.7.0. Please use Chronic::MiniDate.from_time(time) instead"
109
114
  Chronic::MiniDate.from_time(self)
110
115
  end
116
+
111
117
  end
@@ -1,5 +1,6 @@
1
1
  module Chronic
2
2
 
3
+ # Returns a Hash of default configuration options.
3
4
  DEFAULT_OPTIONS = {
4
5
  :context => :future,
5
6
  :now => nil,
@@ -11,53 +12,43 @@ module Chronic
11
12
 
12
13
  class << self
13
14
 
14
- # Parses a string containing a natural language date or time
15
+ # Parses a string containing a natural language date or time.
15
16
  #
16
17
  # If the parser can find a date or time, either a Time or Chronic::Span
17
18
  # will be returned (depending on the value of `:guess`). If no
18
- # date or time can be found, `nil` will be returned
19
+ # date or time can be found, `nil` will be returned.
19
20
  #
20
- # @param [String] text The text to parse
21
+ # text - The String text to parse.
22
+ # opts - An optional Hash of configuration options:
23
+ # :context - If your string represents a birthday, you can set
24
+ # this value to :past and if an ambiguous string is
25
+ # given, it will assume it is in the past.
26
+ # :now - Time, all computations will be based off of time
27
+ # instead of Time.now.
28
+ # :guess - By default the parser will guess a single point in time
29
+ # for the given date or time. If you'd rather have the
30
+ # entire time span returned, set this to false
31
+ # and a Chronic::Span will be returned.
32
+ # :ambiguous_time_range - If an Integer is given, ambiguous times
33
+ # (like 5:00) will be assumed to be within the range of
34
+ # that time in the AM to that time in the PM. For
35
+ # example, if you set it to `7`, then the parser will
36
+ # look for the time between 7am and 7pm. In the case of
37
+ # 5:00, it would assume that means 5:00pm. If `:none`
38
+ # is given, no assumption will be made, and the first
39
+ # matching instance of that time will be used.
40
+ # :endian_precedence - By default, Chronic will parse "03/04/2011"
41
+ # as the fourth day of the third month. Alternatively you
42
+ # can tell Chronic to parse this as the third day of the
43
+ # fourth month by setting this to [:little, :middle].
44
+ # :ambiguous_year_future_bias - When parsing two digit years
45
+ # (ie 79) unlike Rubys Time class, Chronic will attempt
46
+ # to assume the full year using this figure. Chronic will
47
+ # look x amount of years into the future and past. If the
48
+ # two digit year is `now + x years` it's assumed to be the
49
+ # future, `now - x years` is assumed to be the past.
21
50
  #
22
- # @option opts [Symbol] :context (:future)
23
- # * If your string represents a birthday, you can set `:context` to
24
- # `:past` and if an ambiguous string is given, it will assume it is
25
- # in the past. Specify `:future` or omit to set a future context.
26
- #
27
- # @option opts [Object] :now (Time.now)
28
- # * By setting `:now` to a Time, all computations will be based off of
29
- # that time instead of `Time.now`. If set to nil, Chronic will use
30
- # `Time.now`
31
- #
32
- # @option opts [Boolean] :guess (true)
33
- # * By default, the parser will guess a single point in time for the
34
- # given date or time. If you'd rather have the entire time span
35
- # returned, set `:guess` to `false` and a {Chronic::Span} will
36
- # be returned
37
- #
38
- # @option opts [Integer] :ambiguous_time_range (6)
39
- # * If an Integer is given, ambiguous times (like 5:00) will be
40
- # assumed to be within the range of that time in the AM to that time
41
- # in the PM. For example, if you set it to `7`, then the parser
42
- # will look for the time between 7am and 7pm. In the case of 5:00, it
43
- # would assume that means 5:00pm. If `:none` is given, no
44
- # assumption will be made, and the first matching instance of that
45
- # time will be used
46
- #
47
- # @option opts [Array] :endian_precedence ([:middle, :little])
48
- # * By default, Chronic will parse "03/04/2011" as the fourth day
49
- # of the third month. Alternatively you can tell Chronic to parse
50
- # this as the third day of the fourth month by altering the
51
- # `:endian_precedence` to `[:little, :middle]`
52
- #
53
- # @option opts [Integer] :ambiguous_year_future_bias (50)
54
- # * When parsing two digit years (ie 79) unlike Rubys Time class,
55
- # Chronic will attempt to assume the full year using this figure.
56
- # Chronic will look x amount of years into the future and past. If
57
- # the two digit year is `now + x years` it's assumed to be the
58
- # future, `now - x years` is assumed to be the past
59
- #
60
- # @return [Time, Chronic::Span, nil]
51
+ # Returns a new Time object, or Chronic::Span if :guess option is false.
61
52
  def parse(text, opts={})
62
53
  options = DEFAULT_OPTIONS.merge opts
63
54
 
@@ -87,14 +78,17 @@ module Chronic
87
78
  end
88
79
  end
89
80
 
90
- # Clean up the specified text ready for parsing
81
+ # Clean up the specified text ready for parsing.
91
82
  #
92
83
  # Clean up the string by stripping unwanted characters, converting
93
84
  # idioms to their canonical form, converting number words to numbers
94
85
  # (three => 3), and converting ordinal words to numeric
95
86
  # ordinals (third => 3rd)
96
87
  #
97
- # @example
88
+ # text - The String text to normalize.
89
+ #
90
+ # Examples:
91
+ #
98
92
  # Chronic.pre_normalize('first day in May')
99
93
  # #=> "1st day in may"
100
94
  #
@@ -104,17 +98,18 @@ module Chronic
104
98
  # Chronic.pre_normalize('one hundred and thirty six days from now')
105
99
  # #=> "136 days future this second"
106
100
  #
107
- # @param [String] text The string to normalize
108
- # @return [String] A new string ready for Chronic to parse
101
+ # Returns a new String ready for Chronic to parse.
109
102
  def pre_normalize(text)
110
103
  text = text.to_s.downcase
111
- text.gsub!(/['"\.]/, '')
104
+ text.gsub!(/\./, ':')
105
+ text.gsub!(/['"]/, '')
112
106
  text.gsub!(/,/, ' ')
107
+ text.gsub!(/^second /, '2nd ')
113
108
  text.gsub!(/\bsecond (of|day|month|hour|minute|second)\b/, '2nd \1')
114
109
  text = Numerizer.numerize(text)
115
110
  text.gsub!(/ \-(\d{4})\b/, ' tzminus\1')
116
111
  text.gsub!(/([\/\-\,\@])/) { ' ' + $1 + ' ' }
117
- text.gsub!(/(?:^|\s)0(\d+:\d+\s*pm?\b)/, '\1')
112
+ text.gsub!(/(?:^|\s)0(\d+:\d+\s*pm?\b)/, ' \1')
118
113
  text.gsub!(/\btoday\b/, 'this day')
119
114
  text.gsub!(/\btomm?orr?ow\b/, 'next day')
120
115
  text.gsub!(/\byesterday\b/, 'last day')
@@ -129,23 +124,26 @@ module Chronic
129
124
  text.gsub!(/\b\d+:?\d*[ap]\b/,'\0m')
130
125
  text.gsub!(/(\d)([ap]m|oclock)\b/, '\1 \2')
131
126
  text.gsub!(/\b(hence|after|from)\b/, 'future')
127
+ text.gsub!(/^\s?an? /i, '1 ')
128
+ text.gsub!(/\b(\d{4}):(\d{2}):(\d{2})\b/, '\1 / \2 / \3') # DTOriginal
132
129
  text
133
130
  end
134
131
 
135
- # Convert number words to numbers (three => 3, fourth => 4th)
132
+ # Convert number words to numbers (three => 3, fourth => 4th).
133
+ #
134
+ # text - The String to convert.
136
135
  #
137
- # @see Numerizer.numerize
138
- # @param [String] text The string to convert
139
- # @return [String] A new string with words converted to numbers
136
+ # Returns a new String with words converted to numbers.
140
137
  def numericize_numbers(text)
141
138
  warn "Chronic.numericize_numbers will be deprecated in version 0.7.0. Please use Chronic::Numerizer.numerize instead"
142
139
  Numerizer.numerize(text)
143
140
  end
144
141
 
145
- # Guess a specific time within the given span
142
+ # Guess a specific time within the given span.
146
143
  #
147
- # @param [Span] span
148
- # @return [Time]
144
+ # span - The Chronic::Span object to calcuate a guess from.
145
+ #
146
+ # Returns a new Time object.
149
147
  def guess(span)
150
148
  if span.width > 1
151
149
  span.begin + (span.width / 2)
@@ -154,11 +152,13 @@ module Chronic
154
152
  end
155
153
  end
156
154
 
157
- # List of {Handler} definitions. See {parse} for a list of options this
158
- # method accepts
155
+ # List of Handler definitions. See #parse for a list of options this
156
+ # method accepts.
157
+ #
158
+ # options - An optional Hash of configuration options:
159
+ # :endian_precedence -
159
160
  #
160
- # @see parse
161
- # @return [Hash] A Hash of Handler definitions
161
+ # Returns A Hash of Handler definitions.
162
162
  def definitions(options={})
163
163
  options[:endian_precedence] ||= [:middle, :little]
164
164
 
@@ -188,7 +188,9 @@ module Chronic
188
188
  Handler.new([:scalar_day, :repeater_month_name, :scalar_year, :separator_at?, 'time?'], :handle_sd_rmn_sy),
189
189
  Handler.new([:scalar_day, :repeater_month_name, :separator_at?, 'time?'], :handle_sd_rmn),
190
190
  Handler.new([:scalar_year, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_day, :separator_at?, 'time?'], :handle_sy_sm_sd),
191
- Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_year], :handle_sm_sy)
191
+ Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_day], :handle_sm_sd),
192
+ Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_year], :handle_sm_sy),
193
+ Handler.new([:scalar_day, :separator_slash_or_dash, :repeater_month_name, :separator_slash_or_dash, :scalar_year], :handle_sm_rmn_sy)
192
194
  ],
193
195
 
194
196
  # tonight at 7pm
@@ -229,9 +231,17 @@ module Chronic
229
231
  @definitions
230
232
  end
231
233
 
232
- # Construct a time Object
234
+ # Construct a new time object determining possible month overflows
235
+ # and leap years.
236
+ #
237
+ # year - Integer year.
238
+ # month - Integer month.
239
+ # day - Integer day.
240
+ # hour - Integer hour.
241
+ # minute - Integer minute.
242
+ # second - Integer second.
233
243
  #
234
- # @return [Time]
244
+ # Returns a new Time object constructed from these params.
235
245
  def construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
236
246
  if second >= 60
237
247
  minute += second / 60
@@ -1,20 +1,22 @@
1
1
  module Chronic
2
2
  class Grabber < Tag
3
3
 
4
- # Scan an Array of {Token}s and apply any necessary Grabber tags to
5
- # each token
4
+ # Scan an Array of Tokens and apply any necessary Grabber tags to
5
+ # each token.
6
6
  #
7
- # @param [Array<Token>] tokens Array of tokens to scan
8
- # @param [Hash] options Options specified in {Chronic.parse}
9
- # @return [Array] list of tokens
7
+ # tokens - An Array of Token objects to scan.
8
+ # options - The Hash of options specified in Chronic::parse.
9
+ #
10
+ # Returns an Array of Token objects.
10
11
  def self.scan(tokens, options)
11
12
  tokens.each do |token|
12
13
  if t = scan_for_all(token) then token.tag(t); next end
13
14
  end
14
15
  end
15
16
 
16
- # @param [Token] token
17
- # @return [Grabber, nil]
17
+ # token - The Token object to scan.
18
+ #
19
+ # Returns a new Grabber object.
18
20
  def self.scan_for_all(token)
19
21
  scan_for token, self,
20
22
  {
@@ -1,25 +1,22 @@
1
1
  module Chronic
2
2
  class Handler
3
3
 
4
- # @return [Array] A list of patterns
5
4
  attr_reader :pattern
6
5
 
7
- # @return [Symbol] The method which handles this list of patterns.
8
- # This method should exist inside the {Handlers} module
9
6
  attr_reader :handler_method
10
7
 
11
- # @param [Array] pattern A list of patterns to match tokens against
12
- # @param [Symbol] handler_method The method to be invoked when patterns
13
- # are matched. This method should exist inside the {Handlers} module
8
+ # pattern - An Array of patterns to match tokens against.
9
+ # handler_method - A Symbole representing the method to be invoked
10
+ # when patterns are matched.
14
11
  def initialize(pattern, handler_method)
15
12
  @pattern = pattern
16
13
  @handler_method = handler_method
17
14
  end
18
15
 
19
- # @param [Array] tokens
20
- # @param [Hash] definitions
21
- # @return [Boolean]
22
- # @see Chronic.tokens_to_span
16
+ # tokens - An Array of tokens to process.
17
+ # definitions - A Hash of definitions to check against.
18
+ #
19
+ # Returns true if a match is found.
23
20
  def match(tokens, definitions)
24
21
  token_index = 0
25
22
 
@@ -70,8 +67,9 @@ module Chronic
70
67
  Handlers.send(@handler_method, tokens, options)
71
68
  end
72
69
 
73
- # @param [Handler] The handler to compare
74
- # @return [Boolean] True if these handlers match
70
+ # other - The other Handler object to compare.
71
+ #
72
+ # Returns true if these Handlers match.
75
73
  def ==(other)
76
74
  @pattern == other.pattern
77
75
  end