chronic 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -4
  3. data/HISTORY.md +12 -0
  4. data/README.md +8 -0
  5. data/Rakefile +28 -8
  6. data/chronic.gemspec +7 -5
  7. data/lib/chronic.rb +10 -10
  8. data/lib/chronic/date.rb +82 -0
  9. data/lib/chronic/handler.rb +34 -25
  10. data/lib/chronic/handlers.rb +22 -3
  11. data/lib/chronic/ordinal.rb +22 -20
  12. data/lib/chronic/parser.rb +31 -26
  13. data/lib/chronic/repeater.rb +18 -18
  14. data/lib/chronic/repeaters/repeater_day.rb +4 -3
  15. data/lib/chronic/repeaters/repeater_day_name.rb +5 -4
  16. data/lib/chronic/repeaters/repeater_day_portion.rb +4 -3
  17. data/lib/chronic/repeaters/repeater_fortnight.rb +4 -3
  18. data/lib/chronic/repeaters/repeater_hour.rb +4 -3
  19. data/lib/chronic/repeaters/repeater_minute.rb +4 -3
  20. data/lib/chronic/repeaters/repeater_month.rb +5 -4
  21. data/lib/chronic/repeaters/repeater_month_name.rb +4 -3
  22. data/lib/chronic/repeaters/repeater_season.rb +5 -3
  23. data/lib/chronic/repeaters/repeater_second.rb +4 -3
  24. data/lib/chronic/repeaters/repeater_time.rb +35 -25
  25. data/lib/chronic/repeaters/repeater_week.rb +4 -3
  26. data/lib/chronic/repeaters/repeater_weekday.rb +4 -3
  27. data/lib/chronic/repeaters/repeater_weekend.rb +4 -3
  28. data/lib/chronic/repeaters/repeater_year.rb +5 -4
  29. data/lib/chronic/scalar.rb +34 -69
  30. data/lib/chronic/separator.rb +107 -8
  31. data/lib/chronic/sign.rb +49 -0
  32. data/lib/chronic/tag.rb +5 -4
  33. data/lib/chronic/time.rb +40 -0
  34. data/test/helper.rb +2 -2
  35. data/test/test_chronic.rb +4 -4
  36. data/test/test_handler.rb +20 -0
  37. data/test/test_parsing.rb +72 -3
  38. data/test/test_repeater_time.rb +18 -0
  39. metadata +24 -6
