chronic 0.1.5 → 0.2.1

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.
data/History.txt CHANGED
@@ -1,3 +1,19 @@
1
+ = 0.2.1
2
+
3
+ * fixed time overflow issue
4
+ * implemented "next" for minute repeater
5
+ * generalized time dealiasing to dealias regardless of day portion and time position
6
+ * added additional token match for cases like "friday evening at 7" and "tomorrow evening at 7"
7
+ * added support for Time#to_s output format: "Mon Apr 02 17:00:00 PDT 2007"
8
+
9
+ = 0.2.0 2007-03-20
10
+
11
+ * implemented numerizer, allowing the use of number words (e.g. five weeks ago) (by shalev)
12
+
13
+ = 0.1.6 2006-01-15
14
+
15
+ * added 'weekend' support (by eventualbuddha)
16
+
1
17
  = 0.1.5 2006-12-20
2
18
 
3
19
  * fixed 'aug 20' returning next year if current month is august
@@ -11,7 +27,7 @@
11
27
 
12
28
  = 0.1.3
13
29
 
14
- * improved regexes for word variations (Josh Goebel)
30
+ * improved regexes for word variations (by Josh Goebel)
15
31
  * fixed a bug that caused "today at 3am" to return nil if current time is after 3am
16
32
 
17
33
  = 0.1.2
data/Manifest.txt CHANGED
@@ -26,10 +26,11 @@ lib/chronic/repeaters/repeater_weekend.rb
26
26
  lib/chronic/repeaters/repeater_year.rb
27
27
  lib/chronic/scalar.rb
28
28
  lib/chronic/separator.rb
29
- test/parse_numbers.rb
29
+ lib/numerizer/numerizer.rb
30
30
  test/suite.rb
31
31
  test/test_Chronic.rb
32
32
  test/test_Handler.rb
33
+ test/test_Numerizer.rb
33
34
  test/test_RepeaterDayName.rb
34
35
  test/test_RepeaterFortnight.rb
35
36
  test/test_RepeaterHour.rb
@@ -37,6 +38,7 @@ test/test_RepeaterMonth.rb
37
38
  test/test_RepeaterMonthName.rb
38
39
  test/test_RepeaterTime.rb
39
40
  test/test_RepeaterWeek.rb
41
+ test/test_RepeaterWeekend.rb
40
42
  test/test_RepeaterYear.rb
41
43
  test/test_Span.rb
42
44
  test/test_Token.rb
data/Rakefile CHANGED
@@ -7,33 +7,13 @@ require './lib/chronic.rb'
7
7
  Hoe.new('chronic', Chronic::VERSION) do |p|
8
8
  p.rubyforge_name = 'chronic'
9
9
  p.summary = 'A natural language date parser'
10
+ p.author = 'Tom Preston-Werner'
11
+ p.email = 'tom@rubyisawesome.com'
10
12
  p.description = p.paragraphs_of('README.txt', 2).join("\n\n")
11
13
  p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
12
14
  p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ p.need_tar = false
16
+ p.extra_deps = []
13
17
  end
14
18
 
15
- # vim: syntax=Ruby
16
-
17
- __END__
18
-
19
- require 'rubygems'
20
-
21
- SPEC = Gem::Specification.new do |s|
22
- s.name = 'chronic'
23
- s.version = '0.1.5'
24
- s.author = 'Tom Preston-Werner'
25
- s.email = 'tom@rubyisawesome.com'
26
- s.homepage = 'http://chronic.rubyforge.org'
27
- s.platform = Gem::Platform::RUBY
28
- s.summary = "A natural language date parser"
29
- candidates = Dir["{lib,test}/**/*"]
30
- s.files = candidates.delete_if do |item|
31
- item.include?('.svn')
32
- end
33
- s.require_path = "lib"
34
- s.autorequire = "chronic"
35
- s.test_file = "test/suite.rb"
36
- s.has_rdoc = true
37
- s.extra_rdoc_files = ['README']
38
- s.rdoc_options << '--main' << 'README'
39
- end
19
+ # vim: syntax=Ruby
@@ -66,7 +66,7 @@ module Chronic
66
66
  @tokens = tokenizer.scan(@tokens, options)
67
67
  end
68
68
 
