chronic 0.3.0 → 0.4.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 +27 -0
  2. data/Manifest.txt +16 -5
  3. data/README.md +14 -8
  4. data/Rakefile +2 -8
  5. data/chronic.gemspec +8 -11
  6. data/lib/chronic.rb +21 -14
  7. data/lib/chronic/chronic.rb +38 -130
  8. data/lib/chronic/grabber.rb +11 -15
  9. data/lib/chronic/handlers.rb +63 -40
  10. data/lib/chronic/mini_date.rb +27 -0
  11. data/lib/chronic/numerizer.rb +120 -0
  12. data/lib/chronic/ordinal.rb +5 -10
  13. data/lib/chronic/pointer.rb +8 -10
  14. data/lib/chronic/repeater.rb +106 -109
  15. data/lib/chronic/repeaters/repeater_day.rb +43 -41
  16. data/lib/chronic/repeaters/repeater_day_name.rb +38 -36
  17. data/lib/chronic/repeaters/repeater_day_portion.rb +74 -73
  18. data/lib/chronic/repeaters/repeater_fortnight.rb +57 -55
  19. data/lib/chronic/repeaters/repeater_hour.rb +46 -44
  20. data/lib/chronic/repeaters/repeater_minute.rb +46 -44
  21. data/lib/chronic/repeaters/repeater_month.rb +52 -50
  22. data/lib/chronic/repeaters/repeater_month_name.rb +84 -80
  23. data/lib/chronic/repeaters/repeater_season.rb +97 -119
  24. data/lib/chronic/repeaters/repeater_season_name.rb +39 -39
  25. data/lib/chronic/repeaters/repeater_second.rb +32 -30
  26. data/lib/chronic/repeaters/repeater_time.rb +106 -101
  27. data/lib/chronic/repeaters/repeater_week.rb +60 -58
  28. data/lib/chronic/repeaters/repeater_weekday.rb +67 -58
  29. data/lib/chronic/repeaters/repeater_weekend.rb +54 -52
  30. data/lib/chronic/repeaters/repeater_year.rb +50 -48
  31. data/lib/chronic/scalar.rb +24 -16
  32. data/lib/chronic/separator.rb +15 -33
  33. data/lib/chronic/span.rb +31 -0
  34. data/lib/chronic/tag.rb +26 -0
  35. data/lib/chronic/time_zone.rb +7 -9
  36. data/lib/chronic/token.rb +35 -0
  37. data/test/helper.rb +5 -6
  38. data/test/test_Chronic.rb +5 -0
  39. data/test/test_Numerizer.rb +60 -39
  40. data/test/test_RepeaterHour.rb +4 -0
  41. data/test/test_parsing.rb +104 -13
  42. metadata +14 -20
  43. data/lib/chronic/numerizer/numerizer.rb +0 -97
@@ -1,52 +1,54 @@
1
- class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
2
- DAY_SECONDS = 86_400 # (24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterDay < Repeater #:nodoc:
3
+ DAY_SECONDS = 86_400 # (24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_day_start = nil
7
- end
8
-
9
- def next(pointer)
10
- super
11
-
12
- if !@current_day_start
13
- @current_day_start = Chronic.time_class.local(@now.year, @now.month, @now.day)
5
+ def initialize(type)
6
+ super
7
+ @current_day_start = nil
14
8
  end
15
9
 
16
- direction = pointer == :future ? 1 : -1
17
- @current_day_start += direction * DAY_SECONDS
10
+ def next(pointer)
11
+ super
18
12
 
19
- Chronic::Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
20
- end
13
+ if !@current_day_start
14
+ @current_day_start = Chronic.time_class.local(@now.year, @now.month, @now.day)
15
+ end
16
+
17
+ direction = pointer == :future ? 1 : -1
18
+ @current_day_start += direction * DAY_SECONDS
21
19
 
22
- def this(pointer = :future)
23
- super
24
-
25
- case pointer
26
- when :future
27
- day_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour + 1)
28
- day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
29
- when :past
30
- day_begin = Time.construct(@now.year, @now.month, @now.day)
31
- day_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
32
- when :none
33
- day_begin = Time.construct(@now.year, @now.month, @now.day)
34
- day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
20
+ Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
35
21
  end
36
22
 
37
- Chronic::Span.new(day_begin, day_end)
38
- end
23
+ def this(pointer = :future)
24
+ super
25
+
26
+ case pointer
27
+ when :future
28
+ day_begin = Time.construct(@now.year, @now.month, @now.day, @now.hour)
29
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
30
+ when :past
31
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
32
+ day_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
33
+ when :none
34
+ day_begin = Time.construct(@now.year, @now.month, @now.day)
35
+ day_end = Time.construct(@now.year, @now.month, @now.day) + DAY_SECONDS
36
+ end
37
+
38
+ Span.new(day_begin, day_end)
39
+ end
39
40
 