@@ -8,6 +8,7 @@ module Chronic
8
8
  DEFAULT_OPTIONS = {
9
9
  :context => :future,
10
10
  :now => nil,
11
+ :hours24 => nil,
11
12
  :guess => true,
12
13
  :ambiguous_time_range => 6,
13
14
  :endian_precedence => [:middle, :little],
@@ -23,10 +24,13 @@ module Chronic
23
24
  # given, it will assume it is in the past.
24
25
  # :now - Time, all computations will be based off of time
25
26
  # instead of Time.now.
27
+ # :hours24 - Time will be parsed as it would be 24 hour clock.
26
28
  # :guess - By default the parser will guess a single point in time
27
29
  # for the given date or time. If you'd rather have the
28
30
  # entire time span returned, set this to false
29
- # and a Chronic::Span will be returned.
31
+ # and a Chronic::Span will be returned. Setting :guess to :end
32
+ # will return last time from Span, to :middle for middle (same as just true)
33
+ # and :begin for first time from span.
30
34
  # :ambiguous_time_range - If an Integer is given, ambiguous times
31
35
  # (like 5:00) will be assumed to be within the range of
32
36
  # that time in the AM to that time in the PM. For
@@ -58,9 +62,7 @@ module Chronic
58
62
 
59
63
  puts "+#{'-' * 51}\n| #{tokens}\n+#{'-' * 51}" if Chronic.debug
60
64
 
61
- if span
62
- options[:guess] ? guess(span) : span
63
- end
65
+ guess(span, options[:guess]) if span
64
66
  end
65
67
 
66
68
  # Clean up the specified text ready for parsing.
@@ -86,14 +88,16 @@ module Chronic
86
88
  # Returns a new String ready for Chronic to parse.
87
89
  def pre_normalize(text)
88
90
  text = text.to_s.downcase
91
+ text.gsub!(/\b(\d{2})\.(\d{2})\.(\d{4})\b/, '\3 / \2 / \1')
89
92
  text.gsub!(/\b([ap])\.m\.?/, '\1m')
93
+ text.gsub!(/(?<=:\d{2}|:\d{2}\.\d{3})\-(\d{2}:?\d{2})\b/, 'tzminus\1')
90
94
  text.gsub!(/\./, ':')
95
+ text.gsub!(/([ap]):m:?/, '\1m')
91
96
  text.gsub!(/['"]/, '')
92
97
  text.gsub!(/,/, ' ')
93
98
  text.gsub!(/^second /, '2nd ')
94
99
  text.gsub!(/\bsecond (of|day|month|hour|minute|second)\b/, '2nd \1')
95
100
  text = Numerizer.numerize(text)
96
- text.gsub!(/\-(\d{2}:?\d{2})\b/, 'tzminus\1')
97
101
  text.gsub!(/([\/\-\,\@])/) { ' ' + $1 + ' ' }
98
102
  text.gsub!(/(?:^|\s)0(\d+:\d+\s*pm?\b)/, ' \1')
99
103
  text.gsub!(/\btoday\b/, 'this day')
@@ -126,12 +130,11 @@ module Chronic
126
130
  # span - The Chronic::Span object to calcuate a guess from.
127
131
  #
128
132
  # Returns a new Time object.
129
- def guess(span)
130
- if span.width > 1
131
- span.begin + (span.width / 2)
132
- else
133
- span.begin
134
- end
133
+ def guess(span, mode = :middle)
134
+ return span if not mode
135
+ return span.begin + span.width / 2 if span.width > 1 and (mode == true or mode == :middle)
136
+ return span.end if mode == :end
137
+ span.begin
135
138
  end
136
139
 
137
140
  # List of Handler definitions. See Chronic.parse for a list of options this
@@ -149,19 +152,21 @@ module Chronic
149
152
  ],
150
153
 
151
154
  :date => [
152
- Handler.new([:repeater_day_name, :repeater_month_name, :scalar_day, :repeater_time, :separator_slash_or_dash?, :time_zone, :scalar_year], :handle_generic),
155
+ Handler.new([:repeater_day_name, :repeater_month_name, :scalar_day, :repeater_time, [:separator_slash?, :separator_dash?], :time_zone, :scalar_year], :handle_generic),
153
156
  Handler.new([:repeater_day_name, :repeater_month_name, :scalar_day], :handle_rdn_rmn_sd),
154
157
  Handler.new([:repeater_day_name, :repeater_month_name, :scalar_day, :scalar_year], :handle_rdn_rmn_sd_sy),
155
158
  Handler.new([:repeater_day_name, :repeater_month_name, :ordinal_day], :handle_rdn_rmn_od),
159
+ Handler.new([:repeater_day_name, :repeater_month_name, :ordinal_day, :scalar_year], :handle_rdn_rmn_od_sy),
156
160
  Handler.new([:repeater_day_name, :repeater_month_name, :scalar_day, :separator_at?, 'time?'], :handle_rdn_rmn_sd),
157
161
  Handler.new([:repeater_day_name, :repeater_month_name, :ordinal_day, :separator_at?, 'time?'], :handle_rdn_rmn_od),
158
162
  Handler.new([:repeater_day_name, :ordinal_day, :separator_at?, 'time?'], :handle_rdn_od),
159
- Handler.new([:scalar_year, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_day, :repeater_time, :time_zone], :handle_generic),
163
+ Handler.new([:scalar_year, [:separator_slash, :separator_dash], :scalar_month, [:separator_slash, :separator_dash], :scalar_day, :repeater_time, :time_zone], :handle_generic),
164
+ Handler.new([:ordinal_day], :handle_generic),
160
165
  Handler.new([:repeater_month_name, :scalar_day, :scalar_year], :handle_rmn_sd_sy),
161
166
  Handler.new([:repeater_month_name, :ordinal_day, :scalar_year], :handle_rmn_od_sy),
162
167
  Handler.new([:repeater_month_name, :scalar_day, :scalar_year, :separator_at?, 'time?'], :handle_rmn_sd_sy),
163
168
  Handler.new([:repeater_month_name, :ordinal_day, :scalar_year, :separator_at?, 'time?'], :handle_rmn_od_sy),
164
- Handler.new([:repeater_month_name, :separator_slash_or_dash?, :scalar_day, :separator_at?, 'time?'], :handle_rmn_sd),
169
+ Handler.new([:repeater_month_name, [:separator_slash?, :separator_dash?], :scalar_day, :separator_at?, 'time?'], :handle_rmn_sd),
165
170
  Handler.new([:repeater_time, :repeater_day_portion?, :separator_on?, :repeater_month_name, :scalar_day], :handle_rmn_sd_on),
166
171
  Handler.new([:repeater_month_name, :ordinal_day, :separator_at?, 'time?'], :handle_rmn_od),
167
172
  Handler.new([:ordinal_day, :repeater_month_name, :scalar_year, :separator_at?, 'time?'], :handle_od_rmn_sy),
@@ -171,12 +176,12 @@ module Chronic
171
176
  Handler.new([:repeater_time, :repeater_day_portion?, :separator_on?, :repeater_month_name, :ordinal_day], :handle_rmn_od_on),
172
177
  Handler.new([:repeater_month_name, :scalar_year], :handle_rmn_sy),
173
178
  Handler.new([:scalar_day, :repeater_month_name, :scalar_year, :separator_at?, 'time?'], :handle_sd_rmn_sy),
174
- Handler.new([:scalar_day, :separator_slash_or_dash?, :repeater_month_name, :separator_at?, 'time?'], :handle_sd_rmn),
175
- Handler.new([:scalar_year, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_day, :separator_at?, 'time?'], :handle_sy_sm_sd),
176
- Handler.new([:scalar_year, :separator_slash_or_dash, :scalar_month], :handle_sy_sm),
177
- Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_year], :handle_sm_sy),
178
- Handler.new([:scalar_day, :separator_slash_or_dash, :repeater_month_name, :separator_slash_or_dash, :scalar_year, :repeater_time?], :handle_sm_rmn_sy),
179
- Handler.new([:scalar_year, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar?, :time_zone], :handle_generic),
179
+ Handler.new([:scalar_day, [:separator_slash?, :separator_dash?], :repeater_month_name, :separator_at?, 'time?'], :handle_sd_rmn),
180
+ Handler.new([:scalar_year, [:separator_slash, :separator_dash], :scalar_month, [:separator_slash, :separator_dash], :scalar_day, :separator_at?, 'time?'], :handle_sy_sm_sd),
181
+ Handler.new([:scalar_year, [:separator_slash, :separator_dash], :scalar_month], :handle_sy_sm),
182
+ Handler.new([:scalar_month, [:separator_slash, :separator_dash], :scalar_year], :handle_sm_sy),
183
+ Handler.new([:scalar_day, [:separator_slash, :separator_dash], :repeater_month_name, [:separator_slash, :separator_dash], :scalar_year, :repeater_time?], :handle_sm_rmn_sy),
184
+ Handler.new([:scalar_year, [:separator_slash, :separator_dash], :scalar_month, [:separator_slash, :separator_dash], :scalar?, :time_zone], :handle_generic),
180
185
  ],