69
- [Grabber, Pointer, Scalar, Ordinal, Separator].each do |tokenizer|
69
+ [Grabber, Pointer, Scalar, Ordinal, Separator, TimeZone].each do |tokenizer|
70
70
  @tokens = tokenizer.scan(@tokens)
71
71
  end
72
72
 
@@ -101,6 +101,7 @@ module Chronic
101
101
  # ordinals (third => 3rd)
102
102
  def pre_normalize(text) #:nodoc:
103
103
  normalized_text = text.to_s.downcase
104
+ normalized_text = numericize_numbers(normalized_text)
104
105
  normalized_text.gsub!(/['"\.]/, '')
105
106
  normalized_text.gsub!(/([\/\-\,\@])/) { ' ' + $1 + ' ' }
106
107
  normalized_text.gsub!(/\btoday\b/, 'this day')
@@ -118,15 +119,12 @@ module Chronic
118
119
  normalized_text.gsub!(/\btonight\b/, 'this night')
119
120
  normalized_text.gsub!(/(?=\w)([ap]m|oclock)\b/, ' \1')
120
121
  normalized_text.gsub!(/\b(hence|after|from)\b/, 'future')
121
- normalized_text.gsub!(/\ba\b/, '1')
122
- normalized_text.gsub!(/\s+/, ' ')
123
- normalized_text = numericize_numbers(normalized_text)
124
122
  normalized_text = numericize_ordinals(normalized_text)
125
123
  end
126
124
 
127
125
  # Convert number words to numbers (three => 3)
128
126
  def numericize_numbers(text) #:nodoc:
129
- text
127
+ Numerizer.numerize(text)
130
128
  end
131
129
 
132
130
  # Convert ordinal words to numeric ordinals (third => 3rd)
@@ -6,7 +6,8 @@ module Chronic
6
6
  @definitions ||=
7
7
  {:time => [Handler.new([:repeater_time, :repeater_day_portion?], nil)],
8
8
 
9
- :date => [Handler.new([:repeater_month_name, :scalar_day, :scalar_year], :handle_rmn_sd_sy),
9
+ :date => [Handler.new([:repeater_day_name, :repeater_month_name, :scalar_day, :repeater_time, :time_zone, :scalar_year], :handle_rdn_rmn_sd_t_tz_sy),
10
+ Handler.new([:repeater_month_name, :scalar_day, :scalar_year], :handle_rmn_sd_sy),
10
11
  Handler.new([:repeater_month_name, :scalar_day, :scalar_year, :separator_at?, 'time?'], :handle_rmn_sd_sy),
11
12
  Handler.new([:repeater_month_name, :scalar_day, :separator_at?, 'time?'], :handle_rmn_sd),
12
13
  Handler.new([:repeater_month_name, :ordinal_day, :separator_at?, 'time?'], :handle_rmn_od),
@@ -17,13 +18,17 @@ module Chronic
17
18
  Handler.new([:scalar_year, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_day, :separator_at?, 'time?'], :handle_sy_sm_sd),
18
19
  Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_year], :handle_sm_sy)],
19
20
 
21
+ # tonight at 7pm
20
22
  :anchor => [Handler.new([:grabber?, :repeater, :separator_at?, :repeater?, :repeater?], :handle_r),
23
+ Handler.new([:grabber?, :repeater, :repeater, :separator_at?, :repeater?, :repeater?], :handle_r),
21
24
  Handler.new([:repeater, :grabber, :repeater], :handle_r_g_r)],
22
25
 
26
+ # 3 weeks from now, in 2 months
23
27
  :arrow => [Handler.new([:scalar, :repeater, :pointer], :handle_s_r_p),
24
28
  Handler.new([:pointer, :scalar, :repeater], :handle_p_s_r),
25
29
  Handler.new([:scalar, :repeater, :pointer, 'anchor'], :handle_s_r_p_a)],
26
30
 
31
+ # 3rd week in march
27
32
  :narrow => [Handler.new([:ordinal, :repeater, :separator_in, :repeater], :handle_o_r_s_r),
28
33
  Handler.new([:ordinal, :repeater, :grabber, :repeater], :handle_o_r_g_r)]
29
34
  }
@@ -34,6 +39,7 @@ module Chronic
34
39
 
35
40
  self.definitions[:date].each do |handler|
36
41
  if handler.match(tokens, self.definitions)
42
+ puts "-date" if Chronic.debug
37
43
  good_tokens = tokens.select { |o| !o.get_tag Separator }
38
44
  return self.send(handler.handler_method, good_tokens, options)
39
45
  end
@@ -43,6 +49,7 @@ module Chronic
43
49
 
44
50
  self.definitions[:anchor].each do |handler|
45
51
  if handler.match(tokens, self.definitions)
52
+ puts "-anchor" if Chronic.debug
46
53
  good_tokens = tokens.select { |o| !o.get_tag Separator }
47
54
  return self.send(handler.handler_method, good_tokens, options)
48
55
  end
@@ -52,21 +59,24 @@ module Chronic
52
59
 
53
60
  self.definitions[:arrow].each do |handler|
54
61
  if handler.match(tokens, self.definitions)
62
+ puts "-arrow" if Chronic.debug
55
63
  good_tokens = tokens.reject { |o| o.get_tag(SeparatorAt) || o.get_tag(SeparatorSlashOrDash) || o.get_tag(SeparatorComma) }
56
64
  return self.send(handler.handler_method, good_tokens, options)
57
65
  end
58
66
  end
59
67
 
60
- # not an arrow, let's hope it's an narrow
68
+ # not an arrow, let's hope it's a narrow
61
69
 
62
70
  self.definitions[:narrow].each do |handler|
63
71
  if handler.match(tokens, self.definitions)
72
+ puts "-narrow" if Chronic.debug
64
73
  #good_tokens = tokens.select { |o| !o.get_tag Separator }
65
74
  return self.send(handler.handler_method, tokens, options)
66
75
  end
67
76
  end
68
77
 
69
78
  # I guess you're out of luck!
79
+ puts "-none" if Chronic.debug
70
80
  return nil
71
81
  end
72
82
 
@@ -122,6 +132,19 @@ module Chronic
122
132
  end
123
133
  end
124
134
 
135
+ def handle_rdn_rmn_sd_t_tz_sy(tokens, options) #:nodoc:
136
+ month = tokens[1].get_tag(RepeaterMonthName).index
137
+ day = tokens[2].get_tag(ScalarDay).type
138
+ year = tokens[5].get_tag(ScalarYear).type
139
+
140
+ begin
141
+ day_start = Time.local(year, month, day)
142
+ day_or_time(day_start, [tokens[3]], options)
143
+ rescue ArgumentError
144
+ nil
145
+ end
146
+ end
147
+
125
148
  def handle_rmn_sd_sy(tokens, options) #:nodoc:
126
149
  month = tokens[0].get_tag(RepeaterMonthName).index
127
150
  day = tokens[1].get_tag(ScalarDay).type
@@ -214,17 +237,19 @@ module Chronic
214
237
  def handle_s_r_p(tokens, options) #:nodoc:
215
238
  repeater = tokens[1].get_tag(Repeater)
216
239
 
217
- span =
218
- case true
219
- when [RepeaterYear, RepeaterSeason, RepeaterSeasonName, RepeaterMonth, RepeaterMonthName, RepeaterFortnight, RepeaterWeek].include?(repeater.class)
220
- self.parse("this hour", :guess => false, :now => @now)
221
- when [RepeaterWeekend, RepeaterDay, RepeaterDayName, RepeaterDayPortion, RepeaterHour].include?(repeater.class)
222
- self.parse("this minute", :guess => false, :now => @now)
223
- when [RepeaterMinute, RepeaterSecond].include?(repeater.class)
224
- self.parse("this second", :guess => false, :now => @now)
225
- else
226
- raise(ChronicPain, "Invalid repeater: #{repeater.class}")
227
- end
240
+ # span =
241
+ # case true
242
+ # when [RepeaterYear, RepeaterSeason, RepeaterSeasonName, RepeaterMonth, RepeaterMonthName, RepeaterFortnight, RepeaterWeek].include?(repeater.class)
243
+ # self.parse("this hour", :guess => false, :now => @now)
244
+ # when [RepeaterWeekend, RepeaterDay, RepeaterDayName, RepeaterDayPortion, RepeaterHour].include?(repeater.class)
245
+ # self.parse("this minute", :guess => false, :now => @now)
246
+ # when [RepeaterMinute, RepeaterSecond].include?(repeater.class)
247
+ # self.parse("this second", :guess => false, :now => @now)
248
+ # else
249
+ # raise(ChronicPain, "Invalid repeater: #{repeater.class}")
250
+ # end
251
+
252
+ span = self.parse("this second", :guess => false, :now => @now)
228
253
 
229
254
  self.handle_srp(tokens, span, options)
230
255
  end
@@ -331,22 +356,54 @@ module Chronic
331
356
 
332
357
  def dealias_and_disambiguate_times(tokens, options) #:nodoc:
333
358
  # handle aliases of am/pm
334
- # 5:00 in the morning => 5:00 am
335
- # 7:00 in the evening => 7:00 pm
336
- #ttokens = []
337
- tokens.each_with_index do |t0, i|
338
- t1 = tokens[i + 1]
339
- if t1 && (t1tag = t1.get_tag(RepeaterDayPortion)) && t0.get_tag(RepeaterTime)
340
- if [:morning].include?(t1tag.type)
341
- t1.untag(RepeaterDayPortion)
342
- t1.tag(RepeaterDayPortion.new(:am))
343
- elsif [:afternoon, :evening, :night].include?(t1tag.type)
344
- t1.untag(RepeaterDayPortion)
345
- t1.tag(RepeaterDayPortion.new(:pm))
346
- end
359
+ # 5:00 in the morning -> 5:00 am
360
+ # 7:00 in the evening -> 7:00 pm
361
+
362
+ day_portion_index = nil
363
+ tokens.each_with_index do |t, i|
364
+ if t.get_tag(RepeaterDayPortion)
365
+ day_portion_index = i
366
+ break
367
+ end
368
+ end
369
+
370
+ time_index = nil
371
+ tokens.each_with_index do |t, i|
372
+ if t.get_tag(RepeaterTime)
373
+ time_index = i
374
+ break
347
375
  end
348
376
  end
349
- #tokens = ttokens
377
+
378
+ if (day_portion_index && time_index)
379
+ t1 = tokens[day_portion_index]
380
+ t1tag = t1.get_tag(RepeaterDayPortion)
381
+
382
+ if [:morning].include?(t1tag.type)
383
+ puts '--morning->am' if Chronic.debug
384
+ t1.untag(RepeaterDayPortion)
385
+ t1.tag(RepeaterDayPortion.new(:am))
386
+ elsif [:afternoon, :evening, :night].include?(t1tag.type)
387
+ puts "--#{t1tag.type}->pm" if Chronic.debug
388
+ t1.untag(RepeaterDayPortion)
389
+ t1.tag(RepeaterDayPortion.new(:pm))
390
+ end
391
+ end
392
+
393
+ # tokens.each_with_index do |t0, i|
394
+ # t1 = tokens[i + 1]
395
+ # if t1 && (t1tag = t1.get_tag(RepeaterDayPortion)) && t0.get_tag(RepeaterTime)
396
+ # if [:morning].include?(t1tag.type)
397
+ # puts '--morning->am' if Chronic.debug
398
+ # t1.untag(RepeaterDayPortion)
399
+ # t1.tag(RepeaterDayPortion.new(:am))
400
+ # elsif [:afternoon, :evening, :night].include?(t1tag.type)
401
+ # puts "--#{t1tag.type}->pm" if Chronic.debug
402
+ # t1.untag(RepeaterDayPortion)
403
+ # t1.tag(RepeaterDayPortion.new(:pm))
404
+ # end
405
+ # end
406
+ # end
350
407
 
351
408
  # handle ambiguous times if :ambiguous_time_range is specified
352
409
  if options[:ambiguous_time_range] != :none
@@ -10,9 +10,9 @@ module Chronic
10
10
  end
11
11
 
12
12
  def self.scan_for_all(token)
13
- scanner = {/past/ => :past,
14
- /future/ => :future,
15
- /in/ => :future}
13
+ scanner = {/\bpast\b/ => :past,
14
+ /\bfuture\b/ => :future,
15
+ /\bin\b/ => :future}
16
16
  scanner.keys.each do |scanner_item|
17
17
  return self.new(scanner[scanner_item]) if scanner_item =~ token.word
18
18
  end
@@ -33,6 +33,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
33
33
  def self.scan_for_day_names(token)
34
34
  scanner = {/^m[ou]n(day)?$/ => :monday,
35
35
  /^t(ue|eu|oo|u|)s(day)?$/ => :tuesday,
36
+ /^tue$/ => :tuesday,
36
37
  /^we(dnes|nds|nns)day$/ => :wednesday,
37
38
  /^wed$/ => :wednesday,
38
39
  /^th(urs|ers)day$/ => :thursday,
@@ -72,7 +73,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
72
73
  /^months?$/ => :month,
73
74
  /^fortnights?$/ => :fortnight,
74
75
  /^weeks?$/ => :week,
75
- /^weekends?$/ => :weekends,
76
+ /^weekends?$/ => :weekend,
76
77
  /^days?$/ => :day,
77
78
  /^hours?$/ => :hour,
78
79
  /^minutes?$/ => :minute,
@@ -104,7 +105,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
104
105
  end
105
106
 
106
107
  def this(pointer)
107
- !@now.nil? || raise("Start point must be set before calling #next")
108
+ !@now.nil? || raise("Start point must be set before calling #this")
108
109
  [:future, :past, :none].include?(pointer) || raise("First argument 'pointer' must be one of :past, :future, :none")
109
110
  end
110
111
 
@@ -19,14 +19,14 @@ class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
19
19
 
20
20
  case pointer
21
21
  when :future
22
- day_begin = Time.local(@now.year, @now.month, @now.day, @now.hour + 1)
23
- day_end = Time.local(@now.year, @now.month, @now.day) + DAY_SECONDS
22
+ day_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
23
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
24
24
  when :past
25
- day_begin = Time.local(@now.year, @now.month, @now.day)
26
- day_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
25
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
26
+ day_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
27
27
  when :none
28
- day_begin = Time.local(@now.year, @now.month, @now.day)
29
- day_end = Time.local(@now.year, @now.month, @now.day) + DAY_SECONDS
28
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
29
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
30
30
  end
31
31
 
32
32
  Chronic::Span.new(day_begin, day_end)
@@ -7,7 +7,7 @@ class Chronic::RepeaterDayName < Chronic::Repeater #:nodoc:
7
7
  direction = pointer == :future ? 1 : -1
8
8
 
9
9
  if !@current_day_start
10
- @current_day_start = Time.local(@now.year, @now.month, @now.day)
10
+ @current_day_start = Time.construct(@now.year, @now.month, @now.day)
11
11
  @current_day_start += direction * DAY_SECONDS
12
12
 
13
13
  day_num = symbol_to_number(@type)
@@ -34,7 +34,7 @@ class Chronic::RepeaterDayName < Chronic::Repeater #:nodoc:
34
34
  end
35
35
 
36
36
  def to_s
37
- super << '-dayofweek-' << @type.to_s
37
+ super << '-dayname-' << @type.to_s
38
38
  end
39
39
 
40
40
  private
@@ -28,27 +28,27 @@ class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
28
28
  full_day = 60 * 60 * 24
29
29
 
30
30
  if !@current_span
31
- now_seconds = @now - Time.local(@now.year, @now.month, @now.day)
31
+ now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
32
32
  if now_seconds < @range.begin
33
33
  case pointer
34
34
  when :future
35
- range_start = Time.local(@now.year, @now.month, @now.day) + @range.begin
35
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
36
36
  when :past
37
- range_start = Time.local(@now.year, @now.month, @now.day) - full_day + @range.begin
37
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
38
38
  end
39
39
  elsif now_seconds > @range.end
40
40
  case pointer
41
41
  when :future
42
- range_start = Time.local(@now.year, @now.month, @now.day) + full_day + @range.begin
42
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
43
43
  when :past
44
- range_start = Time.local(@now.year, @now.month, @now.day) + @range.begin
44
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
45
45
  end
46
46
  else
47
47
  case pointer
48
48
  when :future
49
- range_start = Time.local(@now.year, @now.month, @now.day) + full_day + @range.begin
49
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
50
50
  when :past
51
- range_start = Time.local(@now.year, @now.month, @now.day) - full_day + @range.begin
51
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
52
52
  end
53
53
  end
54
54
 
@@ -66,7 +66,7 @@ class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
66
66
  def this(context = :future)
67
67
  super
68
68
 
69
- range_start = Time.local(@now.year, @now.month, @now.day) + @range.begin
69
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
70
70
  @current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
71
71
  end
72
72
 
@@ -33,7 +33,7 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
33
33
 
34
34
  case pointer
35
35
  when :future
36
- this_fortnight_start = Time.local(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
36
+ this_fortnight_start = Time.construct(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
37
37
  sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
38
38
  sunday_repeater.start = @now
39
39
  sunday_repeater.this(:future)
@@ -41,7 +41,7 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
41
41
  this_fortnight_end = this_sunday_span.begin
42
42
  Chronic::Span.new(this_fortnight_start, this_fortnight_end)
43
43
  when :past
44
- this_fortnight_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
44
+ this_fortnight_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
45
45
  sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
46
46
  sunday_repeater.start = @now
47
47
  last_sunday_span = sunday_repeater.next(:past)
@@ -7,9 +7,9 @@ class Chronic::RepeaterHour < Chronic::Repeater #:nodoc:
7
7
  if !@current_hour_start
8
8
  case pointer
9
9
  when :future
10
- @current_hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour + 1)
10
+ @current_hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
11
11
  when :past
12
- @current_hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour - 1)
12
+ @current_hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour - 1)
13
13
  end
14
14
  else
15
15
  direction = pointer == :future ? 1 : -1
@@ -24,13 +24,13 @@ class Chronic::RepeaterHour < Chronic::Repeater #:nodoc:
24
24
 
25
25
  case pointer
26
26
  when :future
27
- hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
28
- hour_end = Time.local(@now.year, @now.month, @now.day, @now.hour + 1)
27
+ hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
28
+ hour_end = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
29
29
  when :past
30
- hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour)
31
- hour_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
30
+ hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour)
31
+ hour_end = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
32
32
  when :none
