gitlab-chronic 0.10.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.gitlab-ci.yml +14 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -0
- data/HISTORY.md +252 -0
- data/LICENSE +21 -0
- data/README.md +188 -0
- data/Rakefile +68 -0
- data/chronic.gemspec +25 -0
- data/lib/chronic.rb +155 -0
- data/lib/chronic/date.rb +81 -0
- data/lib/chronic/definition.rb +128 -0
- data/lib/chronic/dictionary.rb +36 -0
- data/lib/chronic/handler.rb +97 -0
- data/lib/chronic/handlers.rb +672 -0
- data/lib/chronic/mini_date.rb +38 -0
- data/lib/chronic/parser.rb +222 -0
- data/lib/chronic/repeaters/repeater_day.rb +54 -0
- data/lib/chronic/repeaters/repeater_day_name.rb +53 -0
- data/lib/chronic/repeaters/repeater_day_portion.rb +109 -0
- data/lib/chronic/repeaters/repeater_fortnight.rb +72 -0
- data/lib/chronic/repeaters/repeater_hour.rb +59 -0
- data/lib/chronic/repeaters/repeater_minute.rb +59 -0
- data/lib/chronic/repeaters/repeater_month.rb +80 -0
- data/lib/chronic/repeaters/repeater_month_name.rb +95 -0
- data/lib/chronic/repeaters/repeater_quarter.rb +59 -0
- data/lib/chronic/repeaters/repeater_quarter_name.rb +40 -0
- data/lib/chronic/repeaters/repeater_season.rb +111 -0
- data/lib/chronic/repeaters/repeater_season_name.rb +43 -0
- data/lib/chronic/repeaters/repeater_second.rb +43 -0
- data/lib/chronic/repeaters/repeater_time.rb +159 -0
- data/lib/chronic/repeaters/repeater_week.rb +76 -0
- data/lib/chronic/repeaters/repeater_weekday.rb +86 -0
- data/lib/chronic/repeaters/repeater_weekend.rb +67 -0
- data/lib/chronic/repeaters/repeater_year.rb +78 -0
- data/lib/chronic/season.rb +26 -0
- data/lib/chronic/span.rb +31 -0
- data/lib/chronic/tag.rb +89 -0
- data/lib/chronic/tags/grabber.rb +29 -0
- data/lib/chronic/tags/ordinal.rb +52 -0
- data/lib/chronic/tags/pointer.rb +28 -0
- data/lib/chronic/tags/repeater.rb +160 -0
- data/lib/chronic/tags/scalar.rb +89 -0
- data/lib/chronic/tags/separator.rb +123 -0
- data/lib/chronic/tags/sign.rb +35 -0
- data/lib/chronic/tags/time_zone.rb +32 -0
- data/lib/chronic/time.rb +40 -0
- data/lib/chronic/token.rb +61 -0
- data/lib/chronic/tokenizer.rb +38 -0
- data/lib/chronic/version.rb +3 -0
- data/test/helper.rb +12 -0
- data/test/test_chronic.rb +203 -0
- data/test/test_daylight_savings.rb +122 -0
- data/test/test_handler.rb +128 -0
- data/test/test_mini_date.rb +32 -0
- data/test/test_parsing.rb +1537 -0
- data/test/test_repeater_day_name.rb +51 -0
- data/test/test_repeater_day_portion.rb +254 -0
- data/test/test_repeater_fortnight.rb +62 -0
- data/test/test_repeater_hour.rb +68 -0
- data/test/test_repeater_minute.rb +34 -0
- data/test/test_repeater_month.rb +50 -0
- data/test/test_repeater_month_name.rb +56 -0
- data/test/test_repeater_quarter.rb +70 -0
- data/test/test_repeater_quarter_name.rb +198 -0
- data/test/test_repeater_season.rb +40 -0
- data/test/test_repeater_time.rb +88 -0
- data/test/test_repeater_week.rb +115 -0
- data/test/test_repeater_weekday.rb +55 -0
- data/test/test_repeater_weekend.rb +74 -0
- data/test/test_repeater_year.rb +69 -0
- data/test/test_span.rb +23 -0
- data/test/test_token.rb +31 -0
- metadata +215 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
module Chronic
|
2
|
+
class RepeaterFortnight < Repeater #:nodoc:
|
3
|
+
FORTNIGHT_SECONDS = 1_209_600 # (14 * 24 * 60 * 60)
|
4
|
+
|
5
|
+
def initialize(type, width = nil, options = {})
|
6
|
+
super
|
7
|
+
@current_fortnight_start = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def next(pointer)
|
11
|
+
super
|
12
|
+
|
13
|
+
unless @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
|
39
|
+
|
40
|
+
case pointer
|
41
|
+
when :future
|
42
|
+
this_fortnight_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour) + RepeaterHour::HOUR_SECONDS
|
43
|
+
sunday_repeater = RepeaterDayName.new(:sunday)
|
44
|
+
sunday_repeater.start = @now
|
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)
|
49
|
+
when :past
|
50
|
+
this_fortnight_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour)
|
51
|
+
sunday_repeater = RepeaterDayName.new(:sunday)
|
52
|
+
sunday_repeater.start = @now
|
53
|
+
last_sunday_span = sunday_repeater.next(:past)
|
54
|
+
this_fortnight_start = last_sunday_span.begin
|
55
|
+
Span.new(this_fortnight_start, this_fortnight_end)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def offset(span, amount, pointer)
|
60
|
+
direction = pointer == :future ? 1 : -1
|
61
|
+
span + direction * amount * FORTNIGHT_SECONDS
|
62
|
+
end
|
63
|
+
|
64
|
+
def width
|
65
|
+
FORTNIGHT_SECONDS
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
super << '-fortnight'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Chronic
|
2
|
+
class RepeaterHour < Repeater #:nodoc:
|
3
|
+
HOUR_SECONDS = 3600 # 60 * 60
|
4
|
+
|
5
|
+
def initialize(type, width = nil, options = {})
|
6
|
+
super
|
7
|
+
@current_hour_start = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def next(pointer)
|
11
|
+
super
|
12
|
+
|
13
|
+
unless @current_hour_start
|
14
|
+
case pointer
|
15
|
+
when :future
|
16
|
+
@current_hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour + 1)
|
17
|
+
when :past
|
18
|
+
@current_hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour - 1)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
direction = pointer == :future ? 1 : -1
|
22
|
+
@current_hour_start += direction * HOUR_SECONDS
|
23
|
+
end
|
24
|
+
|
25
|
+
Span.new(@current_hour_start, @current_hour_start + HOUR_SECONDS)
|
26
|
+
end
|
27
|
+
|
28
|
+
def this(pointer = :future)
|
29
|
+
super
|
30
|
+
|
31
|
+
case pointer
|
32
|
+
when :future
|
33
|
+
hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
|
34
|
+
hour_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour + 1)
|
35
|
+
when :past
|
36
|
+
hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour)
|
37
|
+
hour_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
38
|
+
when :none
|
39
|
+
hour_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour)
|
40
|
+
hour_end = hour_start + HOUR_SECONDS
|
41
|
+
end
|
42
|
+
|
43
|
+
Span.new(hour_start, hour_end)
|
44
|
+
end
|
45
|
+
|
46
|
+
def offset(span, amount, pointer)
|
47
|
+
direction = pointer == :future ? 1 : -1
|
48
|
+
span + direction * amount * HOUR_SECONDS
|
49
|
+
end
|
50
|
+
|
51
|
+
def width
|
52
|
+
HOUR_SECONDS
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
super << '-hour'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Chronic
|
2
|
+
class RepeaterMinute < Repeater #:nodoc:
|
3
|
+
MINUTE_SECONDS = 60
|
4
|
+
|
5
|
+
def initialize(type, width = nil, options = {})
|
6
|
+
super
|
7
|
+
@current_minute_start = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def next(pointer = :future)
|
11
|
+
super
|
12
|
+
|
13
|
+
unless @current_minute_start
|
14
|
+
case pointer
|
15
|
+
when :future
|
16
|
+
@current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
|
17
|
+
when :past
|
18
|
+
@current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min - 1)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
direction = pointer == :future ? 1 : -1
|
22
|
+
@current_minute_start += direction * MINUTE_SECONDS
|
23
|
+
end
|
24
|
+
|
25
|
+
Span.new(@current_minute_start, @current_minute_start + MINUTE_SECONDS)
|
26
|
+
end
|
27
|
+
|
28
|
+
def this(pointer = :future)
|
29
|
+
super
|
30
|
+
|
31
|
+
case pointer
|
32
|
+
when :future
|
33
|
+
minute_begin = @now
|
34
|
+
minute_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
35
|
+
when :past
|
36
|
+
minute_begin = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
37
|
+
minute_end = @now
|
38
|
+
when :none
|
39
|
+
minute_begin = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
40
|
+
minute_end = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
|
41
|
+
end
|
42
|
+
|
43
|
+
Span.new(minute_begin, minute_end)
|
44
|
+
end
|
45
|
+
|
46
|
+
def offset(span, amount, pointer)
|
47
|
+
direction = pointer == :future ? 1 : -1
|
48
|
+
span + direction * amount * MINUTE_SECONDS
|
49
|
+
end
|
50
|
+
|
51
|
+
def width
|
52
|
+
MINUTE_SECONDS
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
super << '-minute'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,80 @@
|
|
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, width = nil, options = {})
|
9
|
+
super
|
10
|
+
@current_month_start = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def next(pointer)
|
14
|
+
super
|
15
|
+
|
16
|
+
unless @current_month_start
|
17
|
+
@current_month_start = offset_by(Chronic.construct(@now.year, @now.month), 1, pointer)
|
18
|
+
else
|
19
|
+
@current_month_start = offset_by(Chronic.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
|
20
|
+
end
|
21
|
+
|
22
|
+
Span.new(@current_month_start, Chronic.construct(@current_month_start.year, @current_month_start.month + 1))
|
23
|
+
end
|
24
|
+
|
25
|
+
def this(pointer = :future)
|
26
|
+
super
|
27
|
+
|
28
|
+
case pointer
|
29
|
+
when :future
|
30
|
+
month_start = Chronic.construct(@now.year, @now.month, @now.day + 1)
|
31
|
+
month_end = self.offset_by(Chronic.construct(@now.year, @now.month), 1, :future)
|
32
|
+
when :past
|
33
|
+
month_start = Chronic.construct(@now.year, @now.month)
|
34
|
+
month_end = Chronic.construct(@now.year, @now.month, @now.day)
|
35
|
+
when :none
|
36
|
+
month_start = Chronic.construct(@now.year, @now.month)
|
37
|
+
month_end = self.offset_by(Chronic.construct(@now.year, @now.month), 1, :future)
|
38
|
+
end
|
39
|
+
|
40
|
+
Span.new(month_start, month_end)
|
41
|
+
end
|
42
|
+
|
43
|
+
def offset(span, amount, pointer)
|
44
|
+
Span.new(offset_by(span.begin, amount, pointer), offset_by(span.end, amount, pointer))
|
45
|
+
end
|
46
|
+
|
47
|
+
def offset_by(time, amount, pointer)
|
48
|
+
direction = pointer == :future ? 1 : -1
|
49
|
+
|
50
|
+
amount_years = direction * amount / YEAR_MONTHS
|
51
|
+
amount_months = direction * amount % YEAR_MONTHS
|
52
|
+
|
53
|
+
new_year = time.year + amount_years
|
54
|
+
new_month = time.month + amount_months
|
55
|
+
if new_month > YEAR_MONTHS
|
56
|
+
new_year += 1
|
57
|
+
new_month -= YEAR_MONTHS
|
58
|
+
end
|
59
|
+
|
60
|
+
days = month_days(new_year, new_month)
|
61
|
+
new_day = time.day > days ? days : time.day
|
62
|
+
|
63
|
+
Chronic.construct(new_year, new_month, new_day, time.hour, time.min, time.sec)
|
64
|
+
end
|
65
|
+
|
66
|
+
def width
|
67
|
+
MONTH_SECONDS
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s
|
71
|
+
super << '-month'
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def month_days(year, month)
|
77
|
+
::Date.leap?(year) ? MONTH_DAYS_LEAP[month - 1] : MONTH_DAYS[month - 1]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,95 @@
|
|
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, width = nil, options = {})
|
20
|
+
super
|
21
|
+
@current_month_begin = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def next(pointer)
|
25
|
+
super
|
26
|
+
|
27
|
+
unless @current_month_begin
|
28
|
+
case pointer
|
29
|
+
when :future
|
30
|
+
if @now.month < index
|
31
|
+
@current_month_begin = Chronic.construct(@now.year, index)
|
32
|
+
elsif @now.month > index
|
33
|
+
@current_month_begin = Chronic.construct(@now.year + 1, index)
|
34
|
+
end
|
35
|
+
when :none
|
36
|
+
if @now.month <= index
|
37
|
+
@current_month_begin = Chronic.construct(@now.year, index)
|
38
|
+
elsif @now.month > index
|
39
|
+
@current_month_begin = Chronic.construct(@now.year + 1, index)
|
40
|
+
end
|
41
|
+
when :past
|
42
|
+
if @now.month >= index
|
43
|
+
@current_month_begin = Chronic.construct(@now.year, index)
|
44
|
+
elsif @now.month < index
|
45
|
+
@current_month_begin = Chronic.construct(@now.year - 1, index)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
@current_month_begin || raise('Current month should be set by now')
|
49
|
+
else
|
50
|
+
case pointer
|
51
|
+
when :future
|
52
|
+
@current_month_begin = Chronic.construct(@current_month_begin.year + 1, @current_month_begin.month)
|
53
|
+
when :past
|
54
|
+
@current_month_begin = Chronic.construct(@current_month_begin.year - 1, @current_month_begin.month)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
cur_month_year = @current_month_begin.year
|
59
|
+
cur_month_month = @current_month_begin.month
|
60
|
+
|
61
|
+
if cur_month_month == 12
|
62
|
+
next_month_year = cur_month_year + 1
|
63
|
+
next_month_month = 1
|
64
|
+
else
|
65
|
+
next_month_year = cur_month_year
|
66
|
+
next_month_month = cur_month_month + 1
|
67
|
+
end
|
68
|
+
|
69
|
+
Span.new(@current_month_begin, Chronic.construct(next_month_year, next_month_month))
|
70
|
+
end
|
71
|
+
|
72
|
+
def this(pointer = :future)
|
73
|
+
super
|
74
|
+
|
75
|
+
case pointer
|
76
|
+
when :past
|
77
|
+
self.next(pointer)
|
78
|
+
when :future, :none
|
79
|
+
self.next(:none)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def width
|
84
|
+
MONTH_SECONDS
|
85
|
+
end
|
86
|
+
|
87
|
+
def index
|
88
|
+
@index ||= MONTHS[@type]
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_s
|
92
|
+
super << '-monthname-' << @type.to_s
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Chronic
|
2
|
+
class RepeaterQuarter < Repeater #:nodoc:
|
3
|
+
MONTHS_PER_QUARTER = 3
|
4
|
+
QUARTER_SECONDS = 7_776_000 # 3 * 30 * 24 * 60 * 60
|
5
|
+
|
6
|
+
def next(pointer)
|
7
|
+
@current_span ||= quarter(@now)
|
8
|
+
offset_quarter_amount = pointer == :future ? 1 : -1
|
9
|
+
@current_span = offset_quarter(@current_span.begin, offset_quarter_amount)
|
10
|
+
end
|
11
|
+
|
12
|
+
def this(*)
|
13
|
+
@current_span = quarter(@now)
|
14
|
+
end
|
15
|
+
|
16
|
+
def offset(span, amount, pointer)
|
17
|
+
direction = pointer == :future ? 1 : -1
|
18
|
+
offset_quarter(span.begin, amount * direction)
|
19
|
+
end
|
20
|
+
|
21
|
+
def width
|
22
|
+
@current_span ? @current_span.width : QUARTER_SECONDS
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
super << '-quarter'
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def quarter_index(month)
|
32
|
+
(month - 1) / MONTHS_PER_QUARTER
|
33
|
+
end
|
34
|
+
|
35
|
+
def quarter(time)
|
36
|
+
year, month = time.year, time.month
|
37
|
+
|
38
|
+
quarter_index = quarter_index(month)
|
39
|
+
quarter_month_start = (quarter_index * MONTHS_PER_QUARTER) + 1
|
40
|
+
quarter_month_end = quarter_month_start + MONTHS_PER_QUARTER
|
41
|
+
|
42
|
+
quarter_start = Chronic.construct(year, quarter_month_start)
|
43
|
+
quarter_end = Chronic.construct(year, quarter_month_end)
|
44
|
+
|
45
|
+
Span.new(quarter_start, quarter_end)
|
46
|
+
end
|
47
|
+
|
48
|
+
def offset_quarter(time, amount)
|
49
|
+
new_month = time.month - 1
|
50
|
+
new_month = new_month + MONTHS_PER_QUARTER * amount
|
51
|
+
new_year = time.year + new_month / 12
|
52
|
+
new_month = new_month % 12 + 1
|
53
|
+
|
54
|
+
offset_time_basis = Chronic.construct(new_year, new_month)
|
55
|
+
|
56
|
+
quarter(offset_time_basis)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Chronic
|
2
|
+
class RepeaterQuarterName < RepeaterQuarter #:nodoc:
|
3
|
+
QUARTERS = {
|
4
|
+
:q1 => 0,
|
5
|
+
:q2 => 1,
|
6
|
+
:q3 => 2,
|
7
|
+
:q4 => 3
|
8
|
+
}
|
9
|
+
|
10
|
+
def next(pointer)
|
11
|
+
unless @current_span
|
12
|
+
@current_span = this(pointer)
|
13
|
+
else
|
14
|
+
year_offset = pointer == :future ? 1 : -1
|
15
|
+
new_year = @current_span.begin.year + year_offset
|
16
|
+
time_basis = Chronic.construct(new_year, @current_span.begin.month)
|
17
|
+
@current_span = quarter(time_basis)
|
18
|
+
end
|
19
|
+
|
20
|
+
@current_span
|
21
|
+
end
|
22
|
+
|
23
|
+
def this(pointer = :future)
|
24
|
+
current_quarter_index = quarter_index(@now.month)
|
25
|
+
target_quarter_index = QUARTERS[type]
|
26
|
+
|
27
|
+
year_basis_offset = case pointer
|
28
|
+
when :past then current_quarter_index > target_quarter_index ? 0 : -1
|
29
|
+
when :future then current_quarter_index < target_quarter_index ? 0 : 1
|
30
|
+
else 0
|
31
|
+
end
|
32
|
+
|
33
|
+
year_basis = @now.year + year_basis_offset
|
34
|
+
month_basis = (MONTHS_PER_QUARTER * target_quarter_index) + 1
|
35
|
+
time_basis = Chronic.construct(year_basis, month_basis)
|
36
|
+
|
37
|
+
@current_span = quarter(time_basis)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|