chronic 0.1.2 → 0.1.3

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/README CHANGED
@@ -12,6 +12,7 @@ Chronic can be installed via RubyGems:
12
12
 
13
13
  You can parse strings containing a natural language date using the Chronic.parse method.
14
14
 
15
+ require 'rubygems'
15
16
  require 'chronic'
16
17
 
17
18
  Time.now #=> Sun Aug 27 23:18:25 PDT 2006
data/lib/chronic.rb CHANGED
@@ -34,8 +34,9 @@ require 'chronic/ordinal'
34
34
  require 'chronic/separator'
35
35
 
36
36
  module Chronic
37
+ @version = "0.1.3"
37
38
  def self.debug=(val); @debug = val; end
38
39
  end
39
40
 
40
- Chronic.debug = false
41
+ Chronic.debug = true
41
42
 
@@ -50,7 +50,7 @@ module Chronic
50
50
  specified_options.keys.each do |key|
51
51
  default_options.keys.include?(key) || raise(InvalidArgumentException, "#{key} is not a valid option key.")
52
52
  end
53
- [:past, :future].include?(options[:context]) || raise(InvalidArgumentException, "Invalid value '#{options[:context]}' for :context specified. Valid values are :past and :future.")
53
+ [:past, :future, :none].include?(options[:context]) || raise(InvalidArgumentException, "Invalid value ':#{options[:context]}' for :context specified. Valid values are :past and :future.")
54
54
 
55
55
  # store now for later =)
56
56
  @now = options[:now]
@@ -73,7 +73,7 @@ module Chronic
73
73
  # strip any non-tagged tokens
74
74
  @tokens = @tokens.select { |token| token.tagged? }
75
75
 
76
- if @debug
76
+ if true
77
77
  puts "+---------------------------------------------------"
78
78
  puts "| " + @tokens.to_s
79
79
  puts "+---------------------------------------------------"
@@ -35,6 +35,7 @@ module Chronic
35
35
  self.definitions[:date].each do |handler|
36
36
  if handler.match(tokens, self.definitions)
37
37
  good_tokens = tokens.select { |o| !o.get_tag Separator }
38
+ puts "--#{handler}"
38
39
  return self.send(handler.handler_method, good_tokens, options)
39
40
  end
40
41
  end
@@ -67,6 +68,7 @@ module Chronic
67
68
  end
68
69
 
69
70
  # I guess you're out of luck!
71
+ puts "--SUCKY"
70
72
  return nil
71
73
  end
72
74
 
@@ -282,14 +284,25 @@ module Chronic
282
284
 
283
285
  head = repeaters.shift
284
286
  head.start = @now
285
-
287
+
286
288
  case grabber.type
287
- when :last: outer_span = head.next(:past)
288
- when :this: outer_span = head.this(options[:context])
289
- when :next: outer_span = head.next(:future)
289
+ when :last
290
+ outer_span = head.next(:past)
291
+ when :this
292
+ puts "--THIS"
293
+ puts "--#{repeaters}"
294
+ if repeaters.size > 0
295
+ puts "--NONE"
296
+ outer_span = head.this(:none)
297
+ else
298
+ outer_span = head.this(options[:context])
299
+ end
300
+ when :next
301
+ outer_span = head.next(:future)
290
302
  else raise(ChronicPain, "Invalid grabber")
291
303
  end
292
304
 
305
+ puts "--#{outer_span}"
293
306
  anchor = find_within(repeaters, outer_span, pointer)
294
307
  end
295
308
 
@@ -307,11 +320,12 @@ module Chronic
307
320
  # Returns a Span representing the innermost time span
308
321
  # or nil if no repeater union could be found
309
322
  def find_within(tags, span, pointer) #:nodoc:
323
+ puts "--#{span}"
310
324
  return span if tags.empty?
311
325
 
312
326
  head, *rest = tags
313
327
  head.start = pointer == :future ? span.begin : span.end
314
- h = head.this(pointer)
328
+ h = head.this(:none)
315
329
 
316
330
  if span.include?(h.begin) || span.include?(h.end)
317
331
  return find_within(rest, h, pointer)