181
186
 
182
187
  :anchor => [
@@ -199,10 +204,10 @@ module Chronic
199
204
  }
200
205
 
201
206
  endians = [
202
- Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_day, :separator_slash_or_dash, :scalar_year, :separator_at?, 'time?'], :handle_sm_sd_sy),
203
- Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_day, :separator_at?, 'time?'], :handle_sm_sd),
204
- Handler.new([:scalar_day, :separator_slash_or_dash, :scalar_month, :separator_at?, 'time?'], :handle_sd_sm),
205
- Handler.new([:scalar_day, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_year, :separator_at?, 'time?'], :handle_sd_sm_sy)
207
+ Handler.new([:scalar_month, [:separator_slash, :separator_dash], :scalar_day, [:separator_slash, :separator_dash], :scalar_year, :separator_at?, 'time?'], :handle_sm_sd_sy),
208
+ Handler.new([:scalar_month, [:separator_slash, :separator_dash], :scalar_day, :separator_at?, 'time?'], :handle_sm_sd),
209
+ Handler.new([:scalar_day, [:separator_slash, :separator_dash], :scalar_month, :separator_at?, 'time?'], :handle_sd_sm),
210
+ Handler.new([:scalar_day, [:separator_slash, :separator_dash], :scalar_month, [:separator_slash, :separator_dash], :scalar_year, :separator_at?, 'time?'], :handle_sd_sm_sy)
206
211
  ]
207
212
 
208
213
  case endian = Array(options[:endian_precedence]).first