33
- hour_start = Time.local(@now.year, @now.month, @now.day, @now.hour)
33
+ hour_start = Time.construct(@now.year, @now.month, @now.day, @now.hour)
34
34
  hour_end = hour_begin + HOUR_SECONDS
35
35
  end
36
36
 
@@ -4,9 +4,19 @@ class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
4
4
  def next(pointer = :future)
5
5
  super
6
6
 
7
- direction = pointer == :future ? 1 : -1
7
+ if !@current_minute_start
8
+ case pointer
9
+ when :future
10
+ @current_minute_start = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
11
+ when :past
12
+ @current_minute_start = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min - 1)
13
+ end
14
+ else
15
+ direction = pointer == :future ? 1 : -1
16
+ @current_minute_start += direction * MINUTE_SECONDS
17
+ end
8
18
 
9
- raise 'not implemented'
19
+ Chronic::Span.new(@current_minute_start, @current_minute_start + MINUTE_SECONDS)
10
20
  end
11
21
 
12
22
  def this(pointer = :future)
@@ -15,13 +25,13 @@ class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
15
25
  case pointer
16
26
  when :future
17
27
  minute_begin = @now
18
- minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
28
+ minute_end = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
19
29
  when :past
20
- minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
30
+ minute_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
21
31
  minute_end = @now
