Hokkaido 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/Gemfile +2 -0
  2. data/Gemfile.lock +2 -2
  3. data/ansiterm-color/.gitignore +3 -0
  4. data/ansiterm-color/CHANGES +28 -0
  5. data/ansiterm-color/COPYING +340 -0
  6. data/ansiterm-color/README +137 -0
  7. data/ansiterm-color/Rakefile +88 -0
  8. data/ansiterm-color/VERSION +1 -0
  9. data/ansiterm-color/bin/cdiff +19 -0
  10. data/ansiterm-color/bin/decolor +12 -0
  11. data/ansiterm-color/doc-main.txt +119 -0
  12. data/ansiterm-color/examples/example.rb +90 -0
  13. data/ansiterm-color/install.rb +15 -0
  14. data/ansiterm-color/lib/term/ansicolor/.keep +0 -0
  15. data/ansiterm-color/lib/term/ansicolor/version.rb +10 -0
  16. data/ansiterm-color/lib/term/ansicolor.rb +102 -0
  17. data/ansiterm-color/make_doc.rb +4 -0
  18. data/ansiterm-color/tests/ansicolor_test.rb +66 -0
  19. data/chronic/.gitignore +6 -0
  20. data/chronic/HISTORY.md +205 -0
  21. data/chronic/LICENSE +21 -0
  22. data/chronic/README.md +181 -0
  23. data/chronic/Rakefile +46 -0
  24. data/chronic/chronic.gemspec +20 -0
  25. data/chronic/lib/chronic/grabber.rb +33 -0
  26. data/chronic/lib/chronic/handler.rb +88 -0
  27. data/chronic/lib/chronic/handlers.rb +572 -0
  28. data/chronic/lib/chronic/mini_date.rb +38 -0
  29. data/chronic/lib/chronic/numerizer.rb +121 -0
  30. data/chronic/lib/chronic/ordinal.rb +47 -0
  31. data/chronic/lib/chronic/pointer.rb +32 -0
  32. data/chronic/lib/chronic/repeater.rb +145 -0
  33. data/chronic/lib/chronic/repeaters/repeater_day.rb +53 -0
  34. data/chronic/lib/chronic/repeaters/repeater_day_name.rb +52 -0
  35. data/chronic/lib/chronic/repeaters/repeater_day_portion.rb +108 -0
  36. data/chronic/lib/chronic/repeaters/repeater_fortnight.rb +71 -0
  37. data/chronic/lib/chronic/repeaters/repeater_hour.rb +58 -0
  38. data/chronic/lib/chronic/repeaters/repeater_minute.rb +58 -0
  39. data/chronic/lib/chronic/repeaters/repeater_month.rb +79 -0
  40. data/chronic/lib/chronic/repeaters/repeater_month_name.rb +94 -0
  41. data/chronic/lib/chronic/repeaters/repeater_season.rb +109 -0
  42. data/chronic/lib/chronic/repeaters/repeater_season_name.rb +43 -0
  43. data/chronic/lib/chronic/repeaters/repeater_second.rb +42 -0
  44. data/chronic/lib/chronic/repeaters/repeater_time.rb +128 -0
  45. data/chronic/lib/chronic/repeaters/repeater_week.rb +74 -0
  46. data/chronic/lib/chronic/repeaters/repeater_weekday.rb +85 -0
  47. data/chronic/lib/chronic/repeaters/repeater_weekend.rb +66 -0
  48. data/chronic/lib/chronic/repeaters/repeater_year.rb +77 -0
  49. data/chronic/lib/chronic/scalar.rb +116 -0
  50. data/chronic/lib/chronic/season.rb +26 -0
  51. data/chronic/lib/chronic/separator.rb +94 -0
  52. data/chronic/lib/chronic/span.rb +31 -0
  53. data/chronic/lib/chronic/tag.rb +36 -0
  54. data/chronic/lib/chronic/time_zone.rb +32 -0
  55. data/chronic/lib/chronic/token.rb +47 -0
  56. data/chronic/lib/chronic.rb +442 -0
  57. data/chronic/test/helper.rb +12 -0
  58. data/chronic/test/test_chronic.rb +150 -0
  59. data/chronic/test/test_daylight_savings.rb +118 -0
  60. data/chronic/test/test_handler.rb +104 -0
  61. data/chronic/test/test_mini_date.rb +32 -0
  62. data/chronic/test/test_numerizer.rb +72 -0
  63. data/chronic/test/test_parsing.rb +1061 -0
  64. data/chronic/test/test_repeater_day_name.rb +51 -0
  65. data/chronic/test/test_repeater_day_portion.rb +254 -0
  66. data/chronic/test/test_repeater_fortnight.rb +62 -0
  67. data/chronic/test/test_repeater_hour.rb +68 -0
  68. data/chronic/test/test_repeater_minute.rb +34 -0
  69. data/chronic/test/test_repeater_month.rb +50 -0
  70. data/chronic/test/test_repeater_month_name.rb +56 -0
  71. data/chronic/test/test_repeater_season.rb +40 -0
  72. data/chronic/test/test_repeater_time.rb +70 -0
  73. data/chronic/test/test_repeater_week.rb +62 -0
  74. data/chronic/test/test_repeater_weekday.rb +55 -0
  75. data/chronic/test/test_repeater_weekend.rb +74 -0
  76. data/chronic/test/test_repeater_year.rb +69 -0
  77. data/chronic/test/test_span.rb +23 -0
  78. data/chronic/test/test_token.rb +25 -0
  79. data/lib/Hokkaido/version.rb +1 -1
  80. data/lib/Hokkaido.rb +13 -9
  81. data/lib/gem_modifier.rb +23 -3
  82. data/lib/term/ansicolor.rb +4 -1
  83. data/spec/Hokkaido/port_spec.rb +15 -7
  84. metadata +78 -2