@@ -220,7 +225,7 @@ module Chronic
220
225
  def tokenize(text, options)
221
226
  text = pre_normalize(text)
222
227
  tokens = text.split(' ').map { |word| Token.new(word) }
223
- [Repeater, Grabber, Pointer, Scalar, Ordinal, Separator, TimeZone].each do |tok|
228
+ [Repeater, Grabber, Pointer, Scalar, Ordinal, Separator, Sign, TimeZone].each do |tok|
224
229
  tok.scan(tokens, options)
225
230
  end
226
231
  tokens.select { |token| token.tagged? }
@@ -245,7 +250,7 @@ module Chronic
245
250
 
246
251
  definitions[:arrow].each do |handler|
247
252
  if handler.match(tokens, definitions)
248
- good_tokens = tokens.reject { |o| o.get_tag(SeparatorAt) || o.get_tag(SeparatorSlashOrDash) || o.get_tag(SeparatorComma) || o.get_tag(SeparatorAnd) }
253
+ good_tokens = tokens.reject { |o| o.get_tag(SeparatorAt) || o.get_tag(SeparatorSlash) || o.get_tag(SeparatorDash) || o.get_tag(SeparatorComma) || o.get_tag(SeparatorAnd) }
249
254
  return handler.invoke(:arrow, good_tokens, self, options)
250
255
  end
251
256
  end
@@ -10,32 +10,32 @@ module Chronic
10
10
  # Returns an Array of tokens.
11
11
  def self.scan(tokens, options)
12
12
  tokens.each do |token|
13
- if t = scan_for_season_names(token) then token.tag(t); next end
14
- if t = scan_for_month_names(token) then token.tag(t); next end
15
- if t = scan_for_day_names(token) then token.tag(t); next end
16
- if t = scan_for_day_portions(token) then token.tag(t); next end
17
- if t = scan_for_times(token) then token.tag(t); next end
18
- if t = scan_for_units(token) then token.tag(t); next end
13
+ if t = scan_for_season_names(token, options) then token.tag(t); next end
14
+ if t = scan_for_month_names(token, options) then token.tag(t); next end
15
+ if t = scan_for_day_names(token, options) then token.tag(t); next end
16
+ if t = scan_for_day_portions(token, options) then token.tag(t); next end
17
+ if t = scan_for_times(token, options) then token.tag(t); next end
18
+ if t = scan_for_units(token, options) then token.tag(t); next end
19
19
  end
20
20
  end
21
21
 
22
22
  # token - The Token object we want to scan.
23
23
  #
24
24
  # Returns a new Repeater object.
25
- def self.scan_for_season_names(token)
25
+ def self.scan_for_season_names(token, options = {})
26
26
  scan_for token, RepeaterSeasonName,
27
27
  {
28
28
  /^springs?$/ => :spring,
29
29
  /^summers?$/ => :summer,
30
30
  /^(autumn)|(fall)s?$/ => :autumn,
31
31
  /^winters?$/ => :winter
32
- }
32
+ }, options
33
33
  end
34
34
 
35
35
  # token - The Token object we want to scan.
36
36
  #
37
37
  # Returns a new Repeater object.
38
- def self.scan_for_month_names(token)
38
+ def self.scan_for_month_names(token, options = {})
39
39
  scan_for token, RepeaterMonthName,
40
40
  {
41
41
  /^jan[:\.]?(uary)?$/ => :january,
@@ -50,13 +50,13 @@ module Chronic
50
50
  /^oct[:\.]?(ober)?$/ => :october,
51
51
  /^nov[:\.]?(ember)?$/ => :november,
52
52
  /^dec[:\.]?(ember)?$/ => :december
53
- }
53
+ }, options
54
54
  end
55
55
 
56
56
  # token - The Token object we want to scan.
57
57
  #
58
58
  # Returns a new Repeater object.
59
- def self.scan_for_day_names(token)
59
+ def self.scan_for_day_names(token, options = {})
60
60
  scan_for token, RepeaterDayName,
61
61
  {
62
62
  /^m[ou]n(day)?$/ => :monday,
@@ -66,13 +66,13 @@ module Chronic
66
66
  /^fr[iy](day)?$/ => :friday,
67
67
  /^sat(t?[ue]rday)?$/ => :saturday,
68
68
  /^su[nm](day)?$/ => :sunday
69
- }
69
+ }, options
70
70
  end