40
- def offset(span, amount, pointer)
41
- direction = pointer == :future ? 1 : -1
42
- span + direction * amount * DAY_SECONDS
43
- end
41
+ def offset(span, amount, pointer)
42
+ direction = pointer == :future ? 1 : -1
43
+ span + direction * amount * DAY_SECONDS
44
+ end
44
45
 
45
- def width
46
- DAY_SECONDS
47
- end
46
+ def width
47
+ DAY_SECONDS
48
+ end
48
49
 
49
- def to_s
50
- super << '-day'
50
+ def to_s
51
+ super << '-day'
52
+ end
51
53
  end
52
- end
54
+ end
@@ -1,51 +1,53 @@
1
- class Chronic::RepeaterDayName < Chronic::Repeater #:nodoc:
2
- DAY_SECONDS = 86400 # (24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterDayName < Repeater #:nodoc:
3
+ DAY_SECONDS = 86400 # (24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_day_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @current_day_start = nil
8
+ end
8
9
 
9
- def next(pointer)
10
- super
10
+ def next(pointer)
11
+ super
11
12
 
12
- direction = pointer == :future ? 1 : -1
13
+ direction = pointer == :future ? 1 : -1
13
14
 
14
- if !@current_day_start
15
- @current_day_start = Time.construct(@now.year, @now.month, @now.day)
16
- @current_day_start += direction * DAY_SECONDS
15
+ if !@current_date
16
+ @current_date = Date.new(@now.year, @now.month, @now.day)
17
+ @current_date += direction
17
18
 
18
- day_num = symbol_to_number(@type)
19
+ day_num = symbol_to_number(@type)
19
20
 
20
- while @current_day_start.wday != day_num
21
- @current_day_start += direction * DAY_SECONDS
21
+ while @current_date.wday != day_num
22
+ @current_date += direction
23
+ end
24
+ else
25
+ @current_date += direction * 7
22
26
  end
23
- else
24
- @current_day_start += direction * 7 * DAY_SECONDS
27
+ next_date = @current_date.succ
28
+ Span.new(Time.construct(@current_date.year, @current_date.month, @current_date.day), Time.construct(next_date.year, next_date.month, next_date.day))
25
29
  end
26
30
 
27
- Chronic::Span.new(@current_day_start, @current_day_start + DAY_SECONDS)
28
- end
29
-
30
- def this(pointer = :future)
31
- super
31
+ def this(pointer = :future)
32
+ super
32
33
 
33
- pointer = :future if pointer == :none
34
- self.next(pointer)
35
- end
34
+ pointer = :future if pointer == :none
35
+ self.next(pointer)
36
+ end
36
37
 
37
- def width
38
- DAY_SECONDS
39
- end
38
+ def width
39
+ DAY_SECONDS
40
+ end
40
41
 
41
- def to_s
42
- super << '-dayname-' << @type.to_s
43
- end
42
+ def to_s
43
+ super << '-dayname-' << @type.to_s
44
+ end
44
45
 
45
- private
46
+ private
46
47
 
47
- def symbol_to_number(sym)
48
- lookup = {:sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3, :thursday => 4, :friday => 5, :saturday => 6}
49
- lookup[sym] || raise("Invalid symbol specified")
48
+ def symbol_to_number(sym)
49
+ lookup = {:sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3, :thursday => 4, :friday => 5, :saturday => 6}
50
+ lookup[sym] || raise("Invalid symbol specified")
51
+ end
50
52
  end
51
- end
53
+ end
@@ -1,94 +1,95 @@
1
- class Chronic::RepeaterDayPortion < Chronic::Repeater #:nodoc:
2
- @@morning = (6 * 60 * 60)..(12 * 60 * 60) # 6am-12am
3
- @@afternoon = (13 * 60 * 60)..(17 * 60 * 60) # 1pm-5pm
4
- @@evening = (17 * 60 * 60)..(20 * 60 * 60) # 5pm-8pm
5
- @@night = (20 * 60 * 60)..(24 * 60 * 60) # 8pm-12pm
1
+ module Chronic
2
+ class RepeaterDayPortion < Repeater #:nodoc:
3
+ PORTIONS = {
4
+ :am => 0..(12 * 60 * 60 - 1),
5
+ :pm => (12 * 60 * 60)..(24 * 60 * 60 - 1),
6
+ :morning => (6 * 60 * 60)..(12 * 60 * 60), # 6am-12am,
7
+ :afternoon =>(13 * 60 * 60)..(17 * 60 * 60), # 1pm-5pm,
8
+ :evening => (17 * 60 * 60)..(20 * 60 * 60), # 5pm-8pm,
9
+ :night =>(20 * 60 * 60)..(24 * 60 * 60), # 8pm-12pm
10
+ }
6
11
 