22
32
  when :none
23
- minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
24
- minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
33
+ minute_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
34
+ minute_end = Time.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
25
35
  end
26
36
 
27
37
  Chronic::Span.new(minute_begin, minute_end)
@@ -6,12 +6,12 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
6
6
  super
7
7
 
8
8
  if !@current_month_start
9
- @current_month_start = offset_by(Time.local(@now.year, @now.month), 1, pointer)
9
+ @current_month_start = offset_by(Time.construct(@now.year, @now.month), 1, pointer)
10
10
  else
11
- @current_month_start = offset_by(Time.local(@current_month_start.year, @current_month_start.month), 1, pointer)
11
+ @current_month_start = offset_by(Time.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
12
12
  end
13
13
 
14
- Chronic::Span.new(@current_month_start, Time.local(@current_month_start.year, @current_month_start.month + 1))
14
+ Chronic::Span.new(@current_month_start, Time.construct(@current_month_start.year, @current_month_start.month + 1))
15
15
  end
16
16
 
17
17
  def this(pointer = :future)
@@ -19,14 +19,14 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
19
19
 
20
20
  case pointer
21
21
  when :future
22
- month_start = Time.local(@now.year, @now.month, @now.day + 1)
23
- month_end = self.offset_by(Time.local(@now.year, @now.month), 1, :future)
22
+ month_start = Time.construct(@now.year, @now.month, @now.day + 1)
23
+ month_end = self.offset_by(Time.construct(@now.year, @now.month), 1, :future)
24
24
  when :past
25
- month_start = Time.local(@now.year, @now.month)
26
- month_end = Time.local(@now.year, @now.month, @now.day)
25
+ month_start = Time.construct(@now.year, @now.month)
26
+ month_end = Time.construct(@now.year, @now.month, @now.day)
27
27
  when :none
28
- month_start = Time.local(@now.year, @now.month)
29
- month_end = self.offset_by(Time.local(@now.year, @now.month), 1, :future)
28
+ month_start = Time.construct(@now.year, @now.month)
29
+ month_end = self.offset_by(Time.construct(@now.year, @now.month), 1, :future)
30
30
  end
31
31
 
32
32
  Chronic::Span.new(month_start, month_end)
@@ -48,10 +48,14 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
48
48
  new_year += 1
49
49
  new_month -= YEAR_MONTHS
50
50
  end
51
- Time.local(new_year, new_month, time.day, time.hour, time.min, time.sec)
51
+ Time.construct(new_year, new_month, time.day, time.hour, time.min, time.sec)
52
52
  end
53
53
 
54
54
  def width
55
55
  MONTH_SECONDS
56
56
  end
57
+
58
+ def to_s
59
+ super << '-month'
60
+ end
57
61
  end
@@ -9,30 +9,30 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
9
9
  case pointer
10
10
  when :future
11
11
  if @now.month < target_month
12
- @current_month_begin = Time.local(@now.year, target_month)
12
+ @current_month_begin = Time.construct(@now.year, target_month)
13
13
  else @now.month > target_month
14
- @current_month_begin = Time.local(@now.year + 1, target_month)
14
+ @current_month_begin = Time.construct(@now.year + 1, target_month)
15
15
  end
16
16
  when :none
17
17
  if @now.month <= target_month
18
- @current_month_begin = Time.local(@now.year, target_month)
18
+ @current_month_begin = Time.construct(@now.year, target_month)
19
19
  else @now.month > target_month
20
- @current_month_begin = Time.local(@now.year + 1, target_month)
20
+ @current_month_begin = Time.construct(@now.year + 1, target_month)
21
21
  end
22
22
  when :past
23
23
  if @now.month > target_month
24
- @current_month_begin = Time.local(@now.year, target_month)
24
+ @current_month_begin = Time.construct(@now.year, target_month)
25
25
  else @now.month < target_month
26
- @current_month_begin = Time.local(@now.year - 1, target_month)
26
+ @current_month_begin = Time.construct(@now.year - 1, target_month)
27
27
  end
28
28
  end
29
29
  @current_month_begin || raise("Current month should be set by now")
30
30
  else
31
31
  case pointer
32
32
  when :future
33
- @current_month_begin = Time.local(@current_month_begin.year + 1, @current_month_begin.month)
33
+ @current_month_begin = Time.construct(@current_month_begin.year + 1, @current_month_begin.month)
34
34
  when :past
35
- @current_month_begin = Time.local(@current_month_begin.year - 1, @current_month_begin.month)
35
+ @current_month_begin = Time.construct(@current_month_begin.year - 1, @current_month_begin.month)
36
36
  end
37
37
  end
38
38
 
@@ -47,7 +47,7 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
47
47
  next_month_month = cur_month_month + 1
48
48
  end
49
49
 
50
- Chronic::Span.new(@current_month_begin, Time.local(next_month_year, next_month_month))
50
+ Chronic::Span.new(@current_month_begin, Time.construct(next_month_year, next_month_month))
51
51
  end
52
52
 
53
53
  def this(pointer = :future)
@@ -70,7 +70,7 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
70
70
  end
71
71
 
72
72
  def to_s
73
- super << '-month-' << @type.to_s
73
+ super << '-monthname-' << @type.to_s
74
74
  end
75
75
 
76
76
  private