@@ -6,7 +6,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
6
6
  if t = self.scan_for_day_names(tokens[i]) then tokens[i].tag(t); next end
7
7
  if t = self.scan_for_day_portions(tokens[i]) then tokens[i].tag(t); next end
8
8
  if t = self.scan_for_times(tokens[i], options) then tokens[i].tag(t); next end
9
- if t = self.scan_for_units(tokens[i]) then tokens[i].tag(t); next end
9
+ if t = self.scan_for_units(tokens[i]) then tokens[i].tag(t); next end
10
10
  end
11
11
  tokens
12
12
  end
@@ -20,7 +20,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
20
20
  /^jun\.?e?$/ => :june,
21
21
  /^jul\.?y?$/ => :july,
22
22
  /^aug\.?(ust)?$/ => :august,
23
- /^sep\.?(tember)?$/ => :september,
23
+ /^sep\.?(t\.?|tember)?$/ => :september,
24
24
  /^oct\.?(ober)?$/ => :october,
25
25
  /^nov\.?(ember)?$/ => :november,
26
26
  /^dec\.?(ember)?$/ => :december}
@@ -52,7 +52,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
52
52
  /^mornings?$/ => :morning,
53
53
  /^afternoons?$/ => :afternoon,
54
54
  /^evenings?$/ => :evening,
55
- /^nights?$/ => :night}
55
+ /^(night|nite)s?$/ => :night}
56
56
  scanner.keys.each do |scanner_item|
57
57
  return Chronic::RepeaterDayPortion.new(scanner[scanner_item]) if scanner_item =~ token.word
58
58
  end
@@ -105,7 +105,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
105
105
 
106
106
  def this(pointer)
107
107
  !@now.nil? || raise("Start point must be set before calling #next")
108
- [:future, :past].include?(pointer) || raise("First argument 'pointer' must be one of :past or :future")
108
+ [:future, :past, :none].include?(pointer) || raise("First argument 'pointer' must be one of :past, :future, :none")
109
109
  end
110
110
 
111
111
  def to_s
@@ -24,6 +24,9 @@ class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
24
24
  when :past
25
25
  day_begin = Time.local(@now.year, @now.month, @now.day)
26
26
  day_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
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
27
30
  end
28
31
 
29
32
  Chronic::Span.new(day_begin, day_end)
@@ -25,6 +25,7 @@ class Chronic::RepeaterDayName < Chronic::Repeater #:nodoc:
25
25
  def this(pointer = :future)
26
26
  super
27
27
 
28
+ pointer = :future if pointer == :none
28
29
  self.next(pointer)
29
30
  end
30
31
 
@@ -29,6 +29,8 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
29
29
  def this(pointer = :future)
30
30
  super
31
31
 
32
+ pointer = :future if pointer == :none
33
+
32
34
  case pointer
33
35
  when :future
34
36
  this_fortnight_start = Time.local(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
@@ -42,7 +44,6 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
42
44
  this_fortnight_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
43
45
  sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
44
46
  sunday_repeater.start = @now
45
- #sunday_repeater.next(:past)
46
47
  last_sunday_span = sunday_repeater.next(:past)
47
48
  this_fortnight_start = last_sunday_span.begin
48
49
  Chronic::Span.new(this_fortnight_start, this_fortnight_end)
@@ -1,9 +1,30 @@
1
1
  class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
2
2
  MINUTE_SECONDS = 60
3
3
 
4
+ def next(pointer = :future)
5
+ super
6
+
7
+ direction = pointer == :future ? 1 : -1
8
+
9
+ raise 'not implemented'
10
+ end
11
+
4
12
  def this(pointer = :future)
5
- minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
6
- Chronic::Span.new(minute_begin, minute_begin + MINUTE_SECONDS)
13
+ super
14
+
15
+ case pointer
16
+ when :future
17
+ minute_begin = @now
18
+ minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
19
+ when :past
20
+ minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
21
+ minute_end = @now
22
+ 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
25
+ end
26
+
27
+ Chronic::Span.new(minute_begin, minute_end)
7
28
  end
8
29
 
9
30
  def offset(span, amount, pointer)
@@ -24,6 +24,9 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
24
24
  when :past
25
25
  month_start = Time.local(@now.year, @now.month)
26
26
  month_end = Time.local(@now.year, @now.month, @now.day)
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)
27
30
  end