7
- def initialize(type)
8
- super
9
- @current_span = nil
12
+ def initialize(type)
13
+ super
14
+ @current_span = nil
10
15
 
11
- if type.kind_of? Integer
12
- @range = (@type * 60 * 60)..((@type + 12) * 60 * 60)
13
- else
14
- lookup = {:am => 0..(12 * 60 * 60 - 1),
15
- :pm => (12 * 60 * 60)..(24 * 60 * 60 - 1),
16
- :morning => @@morning,
17
- :afternoon => @@afternoon,
18
- :evening => @@evening,
19
- :night => @@night}
20
- @range = lookup[type]
21
- lookup[type] || raise("Invalid type '#{type}' for RepeaterDayPortion")
16
+ if type.kind_of? Integer
17
+ @range = (@type * 60 * 60)..((@type + 12) * 60 * 60)
18
+ else
19
+ @range = PORTIONS[type]
20
+ @range || raise("Invalid type '#{type}' for RepeaterDayPortion")
21
+ end
22
+
23
+ @range || raise("Range should have been set by now")
22
24
  end
23
- @range || raise("Range should have been set by now")
24
- end
25
25
 
26
- def next(pointer)
27
- super
26
+ def next(pointer)
27
+ super
28
28
 
29
- full_day = 60 * 60 * 24
29
+ full_day = 60 * 60 * 24
30
30
 
31
- if !@current_span
32
- now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
33
- if now_seconds < @range.begin
34
- case pointer
35
- when :future
36
- range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
37
- when :past
38
- range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
39
- end
40
- elsif now_seconds > @range.end
41
- case pointer
42
- when :future
43
- range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
44
- when :past
45
- range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
31
+ if !@current_span
32
+ now_seconds = @now - Time.construct(@now.year, @now.month, @now.day)
33
+ if now_seconds < @range.begin
34
+ case pointer
35
+ when :future
36
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
37
+ when :past
38
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
39
+ end
40
+ elsif now_seconds > @range.end
41
+ case pointer
42
+ when :future
43
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
44
+ when :past
45
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
46
+ end
47
+ else
48
+ case pointer
49
+ when :future
50
+ range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
51
+ when :past
52
+ range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
53
+ end
46
54
  end
55
+
56
+ @current_span = Span.new(range_start, range_start + (@range.end - @range.begin))
47
57
  else
48
58
  case pointer
49
59
  when :future
50
- range_start = Time.construct(@now.year, @now.month, @now.day) + full_day + @range.begin
60
+ @current_span += full_day
51
61
  when :past
52
- range_start = Time.construct(@now.year, @now.month, @now.day) - full_day + @range.begin
62
+ @current_span -= full_day
53
63
  end
54
64
  end
55
-
56
- @current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
57
- else
58
- case pointer
59
- when :future
60
- @current_span += full_day
61
- when :past
62
- @current_span -= full_day
63
- end
64
65
  end
65
- end
66
66
 
67
- def this(context = :future)
68
- super
67
+ def this(context = :future)
68
+ super
69
69
 
70
- range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
71
- @current_span = Chronic::Span.new(range_start, range_start + (@range.end - @range.begin))
72
- end
70
+ range_start = Time.construct(@now.year, @now.month, @now.day) + @range.begin
71
+ @current_span = Span.new(range_start, range_start + (@range.end - @range.begin))
72
+ end
73
73
 
74
- def offset(span, amount, pointer)
75
- @now = span.begin
76
- portion_span = self.next(pointer)
77
- direction = pointer == :future ? 1 : -1
78
- portion_span + (direction * (amount - 1) * Chronic::RepeaterDay::DAY_SECONDS)
79
- end
74
+ def offset(span, amount, pointer)
75
+ @now = span.begin
76
+ portion_span = self.next(pointer)
77
+ direction = pointer == :future ? 1 : -1
78
+ portion_span + (direction * (amount - 1) * RepeaterDay::DAY_SECONDS)
79
+ end
80
80
 
81
- def width
82
- @range || raise("Range has not been set")
83
- return @current_span.width if @current_span
84
- if @type.kind_of? Integer
85
- return (12 * 60 * 60)
86
- else
87
- @range.end - @range.begin
81
+ def width
82
+ @range || raise("Range has not been set")
83
+ return @current_span.width if @current_span
84
+ if @type.kind_of? Integer
85
+ return (12 * 60 * 60)
86
+ else
87
+ @range.end - @range.begin
88
+ end
88
89
  end
89
- end
90
90
 
91
- def to_s
92
- super << '-dayportion-' << @type.to_s
91
+ def to_s
92
+ super << '-dayportion-' << @type.to_s
93
+ end
93
94
  end
