chronic 0.3.0 → 0.4.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 (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,73 +1,75 @@
1
- class Chronic::RepeaterWeek < Chronic::Repeater #:nodoc:
2
- WEEK_SECONDS = 604800 # (7 * 24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterWeek < Repeater #:nodoc:
3
+ WEEK_SECONDS = 604800 # (7 * 24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_week_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @current_week_start = nil
8
+ end
9
+
10
+ def next(pointer)
11
+ super
8
12
 
9
- def next(pointer)
10
- super
13
+ if !@current_week_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_week_start = next_sunday_span.begin
20
+ when :past
21
+ sunday_repeater = RepeaterDayName.new(:sunday)
22
+ sunday_repeater.start = (@now + RepeaterDay::DAY_SECONDS)
23
+ sunday_repeater.next(:past)
24
+ last_sunday_span = sunday_repeater.next(:past)
25
+ @current_week_start = last_sunday_span.begin
26
+ end
27
+ else
28
+ direction = pointer == :future ? 1 : -1
29
+ @current_week_start += direction * WEEK_SECONDS
30
+ end
31
+
32
+ Span.new(@current_week_start, @current_week_start + WEEK_SECONDS)
33
+ end
34
+
35
+ def this(pointer = :future)
36
+ super
11
37
 
12
- if !@current_week_start
13
38
  case pointer
14
39
  when :future
15
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
40
+ this_week_start = Chronic.time_class.local(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS
41
+ sunday_repeater = RepeaterDayName.new(:sunday)
16
42
  sunday_repeater.start = @now
17
- next_sunday_span = sunday_repeater.next(:future)
18
- @current_week_start = next_sunday_span.begin
43
+ this_sunday_span = sunday_repeater.this(:future)
44
+ this_week_end = this_sunday_span.begin
45
+ Span.new(this_week_start, this_week_end)
19
46
  when :past
20
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
21
- sunday_repeater.start = (@now + Chronic::RepeaterDay::DAY_SECONDS)
22
- sunday_repeater.next(:past)
47
+ this_week_end = Chronic.time_class.local(@now.year, @now.month, @now.day, @now.hour)
48
+ sunday_repeater = RepeaterDayName.new(:sunday)
49
+ sunday_repeater.start = @now
23
50
  last_sunday_span = sunday_repeater.next(:past)
24
- @current_week_start = last_sunday_span.begin
51
+ this_week_start = last_sunday_span.begin
52
+ Span.new(this_week_start, this_week_end)
53
+ when :none
54
+ sunday_repeater = RepeaterDayName.new(:sunday)
55
+ sunday_repeater.start = @now
56
+ last_sunday_span = sunday_repeater.next(:past)
57
+ this_week_start = last_sunday_span.begin
58
+ Span.new(this_week_start, this_week_start + WEEK_SECONDS)
25
59
  end
26
- else
27
- direction = pointer == :future ? 1 : -1
28
- @current_week_start += direction * WEEK_SECONDS
29
60
  end
30
61
 
31
- Chronic::Span.new(@current_week_start, @current_week_start + WEEK_SECONDS)
32
- end
33
-
34
- def this(pointer = :future)
35
- super
36
-
37
- case pointer
38
- when :future
39
- this_week_start = Chronic.time_class.local(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
40
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
41
- sunday_repeater.start = @now
42
- this_sunday_span = sunday_repeater.this(:future)
43
- this_week_end = this_sunday_span.begin
44
- Chronic::Span.new(this_week_start, this_week_end)
45
- when :past
46
- this_week_end = Chronic.time_class.local(@now.year, @now.month, @now.day, @now.hour)
47
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
48
- sunday_repeater.start = @now
49
- last_sunday_span = sunday_repeater.next(:past)
50
- this_week_start = last_sunday_span.begin
51
- Chronic::Span.new(this_week_start, this_week_end)
52
- when :none
53
- sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
54
- sunday_repeater.start = @now
55
- last_sunday_span = sunday_repeater.next(:past)
56
- this_week_start = last_sunday_span.begin
57
- Chronic::Span.new(this_week_start, this_week_start + WEEK_SECONDS)
62
+ def offset(span, amount, pointer)
63
+ direction = pointer == :future ? 1 : -1
64
+ span + direction * amount * WEEK_SECONDS
58
65
  end
59
- end
60
66
 
61
- def offset(span, amount, pointer)
62
- direction = pointer == :future ? 1 : -1
63
- span + direction * amount * WEEK_SECONDS
64
- end
65
-
66
- def width
67
- WEEK_SECONDS
68
- end
67
+ def width
68
+ WEEK_SECONDS
69
+ end
69
70
 
70
- def to_s
71
- super << '-week'
71
+ def to_s
72
+ super << '-week'
73
+ end
72
74
  end
73
- end
75
+ end
@@ -1,77 +1,86 @@
1
- class Chronic::RepeaterWeekday < Chronic::Repeater #:nodoc:
2
- WEEK_WEEKDAYS = 5
3
- DAY_SECONDS = 86400 # (24 * 60 * 60)
4
-
5
- def initialize(type)
6
- super
7
- @current_weekday_start = nil
8
- end
9
-
10
- def next(pointer)
11
- super
1
+ module Chronic
2
+ class RepeaterWeekday < Repeater #:nodoc:
3
+ DAY_SECONDS = 86400 # (24 * 60 * 60)
4
+ DAYS = {
5
+ :sunday => 0,
6
+ :monday => 1,
7
+ :tuesday => 2,
8
+ :wednesday => 3,
9
+ :thursday => 4,
10
+ :friday => 5,
11
+ :saturday => 6
12
+ }
13
+
14
+ def initialize(type)
15
+ super
16
+ @current_weekday_start = nil
17
+ end
12
18
 
13
- direction = pointer == :future ? 1 : -1
19
+ def next(pointer)
20
+ super
14
21
 
15
- if !@current_weekday_start
16
- @current_weekday_start = Time.construct(@now.year, @now.month, @now.day)
17
- @current_weekday_start += direction * DAY_SECONDS
22
+ direction = pointer == :future ? 1 : -1
18
23
 
19
- until is_weekday?(@current_weekday_start.wday)
24
+ if !@current_weekday_start
25
+ @current_weekday_start = Time.construct(@now.year, @now.month, @now.day)
20
26
  @current_weekday_start += direction * DAY_SECONDS
27
+
28
+ until is_weekday?(@current_weekday_start.wday)
29
+ @current_weekday_start += direction * DAY_SECONDS
30
+ end
31
+ else
32
+ loop do
33
+ @current_weekday_start += direction * DAY_SECONDS
34
+ break if is_weekday?(@current_weekday_start.wday)
35
+ end
21
36
  end
22
- else
23
- loop do
24
- @current_weekday_start += direction * DAY_SECONDS
25
- break if is_weekday?(@current_weekday_start.wday)
26
- end
27
- end
28
37
 
29
- Chronic::Span.new(@current_weekday_start, @current_weekday_start + DAY_SECONDS)
30
- end
38
+ Span.new(@current_weekday_start, @current_weekday_start + DAY_SECONDS)
39
+ end
31
40
 
32
- def this(pointer = :future)
33
- super
41
+ def this(pointer = :future)
42
+ super
34
43
 
35
- case pointer
36
- when :past
37
- self.next(:past)
38
- when :future, :none
39
- self.next(:future)
44
+ case pointer
45
+ when :past
46
+ self.next(:past)
47
+ when :future, :none
48
+ self.next(:future)
49
+ end
40
50
  end
41
- end
42
51
 
43
- def offset(span, amount, pointer)
44
- direction = pointer == :future ? 1 : -1
52
+ def offset(span, amount, pointer)
53
+ direction = pointer == :future ? 1 : -1
45
54
 
46
- num_weekdays_passed = 0; offset = 0
47
- until num_weekdays_passed == amount
48
- offset += direction * DAY_SECONDS
49
- num_weekdays_passed += 1 if is_weekday?((span.begin+offset).wday)
50
- end
55
+ num_weekdays_passed = 0; offset = 0
56
+ until num_weekdays_passed == amount
57
+ offset += direction * DAY_SECONDS
58
+ num_weekdays_passed += 1 if is_weekday?((span.begin+offset).wday)
59
+ end
51
60
 
52
- span + offset
53
- end
61
+ span + offset
62
+ end
54
63
 
55
- def width
56
- DAY_SECONDS
57
- end
64
+ def width
65
+ DAY_SECONDS
66
+ end
58
67
 
59
- def to_s
60
- super << '-weekday'
61
- end
68
+ def to_s
69
+ super << '-weekday'
70
+ end
62
71
 
63
- private
72
+ private
64
73
 
65
- def is_weekend?(day)
66
- day == symbol_to_number(:saturday) || day == symbol_to_number(:sunday)
67
- end
74
+ def is_weekend?(day)
75
+ day == symbol_to_number(:saturday) || day == symbol_to_number(:sunday)
76
+ end
68
77
 
69
- def is_weekday?(day)
70
- !is_weekend?(day)
71
- end
78
+ def is_weekday?(day)
79
+ !is_weekend?(day)
80
+ end
72
81
 
73
- def symbol_to_number(sym)
74
- lookup = {:sunday => 0, :monday => 1, :tuesday => 2, :wednesday => 3, :thursday => 4, :friday => 5, :saturday => 6}
75
- lookup[sym] || raise("Invalid symbol specified")
82
+ def symbol_to_number(sym)
83
+ DAYS[sym] || raise("Invalid symbol specified")
84
+ end
76
85
  end
77
- end
86
+ end
@@ -1,65 +1,67 @@
1
- class Chronic::RepeaterWeekend < Chronic::Repeater #:nodoc:
2
- WEEKEND_SECONDS = 172_800 # (2 * 24 * 60 * 60)
1
+ module Chronic
2
+ class RepeaterWeekend < Repeater #:nodoc:
3
+ WEEKEND_SECONDS = 172_800 # (2 * 24 * 60 * 60)
3
4
 
4
- def initialize(type)
5
- super
6
- @current_week_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @current_week_start = nil
8
+ end
9
+
10
+ def next(pointer)
11
+ super
12
+
13
+ if !@current_week_start
14
+ case pointer
15
+ when :future
16
+ saturday_repeater = RepeaterDayName.new(:saturday)
17
+ saturday_repeater.start = @now
18
+ next_saturday_span = saturday_repeater.next(:future)
19
+ @current_week_start = next_saturday_span.begin
20
+ when :past
21
+ saturday_repeater = RepeaterDayName.new(:saturday)
22
+ saturday_repeater.start = (@now + RepeaterDay::DAY_SECONDS)
23
+ last_saturday_span = saturday_repeater.next(:past)
24
+ @current_week_start = last_saturday_span.begin
25
+ end
26
+ else
27
+ direction = pointer == :future ? 1 : -1
28
+ @current_week_start += direction * RepeaterWeek::WEEK_SECONDS
29
+ end
8
30
 
9
- def next(pointer)
10
- super
31
+ Span.new(@current_week_start, @current_week_start + WEEKEND_SECONDS)
32
+ end
33
+
34
+ def this(pointer = :future)
35
+ super
11
36
 
12
- if !@current_week_start
13
37
  case pointer
14
- when :future
15
- saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
38
+ when :future, :none
39
+ saturday_repeater = RepeaterDayName.new(:saturday)
16
40
  saturday_repeater.start = @now
17
- next_saturday_span = saturday_repeater.next(:future)
18
- @current_week_start = next_saturday_span.begin
41
+ this_saturday_span = saturday_repeater.this(:future)
42
+ Span.new(this_saturday_span.begin, this_saturday_span.begin + WEEKEND_SECONDS)
19
43
  when :past
20
- saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
21
- saturday_repeater.start = (@now + Chronic::RepeaterDay::DAY_SECONDS)
22
- last_saturday_span = saturday_repeater.next(:past)
23
- @current_week_start = last_saturday_span.begin
44
+ saturday_repeater = RepeaterDayName.new(:saturday)
45
+ saturday_repeater.start = @now
46
+ last_saturday_span = saturday_repeater.this(:past)
47
+ Span.new(last_saturday_span.begin, last_saturday_span.begin + WEEKEND_SECONDS)
24
48
  end
25
- else
26
- direction = pointer == :future ? 1 : -1
27
- @current_week_start += direction * Chronic::RepeaterWeek::WEEK_SECONDS
28
49
  end
29
50
 
30
- Chronic::Span.new(@current_week_start, @current_week_start + WEEKEND_SECONDS)
31
- end
32
-
33
- def this(pointer = :future)
34
- super
35
-
36
- case pointer
37
- when :future, :none
38
- saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
39
- saturday_repeater.start = @now
40
- this_saturday_span = saturday_repeater.this(:future)
41
- Chronic::Span.new(this_saturday_span.begin, this_saturday_span.begin + WEEKEND_SECONDS)
42
- when :past
43
- saturday_repeater = Chronic::RepeaterDayName.new(:saturday)
44
- saturday_repeater.start = @now
45
- last_saturday_span = saturday_repeater.this(:past)
46
- Chronic::Span.new(last_saturday_span.begin, last_saturday_span.begin + WEEKEND_SECONDS)
51
+ def offset(span, amount, pointer)
52
+ direction = pointer == :future ? 1 : -1
53
+ weekend = RepeaterWeekend.new(:weekend)
54
+ weekend.start = span.begin
55
+ start = weekend.next(pointer).begin + (amount - 1) * direction * RepeaterWeek::WEEK_SECONDS
56
+ Span.new(start, start + (span.end - span.begin))
47
57
  end
48
- end
49
58
 
50
- def offset(span, amount, pointer)
51
- direction = pointer == :future ? 1 : -1
52
- weekend = Chronic::RepeaterWeekend.new(:weekend)
53
- weekend.start = span.begin
54
- start = weekend.next(pointer).begin + (amount - 1) * direction * Chronic::RepeaterWeek::WEEK_SECONDS
55
- Chronic::Span.new(start, start + (span.end - span.begin))
56
- end
57
-
58
- def width
59
- WEEKEND_SECONDS
60
- end
59
+ def width
60
+ WEEKEND_SECONDS
61
+ end
61
62
 
62
- def to_s
63
- super << '-weekend'
63
+ def to_s
64
+ super << '-weekend'
65
+ end
64
66
  end
65
- end
67
+ end
@@ -1,64 +1,66 @@
1
- class Chronic::RepeaterYear < Chronic::Repeater #:nodoc:
2
- YEAR_SECONDS = 31536000 # 365 * 24 * 60 * 60
1
+ module Chronic
2
+ class RepeaterYear < Repeater #:nodoc:
3
+ YEAR_SECONDS = 31536000 # 365 * 24 * 60 * 60
3
4
 
4
- def initialize(type)
5
- super
6
- @current_year_start = nil
7
- end
5
+ def initialize(type)
6
+ super
7
+ @current_year_start = nil
8
+ end
8
9
 
9
- def next(pointer)
10
- super
10
+ def next(pointer)
11
+ super
11
12
 
12
- if !@current_year_start
13
- case pointer
14
- when :future
15
- @current_year_start = Time.construct(@now.year + 1)
16
- when :past
17
- @current_year_start = Time.construct(@now.year - 1)
13
+ if !@current_year_start
14
+ case pointer
15
+ when :future
16
+ @current_year_start = Time.construct(@now.year + 1)
17
+ when :past
18
+ @current_year_start = Time.construct(@now.year - 1)
19
+ end
20
+ else
21
+ diff = pointer == :future ? 1 : -1
22
+ @current_year_start = Time.construct(@current_year_start.year + diff)
18
23
  end
19
- else
20
- diff = pointer == :future ? 1 : -1
21
- @current_year_start = Time.construct(@current_year_start.year + diff)
24
+
25
+ Span.new(@current_year_start, Time.construct(@current_year_start.year + 1))
22
26
  end
23
27
 
24
- Chronic::Span.new(@current_year_start, Time.construct(@current_year_start.year + 1))
25
- end
28
+ def this(pointer = :future)
29
+ super
26
30
 
27
- def this(pointer = :future)
28
- super
31
+ case pointer
32
+ when :future
33
+ this_year_start = Time.construct(@now.year, @now.month, @now.day) + RepeaterDay::DAY_SECONDS
34
+ this_year_end = Time.construct(@now.year + 1, 1, 1)
35
+ when :past
36
+ this_year_start = Time.construct(@now.year, 1, 1)
37
+ this_year_end = Time.construct(@now.year, @now.month, @now.day)
38
+ when :none
39
+ this_year_start = Time.construct(@now.year, 1, 1)
40
+ this_year_end = Time.construct(@now.year + 1, 1, 1)
41
+ end
29
42
 
30
- case pointer
31
- when :future
32
- this_year_start = Time.construct(@now.year, @now.month, @now.day) + Chronic::RepeaterDay::DAY_SECONDS
33
- this_year_end = Time.construct(@now.year + 1, 1, 1)
34
- when :past
35
- this_year_start = Time.construct(@now.year, 1, 1)
36
- this_year_end = Time.construct(@now.year, @now.month, @now.day)
37
- when :none
38
- this_year_start = Time.construct(@now.year, 1, 1)
39
- this_year_end = Time.construct(@now.year + 1, 1, 1)
43
+ Span.new(this_year_start, this_year_end)
40
44
  end
41
45
 
42
- Chronic::Span.new(this_year_start, this_year_end)
43
- end
46
+ def offset(span, amount, pointer)
47
+ direction = pointer == :future ? 1 : -1
44
48
 
45
- def offset(span, amount, pointer)
46
- direction = pointer == :future ? 1 : -1
49
+ sb = span.begin
50
+ new_begin = Time.construct(sb.year + (amount * direction), sb.month, sb.day, sb.hour, sb.min, sb.sec)
47
51
 
48
- sb = span.begin
49
- new_begin = Time.construct(sb.year + (amount * direction), sb.month, sb.day, sb.hour, sb.min, sb.sec)
52
+ se = span.end
53
+ new_end = Time.construct(se.year + (amount * direction), se.month, se.day, se.hour, se.min, se.sec)
50
54
 
51
- se = span.end
52
- new_end = Time.construct(se.year + (amount * direction), se.month, se.day, se.hour, se.min, se.sec)
53
-
54
- Chronic::Span.new(new_begin, new_end)
55
- end
55
+ Span.new(new_begin, new_end)
56
+ end
56
57
 
57
- def width
58
- (365 * 24 * 60 * 60)
59
- end
58
+ def width
59
+ (365 * 24 * 60 * 60)
60
+ end
60
61
 
61
- def to_s
62
- super << '-year'
62
+ def to_s
63
+ super << '-year'
64
+ end
63
65
  end
64
- end
66
+ end