28
31
 
29
32
  Chronic::Span.new(month_start, month_end)
@@ -47,6 +47,8 @@ class Chronic::RepeaterMonthName < Chronic::Repeater #:nodoc:
47
47
  def this(pointer = :future)
48
48
  super
49
49
 
50
+ pointer = :future if pointer == :none
51
+
50
52
  self.next(pointer)
51
53
  end
52
54
 
@@ -16,6 +16,8 @@ class Chronic::RepeaterSecond < Chronic::Repeater #:nodoc:
16
16
  end
17
17
 
18
18
  def this(pointer = :future)
19
+ super
20
+
19
21
  Chronic::Span.new(@now, @now + 1)
20
22
  end
21
23
 
@@ -92,7 +92,10 @@ class Chronic::RepeaterTime < Chronic::Repeater #:nodoc:
92
92
  end
93
93
 
94
94
  def this(context = :future)
95
- [:future, :past].include?(context) || raise("First argument 'context' must be one of :past or :future")
95
+ super
96
+
97
+ context = :future if context == :none
98
+
96
99
  self.next(context)
97
100
  end
98
101
 
@@ -44,6 +44,12 @@ class Chronic::RepeaterWeek < Chronic::Repeater #:nodoc:
44
44
  last_sunday_span = sunday_repeater.next(:past)
45
45
  this_week_start = last_sunday_span.begin
46
46
  Chronic::Span.new(this_week_start, this_week_end)
47
+ when :none
48
+ sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
49
+ sunday_repeater.start = @now
50
+ last_sunday_span = sunday_repeater.next(:past)
51
+ this_week_start = last_sunday_span.begin
52
+ Chronic::Span.new(this_week_start, this_week_start + WEEK_SECONDS)
47
53
  end
48
54
  end
49
55
 
@@ -28,6 +28,9 @@ class Chronic::RepeaterYear < Chronic::Repeater #:nodoc:
28
28
  when :past
29
29
  this_year_start = Time.local(@now.year, 1, 1)
30
30
  this_year_end = Time.local(@now.year, @now.month, @now.day)
31
+ when :none
32
+ this_year_start = Time.local(@now.year, 1, 1)
33
+ this_year_end = Time.local(@now.year + 1, 1, 1)
31
34
  end
32
35
 
33
36
  Chronic::Span.new(this_year_start, this_year_end)
@@ -40,7 +40,7 @@ module Chronic
40
40
  end
41
41
 
42
42
  def self.scan_for_years(token, post_token)
43
- if token.word =~ /^\d\d(\d\d)?$/
43
+ if token.word =~ /^([1-9]\d)?\d\d?$/
44
44
  unless post_token && %w{am pm morning afternoon evening night}.include?(post_token)
45
45
  return ScalarYear.new(token.word.to_i)
46
46
  end
data/test/test_parsing.rb CHANGED
@@ -300,10 +300,22 @@ class TestParsing < Test::Unit::TestCase
300
300
  assert_equal Time.local(2006, 8, 16, 13, 59, 59), time
301
301
  end
302
302
 
303
- def test_parse_guess_grr
303
+ def test_parse_guess_grr
304
304
  time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00)
305
305
  assert_equal Time.local(2006, 8, 15, 16), time
306
306
 
307
+ time = Chronic.parse("today at 9:00", :now => @time_2006_08_16_14_00_00)
308
+ assert_equal Time.local(2006, 8, 16, 9), time
309
+
310
+ time = Chronic.parse("today at 2100", :now => @time_2006_08_16_14_00_00)
311
+ assert_equal Time.local(2006, 8, 16, 21), time
312
+
313
+ time = Chronic.parse("this day at 0900", :now => @time_2006_08_16_14_00_00)
314
+ assert_equal Time.local(2006, 8, 16, 9), time
315
+
316
+ time = Chronic.parse("tomorrow at 0900", :now => @time_2006_08_16_14_00_00)
317
+ assert_equal Time.local(2006, 8, 17, 9), time
318
+
307
319
  time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