71
71
 
72
72
  # token - The Token object we want to scan.
73
73
  #
74
74
  # Returns a new Repeater object.
75
- def self.scan_for_day_portions(token)
75
+ def self.scan_for_day_portions(token, options = {})
76
76
  scan_for token, RepeaterDayPortion,
77
77
  {
78
78
  /^ams?$/ => :am,
@@ -81,20 +81,20 @@ module Chronic
81
81
  /^afternoons?$/ => :afternoon,
82
82
  /^evenings?$/ => :evening,
83
83
  /^(night|nite)s?$/ => :night
84
- }
84
+ }, options
85
85
  end
86
86
 
87
87
  # token - The Token object we want to scan.
88
88
  #
89
89
  # Returns a new Repeater object.
90
- def self.scan_for_times(token)
91
- scan_for token, RepeaterTime, /^\d{1,2}(:?\d{1,2})?([\.:]?\d{1,2})?$/
90
+ def self.scan_for_times(token, options = {})
91
+ scan_for token, RepeaterTime, /^\d{1,2}(:?\d{1,2})?([\.:]?\d{1,2}([\.:]\d{1,6})?)?$/, options
92
92
  end
93
93
 
94
94
  # token - The Token object we want to scan.
95
95
  #
96
96
  # Returns a new Repeater object.
97
- def self.scan_for_units(token)
97
+ def self.scan_for_units(token, options = {})
98
98
  {
99
99
  /^years?$/ => :year,
100
100
  /^seasons?$/ => :season,
@@ -114,7 +114,7 @@ module Chronic
114
114
  if item =~ token.word
115
115
  klass_name = 'Repeater' + symbol.to_s.capitalize
116
116
  klass = Chronic.const_get(klass_name)
117
- return klass.new(symbol)
117
+ return klass.new(symbol, options)
118
118
  end
119
119
  end
120
120
  return nil
@@ -2,14 +2,15 @@ module Chronic
2
2
  class RepeaterDay < Repeater #:nodoc:
3
3
  DAY_SECONDS = 86_400 # (24 * 60 * 60)
4
4
 
5
- def initialize(type)
5
+ def initialize(type, options = {})
6
6
  super
7
+ @current_day_start = nil
7
8
  end
8
9
 
9
10
  def next(pointer)
10
11
  super
11
12
 
12
- if !@current_day_start
13
+ unless @current_day_start
13
14
  @current_day_start = Chronic.time_class.local(@now.year, @now.month, @now.day)
14
15
  end
15
16
 
@@ -50,4 +51,4 @@ module Chronic
50
51
  super << '-day'
51
52
  end
52
53
  end
53
- end
54
+ end
@@ -2,8 +2,9 @@ module Chronic
2
2
  class RepeaterDayName < Repeater #:nodoc:
3
3
  DAY_SECONDS = 86400 # (24 * 60 * 60)
4
4
 
5
- def initialize(type)
5
+ def initialize(type, options = {})
6
6
  super
7
+ @current_date = nil
7
8
  end
8
9
 
9
10
  def next(pointer)
@@ -11,8 +12,8 @@ module Chronic
11
12
 
12
13
  direction = pointer == :future ? 1 : -1
13
14
 
14
- if !@current_date
15
- @current_date = Date.new(@now.year, @now.month, @now.day)
15
+ unless @current_date
16
+ @current_date = ::Date.new(@now.year, @now.month, @now.day)
16
17
  @current_date += direction
17
18
 
18
19
  day_num = symbol_to_number(@type)
@@ -49,4 +50,4 @@ module Chronic
49
50
  lookup[sym] || raise("Invalid symbol specified")
50
51
  end
51
52
  end
52
- end
53
+ end
@@ -9,8 +9,9 @@ module Chronic
9
9
  :night => (20 * 60 * 60)..(24 * 60 * 60), # 8pm-12pm
10
10
  }
11
11
 
12
- def initialize(type)
12
+ def initialize(type, options = {})
13
13
  super
14
+ @current_span = nil
14
15
 
15
16
  if type.kind_of? Integer
16
17
  @range = (@type * 60 * 60)..((@type + 12) * 60 * 60)
@@ -25,7 +26,7 @@ module Chronic
25
26
  def next(pointer)
26
27
  super
27
28
 