@@ -0,0 +1,58 @@
1
+ module Chronic
2
+ class RepeaterMinute < Repeater #:nodoc:
3
+ MINUTE_SECONDS = 60
4
+
5
+ def initialize(type)
6
+ super
7
+ end
8
+
9
+ def next(pointer = :future)
10
+ super
11
+
12
+ if !@current_minute_start
13
+ case pointer
14
+ when :future
15
+ @current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
16
+ when :past
17
+ @current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min - 1)
18
+ end
19
+ else
20
+ direction = pointer == :future ? 1 : -1
21
+ @current_minute_start += direction * MINUTE_SECONDS
22
+ end
23
+
24
+ Span.new(@current_minute_start, @current_minute_start + MINUTE_SECONDS)
25
+ end
26
+
27
+ def this(pointer = :future)
28
+ super
29
+
30
+ case pointer
31
+ when :future
32
+ minute_begin = @now
33
+ minute_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
34
+ when :past
35
+ minute_begin = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
36
+ minute_end = @now
37
+ when :none
38
+ minute_begin = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
39
+ minute_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
40
+ end
41
+
42
+ Span.new(minute_begin, minute_end)
43
+ end
44
+
45
+ def offset(span, amount, pointer)
46
+ direction = pointer == :future ? 1 : -1
47
+ span + direction * amount * MINUTE_SECONDS
48
+ end
49
+
50
+ def width
51
+ MINUTE_SECONDS
52
+ end
53
+
54
+ def to_s
55
+ super << '-minute'
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,79 @@
1
+ module Chronic
2
+ class RepeaterMonth < Repeater #:nodoc:
3
+ MONTH_SECONDS = 2_592_000 # 30 * 24 * 60 * 60
4
+ YEAR_MONTHS = 12
5
+ MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
6
+ MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
7
+
8
+ def initialize(type)
9
+ super
10
+ end
11
+
12
+ def next(pointer)
13
+ super
14
+
15
+ if !@current_month_start
16
+ @current_month_start = offset_by(Chronic.construct(@now.year, @now.month), 1, pointer)
17
+ else
18
+ @current_month_start = offset_by(Chronic.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
19
+ end
20
+
21
+ Span.new(@current_month_start, Chronic.construct(@current_month_start.year, @current_month_start.month + 1))
22
+ end
23
+
24
+ def this(pointer = :future)
25
+ super
26
+
27
+ case pointer
28
+ when :future
29
+ month_start = Chronic.construct(@now.year, @now.month, @now.day + 1)
30
+ month_end = self.offset_by(Chronic.construct(@now.year, @now.month), 1, :future)
31
+ when :past
32
+ month_start = Chronic.construct(@now.year, @now.month)
33
+ month_end = Chronic.construct(@now.year, @now.month, @now.day)
34
+ when :none
35
+ month_start = Chronic.construct(@now.year, @now.month)
36
+ month_end = self.offset_by(Chronic.construct(@now.year, @now.month), 1, :future)
37
+ end
38
+
39
+ Span.new(month_start, month_end)
40
+ end
41
+
42
+ def offset(span, amount, pointer)
43
+ Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
44
+ end
45
+
46
+ def offset_by(time, amount, pointer)
47
+ direction = pointer == :future ? 1 : -1
48
+
49
+ amount_years = direction * amount / YEAR_MONTHS
50
+ amount_months = direction * amount % YEAR_MONTHS
51
+
52
+ new_year = time.year + amount_years
53
+ new_month = time.month + amount_months
54
+ if new_month > YEAR_MONTHS
55
+ new_year += 1
56
+ new_month -= YEAR_MONTHS
57
+ end
58
+
59
+ days = month_days(new_year, new_month)
60
+ new_day = time.day > days ? days : time.day
61
+
62
+ Chronic.construct(new_year, new_month, new_day, time.hour, time.min, time.sec)
63
+ end
64
+
65
+ def width
66
+ MONTH_SECONDS
67
+ end
68
+
69
+ def to_s
70
+ super << '-month'
71
+ end
72
+
73
+ private
74
+
75
+ def month_days(year, month)
76
+ Date.leap?(year) ? MONTH_DAYS_LEAP[month - 1] : MONTH_DAYS[month - 1]
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,94 @@
1
+ module Chronic
2
+ class RepeaterMonthName < Repeater #:nodoc:
3
+ MONTH_SECONDS = 2_592_000 # 30 * 24 * 60 * 60
4
+ MONTHS = {
5
+ :january => 1,
6
+ :february => 2,
7
+ :march => 3,
8
+ :april => 4,
9
+ :may => 5,
10
+ :june => 6,
11
+ :july => 7,
12
+ :august => 8,
13
+ :september => 9,
14
+ :october => 10,
15
+ :november => 11,
16
+ :december => 12
17
+ }
18
+
19
+ def initialize(type)
20
+ super
21
+ end
22
+
23
+ def next(pointer)
24
+ super
25
+
26
+ if !@current_month_begin
27
+ case pointer
28
+ when :future
29
+ if @now.month < index
30
+ @current_month_begin = Chronic.construct(@now.year, index)
31
+ elsif @now.month > index
32
+ @current_month_begin = Chronic.construct(@now.year + 1, index)
33
+ end
34
+ when :none
35
+ if @now.month <= index
36
+ @current_month_begin = Chronic.construct(@now.year, index)
37
+ elsif @now.month > index
38
+ @current_month_begin = Chronic.construct(@now.year + 1, index)
39
+ end
40
+ when :past
41
+ if @now.month >= index
42
+ @current_month_begin = Chronic.construct(@now.year, index)
43
+ elsif @now.month < index
44
+ @current_month_begin = Chronic.construct(@now.year - 1, index)
45
+ end
46
+ end
47
+ @current_month_begin || raise("Current month should be set by now")
48
+ else
49
+ case pointer
50
+ when :future
51
+ @current_month_begin = Chronic.construct(@current_month_begin.year + 1, @current_month_begin.month)
52
+ when :past
53
+ @current_month_begin = Chronic.construct(@current_month_begin.year - 1, @current_month_begin.month)
54
+ end
55
+ end
56
+
57
+ cur_month_year = @current_month_begin.year
58
+ cur_month_month = @current_month_begin.month
59
+
60
+ if cur_month_month == 12
61
+ next_month_year = cur_month_year + 1
62
+ next_month_month = 1
63
+ else
64
+ next_month_year = cur_month_year
65
+ next_month_month = cur_month_month + 1
66
+ end
67
+
68
+ Span.new(@current_month_begin, Chronic.construct(next_month_year, next_month_month))
69
+ end
70
+
71
+ def this(pointer = :future)
72
+ super
73
+
74
+ case pointer
75
+ when :past
76
+ self.next(pointer)
77
+ when :future, :none
78
+ self.next(:none)
79
+ end
80
+ end
81
+
82
+ def width
83
+ MONTH_SECONDS
84
+ end
85
+
86
+ def index
87
+ @index ||= MONTHS[@type]
88
+ end
89
+
90
+ def to_s
91
+ super << '-monthname-' << @type.to_s
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,109 @@
1
+ module Chronic
2
+ class RepeaterSeason < Repeater #:nodoc:
3
+ SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
4
+ SEASONS = {
5
+ :spring => Season.new(MiniDate.new(3,20), MiniDate.new(6,20)),
6
+ :summer => Season.new(MiniDate.new(6,21), MiniDate.new(9,22)),
7
+ :autumn => Season.new(MiniDate.new(9,23), MiniDate.new(12,21)),
8
+ :winter => Season.new(MiniDate.new(12,22), MiniDate.new(3,19))
9
+ }
10
+
11
+ def initialize(type)
12
+ super
13
+ end
14
+
15
+ def next(pointer)
16
+ super
17
+
18
+ direction = pointer == :future ? 1 : -1
19
+ next_season = Season.find_next_season(find_current_season(MiniDate.from_time(@now)), direction)
20
+
21
+ find_next_season_span(direction, next_season)
22
+ end
23
+
24
+ def this(pointer = :future)
25
+ super
26
+
27
+ direction = pointer == :future ? 1 : -1
28
+
29
+ today = Chronic.construct(@now.year, @now.month, @now.day)
30
+ this_ssn = find_current_season(MiniDate.from_time(@now))
31
+ case pointer
32
+ when :past
33
+ this_ssn_start = today + direction * num_seconds_til_start(this_ssn, direction)
34
+ this_ssn_end = today
35
+ when :future
36
+ this_ssn_start = today + RepeaterDay::DAY_SECONDS
37
+ this_ssn_end = today + direction * num_seconds_til_end(this_ssn, direction)
38
+ when :none
39
+ this_ssn_start = today + direction * num_seconds_til_start(this_ssn, direction)
40
+ this_ssn_end = today + direction * num_seconds_til_end(this_ssn, direction)
41
+ end
42
+
43
+ construct_season(this_ssn_start, this_ssn_end)
44
+ end
45
+
46
+ def offset(span, amount, pointer)
47
+ Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
48
+ end
49
+
50
+ def offset_by(time, amount, pointer)
51
+ direction = pointer == :future ? 1 : -1
52
+ time + amount * direction * SEASON_SECONDS
53
+ end
54
+
55
+ def width
56
+ SEASON_SECONDS
57
+ end
58
+
59
+ def to_s
60
+ super << '-season'
61
+ end
62
+
63
+ private
64
+
65
+ def find_next_season_span(direction, next_season)
66
+ unless @next_season_start or @next_season_end
67
+ @next_season_start = Chronic.construct(@now.year, @now.month, @now.day)
68
+ @next_season_end = Chronic.construct(@now.year, @now.month, @now.day)
69
+ end
70
+
71
+ @next_season_start += direction * num_seconds_til_start(next_season, direction)
72
+ @next_season_end += direction * num_seconds_til_end(next_season, direction)
73
+
74
+ construct_season(@next_season_start, @next_season_end)
75
+ end
76
+
77
+ def find_current_season(md)
78
+ [:spring, :summer, :autumn, :winter].find do |season|
79
+ md.is_between?(SEASONS[season].start, SEASONS[season].end)
80
+ end
81
+ end
82
+
83
+ def num_seconds_til(goal, direction)
84
+ start = Chronic.construct(@now.year, @now.month, @now.day)
85
+ seconds = 0
86
+
87
+ until MiniDate.from_time(start + direction * seconds).equals?(goal)
88
+ seconds += RepeaterDay::DAY_SECONDS
89
+ end
90
+
91
+ seconds
92
+ end
93
+
94
+ def num_seconds_til_start(season_symbol, direction)
95
+ num_seconds_til(SEASONS[season_symbol].start, direction)
96
+ end
97
+
98
+ def num_seconds_til_end(season_symbol, direction)
99
+ num_seconds_til(SEASONS[season_symbol].end, direction)
100
+ end
101
+
102
+ def construct_season(start, finish)
103
+ Span.new(
104
+ Chronic.construct(start.year, start.month, start.day),
105
+ Chronic.construct(finish.year, finish.month, finish.day)
106
+ )
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,43 @@
1
+ module Chronic
2
+ class RepeaterSeasonName < RepeaterSeason #:nodoc:
3
+ SEASON_SECONDS = 7_862_400 # 91 * 24 * 60 * 60
4
+ DAY_SECONDS = 86_400 # (24 * 60 * 60)
5
+
6
+ def next(pointer)
7
+ direction = pointer == :future ? 1 : -1
8
+ find_next_season_span(direction, @type)
9
+ end
10
+
11
+ def this(pointer = :future)
12
+ direction = pointer == :future ? 1 : -1
13
+
14
+ today = Chronic.construct(@now.year, @now.month, @now.day)
15
+ goal_ssn_start = today + direction * num_seconds_til_start(@type, direction)
16
+ goal_ssn_end = today + direction * num_seconds_til_end(@type, direction)
17
+ curr_ssn = find_current_season(MiniDate.from_time(@now))
18
+ case pointer
19
+ when :past
20
+ this_ssn_start = goal_ssn_start
21
+ this_ssn_end = (curr_ssn == @type) ? today : goal_ssn_end
22
+ when :future
23
+ this_ssn_start = (curr_ssn == @type) ? today + RepeaterDay::DAY_SECONDS : goal_ssn_start
24
+ this_ssn_end = goal_ssn_end
25
+ when :none
26
+ this_ssn_start = goal_ssn_start
27
+ this_ssn_end = goal_ssn_end
28
+ end
29
+
30
+ construct_season(this_ssn_start, this_ssn_end)
31
+ end
32
+
33
+ def offset(span, amount, pointer)
34
+ Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
35
+ end
36
+
37
+ def offset_by(time, amount, pointer)
38
+ direction = pointer == :future ? 1 : -1
39
+ time + amount * direction * RepeaterYear::YEAR_SECONDS
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,42 @@
1
+ module Chronic
2
+ class RepeaterSecond < Repeater #:nodoc:
3
+ SECOND_SECONDS = 1 # haha, awesome
4
+
5
+ def initialize(type)
6
+ super
7
+ end
8
+
9
+ def next(pointer = :future)
10
+ super
11
+
12
+ direction = pointer == :future ? 1 : -1
13
+
14
+ if !@second_start
15
+ @second_start = @now + (direction * SECOND_SECONDS)
16
+ else
17
+ @second_start += SECOND_SECONDS * direction
18
+ end
19
+
20
+ Span.new(@second_start, @second_start + SECOND_SECONDS)
21
+ end
22
+
23
+ def this(pointer = :future)
24
+ super
25
+
26
+ Span.new(@now, @now + 1)
27
+ end
28
+
29
+ def offset(span, amount, pointer)
30
+ direction = pointer == :future ? 1 : -1
31
+ span + direction * amount * SECOND_SECONDS
32
+ end
33
+
34
+ def width
35
+ SECOND_SECONDS
36
+ end
37
+
38
+ def to_s
39
+ super << '-second'
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,128 @@
1
+ module Chronic
2
+ class RepeaterTime < Repeater #:nodoc:
3
+ class Tick #:nodoc:
4
+ attr_accessor :time
5
+
6
+ def initialize(time, ambiguous = false)
7
+ @time = time
8
+ @ambiguous = ambiguous
9
+ end
10
+
11
+ def ambiguous?
12
+ @ambiguous
13
+ end
14
+
15
+ def *(other)
16
+ Tick.new(@time * other, @ambiguous)
17
+ end
18
+
19
+ def to_f
20
+ @time.to_f
21
+ end
22
+
23
+ def to_s
24
+ @time.to_s + (@ambiguous ? '?' : '')
25
+ end
26
+
27
+ end
28
+
29
+ def initialize(time)
30
+ t = time.gsub(/\:/, '')
31
+
32
+ @type =
33
+ case t.size
34
+ when 1..2
35
+ hours = t.to_i
36
+ Tick.new((hours == 12 ? 0 : hours) * 60 * 60, true)
37
+ when 3
38
+ hours = t[0..0].to_i
39
+ ambiguous = hours > 0
40
+ Tick.new((hours * 60 * 60) + (t[1..2].to_i * 60), ambiguous)
41
+ when 4
42
+ ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
43
+ hours = t[0..1].to_i
44
+ hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60, ambiguous)
45
+ when 5
46
+ Tick.new(t[0..0].to_i * 60 * 60 + t[1..2].to_i * 60 + t[3..4].to_i, true)
47
+ when 6
48
+ ambiguous = time =~ /:/ && t[0..0].to_i != 0 && t[0..1].to_i <= 12
49
+ hours = t[0..1].to_i
50
+ hours == 12 ? Tick.new(0 * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous) : Tick.new(hours * 60 * 60 + t[2..3].to_i * 60 + t[4..5].to_i, ambiguous)
51
+ else
52
+ raise("Time cannot exceed six digits")
53
+ end
54
+ end
55
+
56
+ # Return the next past or future Span for the time that this Repeater represents
57
+ # pointer - Symbol representing which temporal direction to fetch the next day
58
+ # must be either :past or :future
59
+ def next(pointer)
60
+ super
61
+
62
+ half_day = 60 * 60 * 12
63
+ full_day = 60 * 60 * 24
64
+
65
+ first = false
66
+
67
+ unless @current_time
68
+ first = true
69
+ midnight = Chronic.time_class.local(@now.year, @now.month, @now.day)
70
+
71
+ yesterday_midnight = midnight - full_day
72
+ tomorrow_midnight = midnight + full_day
73
+
74
+ offset_fix = midnight.gmt_offset - tomorrow_midnight.gmt_offset
75
+ tomorrow_midnight += offset_fix
76
+
77
+ catch :done do
78
+ if pointer == :future
79
+ if @type.ambiguous?
80
+ [midnight + @type.time + offset_fix, midnight + half_day + @type.time + offset_fix, tomorrow_midnight + @type.time].each do |t|
81
+ (@current_time = t; throw :done) if t >= @now
82
+ end
83
+ else
84
+ [midnight + @type.time + offset_fix, tomorrow_midnight + @type.time].each do |t|
85
+ (@current_time = t; throw :done) if t >= @now
86
+ end
87
+ end
88
+ else # pointer == :past
89
+ if @type.ambiguous?
90
+ [midnight + half_day + @type.time + offset_fix, midnight + @type.time + offset_fix, yesterday_midnight + @type.time + half_day].each do |t|
91
+ (@current_time = t; throw :done) if t <= @now
92
+ end
93
+ else
94
+ [midnight + @type.time + offset_fix, yesterday_midnight + @type.time].each do |t|
95
+ (@current_time = t; throw :done) if t <= @now
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ @current_time || raise("Current time cannot be nil at this point")
102
+ end
103
+
104
+ unless first
105
+ increment = @type.ambiguous? ? half_day : full_day
106
+ @current_time += pointer == :future ? increment : -increment
107
+ end
108
+
109
+ Span.new(@current_time, @current_time + width)
110
+ end
111
+
112
+ def this(context = :future)
113
+ super
114
+
115
+ context = :future if context == :none
116
+
117
+ self.next(context)
118
+ end
119
+
120
+ def width
121
+ 1
122
+ end
123
+
124
+ def to_s
125
+ super << '-time-' << @type.to_s
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,74 @@
1
+ module Chronic
2
+ class RepeaterWeek < Repeater #:nodoc:
3
+ WEEK_SECONDS = 604800 # (7 * 24 * 60 * 60)
4
+
5
+ def initialize(type)
6
+ super
7
+ end
8
+
9
+ def next(pointer)
10
+ super
11
+
12
+ if !@current_week_start
13
+ case pointer
14
+ when :future
15
+ sunday_repeater = RepeaterDayName.new(:sunday)
16
+ sunday_repeater.start = @now
17
+ next_sunday_span = sunday_repeater.next(:future)
18
+ @current_week_start = next_sunday_span.begin
19
+ when :past
20
+ sunday_repeater = RepeaterDayName.new(:sunday)
21
+ sunday_repeater.start = (@now + RepeaterDay::DAY_SECONDS)
22
+ sunday_repeater.next(:past)
23
+ last_sunday_span = sunday_repeater.next(:past)
24
+ @current_week_start = last_sunday_span.begin
25
+ end
26
+ else
27
+ direction = pointer == :future ? 1 : -1
28
+ @current_week_start += direction * WEEK_SECONDS
29
+ end
30
+
31
+ 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) + RepeaterHour::HOUR_SECONDS
40
+ sunday_repeater = 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
+ 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 = 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
+ Span.new(this_week_start, this_week_end)
52
+ when :none
53
+ sunday_repeater = 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
+ Span.new(this_week_start, this_week_start + WEEK_SECONDS)
58
+ end
59
+ end
60
+
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
69
+
70
+ def to_s
71
+ super << '-week'
72
+ end
73
+ end
74
+ end