308
320
  assert_equal Time.local(2006, 8, 15, 4), time
309
321
 
@@ -324,6 +336,9 @@ class TestParsing < Test::Unit::TestCase
324
336
  time = Chronic.parse("today at 6:00pm", :now => @time_2006_08_16_14_00_00)
325
337
  assert_equal Time.local(2006, 8, 16, 18), time
326
338
 
339
+ time = Chronic.parse("today at 6:00am", :now => @time_2006_08_16_14_00_00)
340
+ assert_equal Time.local(2006, 8, 16, 6), time
341
+
327
342
  time = Chronic.parse("this day 1800", :now => @time_2006_08_16_14_00_00)
328
343
  assert_equal Time.local(2006, 8, 16, 18), time
329
344
 
@@ -358,7 +373,7 @@ class TestParsing < Test::Unit::TestCase
358
373
  assert_equal Time.local(2006, 7, 26, 14, 30, 30), time
359
374
 
360
375
  time = Chronic.parse("3 days ago", :now => @time_2006_08_16_14_00_00)
361
- assert_equal Time.local(2006, 8, 13, 14, 0, 30), time
376
+ assert_equal Time.local(2006, 8, 13, 14), time
362
377
 
363
378
  #time = Chronic.parse("1 monday ago", :now => @time_2006_08_16_14_00_00)
364
379
  #assert_equal Time.local(2006, 8, 14, 12), time
@@ -367,7 +382,7 @@ class TestParsing < Test::Unit::TestCase
367
382
  assert_equal Time.local(2006, 8, 12, 9), time
368
383
 
369
384
  time = Chronic.parse("7 hours ago", :now => @time_2006_08_16_14_00_00)
370
- assert_equal Time.local(2006, 8, 16, 7, 0, 30), time
385
+ assert_equal Time.local(2006, 8, 16, 7), time
371
386
 
372
387
  time = Chronic.parse("3 minutes ago", :now => @time_2006_08_16_14_00_00)
373
388
  assert_equal Time.local(2006, 8, 16, 13, 57), time
@@ -390,13 +405,13 @@ class TestParsing < Test::Unit::TestCase
390
405
  assert_equal Time.local(2006, 8, 23, 14, 30, 30), time
391
406
 
392
407
  time = Chronic.parse("1 day hence", :now => @time_2006_08_16_14_00_00)
393
- assert_equal Time.local(2006, 8, 17, 14, 0, 30), time
408
+ assert_equal Time.local(2006, 8, 17, 14), time
394
409
 
395
410
  time = Chronic.parse("5 mornings hence", :now => @time_2006_08_16_14_00_00)
396
411
  assert_equal Time.local(2006, 8, 21, 9), time
397
412
 
398
413
  time = Chronic.parse("1 hour from now", :now => @time_2006_08_16_14_00_00)
399
- assert_equal Time.local(2006, 8, 16, 15, 0, 30), time
414
+ assert_equal Time.local(2006, 8, 16, 15), time
400
415
 
401
416
  time = Chronic.parse("20 minutes hence", :now => @time_2006_08_16_14_00_00)
402
417
  assert_equal Time.local(2006, 8, 16, 14, 20), time
@@ -407,7 +422,7 @@ class TestParsing < Test::Unit::TestCase
407
422
 
408
423
  def test_parse_guess_p_s_r
409
424
  time = Chronic.parse("in 3 hours", :now => @time_2006_08_16_14_00_00)
410
- assert_equal Time.local(2006, 8, 16, 17, 0, 30), time
425
+ assert_equal Time.local(2006, 8, 16, 17), time
411
426
  end
412
427
 
413
428
  def test_parse_guess_s_r_p_a
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: chronic
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.2
7
- date: 2006-09-16 00:00:00 -07:00
6
+ version: 0.1.3
7
+ date: 2006-10-20 00:00:00 -07:00
8
8
  summary: A natural language date parser
9
9
  require_paths:
10
10
  - lib