28
- if !@current_span
29
+ unless @current_span
29
30
  now_seconds = @now - Chronic.construct(@now.year, @now.month, @now.day)
30
31
  if now_seconds < @range.begin
31
32
  case pointer
@@ -105,4 +106,4 @@ module Chronic
105
106
  Chronic.construct(reference.year, reference.month, reference.day, hour_hand, minute_hand, second_hand)
106
107
  end
107
108
  end
108
- end
109
+ end
@@ -2,14 +2,15 @@ module Chronic
2
2
  class RepeaterFortnight < Repeater #:nodoc:
3
3
  FORTNIGHT_SECONDS = 1_209_600 # (14 * 24 * 60 * 60)
4
4
 
5
- def initialize(type)
5
+ def initialize(type, options = {})
6
6
  super
7
+ @current_fortnight_start = nil
7
8
  end
8
9
 
9
10
  def next(pointer)
10
11
  super
11
12
 
12
- if !@current_fortnight_start
13
+ unless @current_fortnight_start
13
14
  case pointer
14
15
  when :future
15
16
  sunday_repeater = RepeaterDayName.new(:sunday)
@@ -68,4 +69,4 @@ module Chronic
68
69
  super << '-fortnight'
69
70
  end
70
71
  end
71
- end
72
+ end
@@ -2,14 +2,15 @@ module Chronic
2
2
  class RepeaterHour < Repeater #:nodoc:
3
3
  HOUR_SECONDS = 3600 # 60 * 60
4
4
 
5
- def initialize(type)
5
+ def initialize(type, options = {})
6
6
  super
7
+ @current_hour_start = nil
7
8
  end
8
9
 
9
10
  def next(pointer)
10
11
  super
11
12
 
12
- if !@current_hour_start
13
+ unless @current_hour_start
13
14
  case pointer
14
15
  when :future
15
16
  @current_hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour + 1)
@@ -55,4 +56,4 @@ module Chronic
55
56
  super << '-hour'
56
57
  end
57
58
  end
58
- end
59
+ end
@@ -2,14 +2,15 @@ module Chronic
2
2
  class RepeaterMinute < Repeater #:nodoc:
3
3
  MINUTE_SECONDS = 60
4
4
 
5
- def initialize(type)
5
+ def initialize(type, options = {})
6
6
  super
7
+ @current_minute_start = nil
7
8
  end
8
9
 
9
10
  def next(pointer = :future)
10
11
  super
11
12
 
12
- if !@current_minute_start
13
+ unless @current_minute_start
13
14
  case pointer
14
15
  when :future
15
16
  @current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
@@ -55,4 +56,4 @@ module Chronic
55
56
  super << '-minute'
56
57
  end
57
58
  end
58
- end
59
+ end
@@ -5,14 +5,15 @@ module Chronic
5
5
  MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
6
6
  MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
7
7
 
8
- def initialize(type)
8
+ def initialize(type, options = {})
9
9
  super
10
+ @current_month_start = nil
10
11
  end
11
12
 
12
13
  def next(pointer)
13
14
  super
14
15
 
15
- if !@current_month_start
16
+ unless @current_month_start
16
17
  @current_month_start = offset_by(Chronic.construct(@now.year, @now.month), 1, pointer)
17
18
  else
18
19
  @current_month_start = offset_by(Chronic.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
@@ -73,7 +74,7 @@ module Chronic
73
74
  private
74
75
 
75
76
  def month_days(year, month)
76
- Date.leap?(year) ? MONTH_DAYS_LEAP[month - 1] : MONTH_DAYS[month - 1]
77
+ ::Date.leap?(year) ? MONTH_DAYS_LEAP[month - 1] : MONTH_DAYS[month - 1]
77
78
  end
78
79
  end
79
- end
80
+ end
@@ -16,14 +16,15 @@ module Chronic
16
16
  :december => 12
17
17
  }
18
18
 
19
- def initialize(type)
19
+ def initialize(type, options = {})
20
20
  super
21
+ @current_month_begin = nil
21
22
  end
22
23
 
23
24
  def next(pointer)
24
25
  super
25
26
 
26
- if !@current_month_begin
27
+ unless @current_month_begin
27
28
  case pointer
28
29
  when :future
29
30
  if @now.month < index
@@ -91,4 +92,4 @@ module Chronic
91
92
  super << '-monthname-' << @type.to_s
92
93
  end
93
94
  end
94
- end
95
+ end