94
- end
95
+ end
@@ -1,70 +1,72 @@
1
- class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
2
- FORTNIGHT_SECONDS = 1_209_600 # (14 * 24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterFortnight < Repeater #:nodoc:
3
+ FORTNIGHT_SECONDS = 1_209_600 # (14 * 24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_fortnight_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @current_fortnight_start = nil
8
+ end
9
+
10
+ def next(pointer)
11
+ super
8
12
 
9
- def next(pointer)
10
- super
13
+ if !@current_fortnight_start
14
+ case pointer
15
+ when :future
16
+ sunday_repeater = RepeaterDayName.new(:sunday)
17
+ sunday_repeater.start = @now
18
+ next_sunday_span = sunday_repeater.next(:future)
19
+ @current_fortnight_start = next_sunday_span.begin
20
+ when :past
21
+ sunday_repeater = RepeaterDayName.new(:sunday)
22
+ sunday_repeater.start = (@now + RepeaterDay::DAY_SECONDS)
23
+ 2.times { sunday_repeater.next(:past) }
24
+ last_sunday_span = sunday_repeater.next(:past)
25
+ @current_fortnight_start = last_sunday_span.begin
26
+ end
27
+ else
28
+ direction = pointer == :future ? 1 : -1
29
+ @current_fortnight_start += direction * FORTNIGHT_SECONDS
30
+ end
31
+
32
+ Span.new(@current_fortnight_start, @current_fortnight_start + FORTNIGHT_SECONDS)
33
+ end
34
+
35
+ def this(pointer = :future)
36
+ super
37
+
38
+ pointer = :future if pointer == :none
11
39
 
12
- if !@current_fortnight_start
13
40
  case pointer
14
41
  when :future
15
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
42
+ this_fortnight_start = Time.construct(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS
43
+ sunday_repeater = RepeaterDayName.new(:sunday)
16
44
  sunday_repeater.start = @now
17
- next_sunday_span = sunday_repeater.next(:future)
18
- @current_fortnight_start = next_sunday_span.begin
45
+ sunday_repeater.this(:future)
46
+ this_sunday_span = sunday_repeater.this(:future)
47
+ this_fortnight_end = this_sunday_span.begin
48
+ Span.new(this_fortnight_start, this_fortnight_end)
19
49
  when :past
20
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
21
- sunday_repeater.start = (@now + Chronic::RepeaterDay::DAY_SECONDS)
22
- 2.times { sunday_repeater.next(:past) }
50
+ this_fortnight_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
51
+ sunday_repeater = RepeaterDayName.new(:sunday)
52
+ sunday_repeater.start = @now
23
53
  last_sunday_span = sunday_repeater.next(:past)
24
- @current_fortnight_start = last_sunday_span.begin
54
+ this_fortnight_start = last_sunday_span.begin
55
+ Span.new(this_fortnight_start, this_fortnight_end)
25
56
  end
26
- else
27
- direction = pointer == :future ? 1 : -1
28
- @current_fortnight_start += direction * FORTNIGHT_SECONDS
29
57
  end
30
58
 
31
- Chronic::Span.new(@current_fortnight_start, @current_fortnight_start + FORTNIGHT_SECONDS)
32
- end
33
-
34
- def this(pointer = :future)
35
- super
36
-
37
- pointer = :future if pointer == :none
38
-
39
- case pointer
40
- when :future
41
- this_fortnight_start = Time.construct(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
42
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
43
- sunday_repeater.start = @now
44
- sunday_repeater.this(:future)
45
- this_sunday_span = sunday_repeater.this(:future)
46
- this_fortnight_end = this_sunday_span.begin
47
- Chronic::Span.new(this_fortnight_start, this_fortnight_end)
48
- when :past
49
- this_fortnight_end = Time.construct(@now.year, @now.month, @now.day, @now.hour)
50
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
51
- sunday_repeater.start = @now
52
- last_sunday_span = sunday_repeater.next(:past)
53
- this_fortnight_start = last_sunday_span.begin
54
- Chronic::Span.new(this_fortnight_start, this_fortnight_end)
59
+ def offset(span, amount, pointer)
60
+ direction = pointer == :future ? 1 : -1
61
+ span + direction * amount * FORTNIGHT_SECONDS
55
62
  end
56
- end
57
63
 
58
- def offset(span, amount, pointer)
59
- direction = pointer == :future ? 1 : -1
60
- span + direction * amount * FORTNIGHT_SECONDS
61
- end
62
-
63
- def width
64
- FORTNIGHT_SECONDS
65
- end
64
+ def width
65
+ FORTNIGHT_SECONDS
66
+ end
66
67
 
67
- def to_s
68
- super << '-fortnight'
68
+ def to_s
69
+ super << '-fortnight'
70
+ end
69
71
  end
70
- end
72
+ end