chronic 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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