chronic 0.6.3 → 0.10.2
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.
- checksums.yaml +7 -0
- data/.gitignore +4 -3
- data/.travis.yml +8 -0
- data/HISTORY.md +76 -0
- data/README.md +47 -42
- data/Rakefile +30 -12
- data/chronic.gemspec +10 -4
- data/lib/chronic/date.rb +82 -0
- data/lib/chronic/grabber.rb +9 -7
- data/lib/chronic/handler.rb +47 -40
- data/lib/chronic/handlers.rb +240 -28
- data/lib/chronic/numerizer.rb +11 -2
- data/lib/chronic/ordinal.rb +28 -23
- data/lib/chronic/parser.rb +268 -0
- data/lib/chronic/pointer.rb +9 -7
- data/lib/chronic/repeater.rb +58 -48
- data/lib/chronic/repeaters/repeater_day.rb +4 -3
- data/lib/chronic/repeaters/repeater_day_name.rb +5 -4
- data/lib/chronic/repeaters/repeater_day_portion.rb +33 -18
- data/lib/chronic/repeaters/repeater_fortnight.rb +4 -3
- data/lib/chronic/repeaters/repeater_hour.rb +4 -3
- data/lib/chronic/repeaters/repeater_minute.rb +4 -3
- data/lib/chronic/repeaters/repeater_month.rb +5 -4
- data/lib/chronic/repeaters/repeater_month_name.rb +4 -3
- data/lib/chronic/repeaters/repeater_season.rb +5 -3
- data/lib/chronic/repeaters/repeater_second.rb +4 -3
- data/lib/chronic/repeaters/repeater_time.rb +35 -25
- data/lib/chronic/repeaters/repeater_week.rb +4 -3
- data/lib/chronic/repeaters/repeater_weekday.rb +4 -3
- data/lib/chronic/repeaters/repeater_weekend.rb +4 -3
- data/lib/chronic/repeaters/repeater_year.rb +6 -5
- data/lib/chronic/scalar.rb +40 -68
- data/lib/chronic/season.rb +1 -12
- data/lib/chronic/separator.rb +142 -23
- data/lib/chronic/sign.rb +49 -0
- data/lib/chronic/span.rb +2 -2
- data/lib/chronic/tag.rb +10 -15
- data/lib/chronic/time.rb +40 -0
- data/lib/chronic/time_zone.rb +9 -7
- data/lib/chronic/token.rb +16 -10
- data/lib/chronic.rb +109 -70
- data/test/helper.rb +8 -2
- data/test/{test_Chronic.rb → test_chronic.rb} +69 -34
- data/test/{test_DaylightSavings.rb → test_daylight_savings.rb} +1 -1
- data/test/{test_Handler.rb → test_handler.rb} +38 -14
- data/test/{test_MiniDate.rb → test_mini_date.rb} +9 -9
- data/test/{test_Numerizer.rb → test_numerizer.rb} +16 -2
- data/test/test_parsing.rb +392 -22
- data/test/{test_RepeaterDayName.rb → test_repeater_day_name.rb} +1 -1
- data/test/test_repeater_day_portion.rb +254 -0
- data/test/{test_RepeaterFortnight.rb → test_repeater_fortnight.rb} +1 -1
- data/test/{test_RepeaterHour.rb → test_repeater_hour.rb} +1 -1
- data/test/{test_RepeaterMinute.rb → test_repeater_minute.rb} +1 -1
- data/test/{test_RepeaterMonth.rb → test_repeater_month.rb} +1 -1
- data/test/{test_RepeaterMonthName.rb → test_repeater_month_name.rb} +1 -1
- data/test/{test_RepeaterSeason.rb → test_repeater_season.rb} +1 -1
- data/test/{test_RepeaterTime.rb → test_repeater_time.rb} +19 -1
- data/test/{test_RepeaterWeek.rb → test_repeater_week.rb} +1 -1
- data/test/{test_RepeaterWeekday.rb → test_repeater_weekday.rb} +1 -1
- data/test/{test_RepeaterWeekend.rb → test_repeater_weekend.rb} +1 -1
- data/test/{test_RepeaterYear.rb → test_repeater_year.rb} +1 -1
- data/test/{test_Span.rb → test_span.rb} +2 -2
- data/test/{test_Token.rb → test_token.rb} +1 -1
- metadata +129 -87
- data/.gemtest +0 -0
- data/.yardopts +0 -3
- data/lib/chronic/chronic.rb +0 -323
|
@@ -2,14 +2,15 @@ module Chronic
|
|
|
2
2
|
class RepeaterMinute < Repeater #:nodoc:
|
|
3
3
|
MINUTE_SECONDS = 60
|
|
4
4
|
|
|
5
|
-
def initialize(type)
|
|
5
|
+
def initialize(type, options = {})
|
|
6
6
|
super
|
|
7
|
+
@current_minute_start = nil
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def next(pointer = :future)
|
|
10
11
|
super
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
unless @current_minute_start
|
|
13
14
|
case pointer
|
|
14
15
|
when :future
|
|
15
16
|
@current_minute_start = Chronic.construct(@now.year, @now.month, @now.day, @now.hour, @now.min + 1)
|
|
@@ -55,4 +56,4 @@ module Chronic
|
|
|
55
56
|
super << '-minute'
|
|
56
57
|
end
|
|
57
58
|
end
|
|
58
|
-
end
|
|
59
|
+
end
|
|
@@ -5,14 +5,15 @@ module Chronic
|
|
|
5
5
|
MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
6
6
|
MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
7
7
|
|
|
8
|
-
def initialize(type)
|
|
8
|
+
def initialize(type, options = {})
|
|
9
9
|
super
|
|
10
|
+
@current_month_start = nil
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def next(pointer)
|
|
13
14
|
super
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
unless @current_month_start
|
|
16
17
|
@current_month_start = offset_by(Chronic.construct(@now.year, @now.month), 1, pointer)
|
|
17
18
|
else
|
|
18
19
|
@current_month_start = offset_by(Chronic.construct(@current_month_start.year, @current_month_start.month), 1, pointer)
|
|
@@ -73,7 +74,7 @@ module Chronic
|
|
|
73
74
|
private
|
|
74
75
|
|
|
75
76
|
def month_days(year, month)
|
|
76
|
-
Date.leap?(year) ? MONTH_DAYS_LEAP[month - 1] : MONTH_DAYS[month - 1]
|
|
77
|
+
::Date.leap?(year) ? MONTH_DAYS_LEAP[month - 1] : MONTH_DAYS[month - 1]
|
|
77
78
|
end
|
|
78
79
|
end
|
|
79
|
-
end
|
|
80
|
+
end
|
|
@@ -16,14 +16,15 @@ module Chronic
|
|
|
16
16
|
:december => 12
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
def initialize(type)
|
|
19
|
+
def initialize(type, options = {})
|
|
20
20
|
super
|
|
21
|
+
@current_month_begin = nil
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def next(pointer)
|
|
24
25
|
super
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
unless @current_month_begin
|
|
27
28
|
case pointer
|
|
28
29
|
when :future
|
|
29
30
|
if @now.month < index
|
|
@@ -91,4 +92,4 @@ module Chronic
|
|
|
91
92
|
super << '-monthname-' << @type.to_s
|
|
92
93
|
end
|
|
93
94
|
end
|
|
94
|
-
end
|
|
95
|
+
end
|
|
@@ -8,8 +8,10 @@ module Chronic
|
|
|
8
8
|
:winter => Season.new(MiniDate.new(12,22), MiniDate.new(3,19))
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
def initialize(type)
|
|
11
|
+
def initialize(type, options = {})
|
|
12
12
|
super
|
|
13
|
+
@next_season_start = nil
|
|
14
|
+
@next_season_end = nil
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def next(pointer)
|
|
@@ -63,7 +65,7 @@ module Chronic
|
|
|
63
65
|
private
|
|
64
66
|
|
|
65
67
|
def find_next_season_span(direction, next_season)
|
|
66
|
-
unless @next_season_start
|
|
68
|
+
unless @next_season_start || @next_season_end
|
|
67
69
|
@next_season_start = Chronic.construct(@now.year, @now.month, @now.day)
|
|
68
70
|
@next_season_end = Chronic.construct(@now.year, @now.month, @now.day)
|
|
69
71
|
end
|
|
@@ -106,4 +108,4 @@ module Chronic
|
|
|
106
108
|
)
|
|
107
109
|
end
|
|
108
110
|
end
|
|
109
|
-
end
|
|
111
|
+
end
|
|
@@ -2,8 +2,9 @@ module Chronic
|
|
|
2
2
|
class RepeaterSecond < Repeater #:nodoc:
|
|
3
3
|
SECOND_SECONDS = 1 # haha, awesome
|
|
4
4
|
|
|
5
|
-
def initialize(type)
|
|
5
|
+
def initialize(type, options = {})
|
|
6
6
|
super
|
|
7
|
+
@second_start = nil
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def next(pointer = :future)
|
|
@@ -11,7 +12,7 @@ module Chronic
|
|
|
11
12
|
|
|
12
13
|
direction = pointer == :future ? 1 : -1
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
unless @second_start
|
|
15
16
|
@second_start = @now + (direction * SECOND_SECONDS)
|
|
16
17
|
else
|
|
17
18
|
@second_start += SECOND_SECONDS * direction
|
|
@@ -39,4 +40,4 @@ module Chronic
|
|
|
39
40
|
super << '-second'
|
|
40
41
|
end
|
|
41
42
|
end
|
|
42
|
-
end
|
|
43
|
+
end
|
|
@@ -26,31 +26,41 @@ module Chronic
|
|
|
26
26
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def initialize(time)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
raise("Time cannot exceed six digits")
|
|
29
|
+
def initialize(time, options = {})
|
|
30
|
+
@current_time = nil
|
|
31
|
+
@options = options
|
|
32
|
+
time_parts = time.split(':')
|
|
33
|
+
raise ArgumentError, "Time cannot have more than 4 groups of ':'" if time_parts.count > 4
|
|
34
|
+
|
|
35
|
+
if time_parts.first.length > 2 and time_parts.count == 1
|
|
36
|
+
if time_parts.first.length > 4
|
|
37
|
+
second_index = time_parts.first.length - 2
|
|
38
|
+
time_parts.insert(1, time_parts.first[second_index..time_parts.first.length])
|
|
39
|
+
time_parts[0] = time_parts.first[0..second_index - 1]
|
|
40
|
+
end
|
|
41
|
+
minute_index = time_parts.first.length - 2
|
|
42
|
+
time_parts.insert(1, time_parts.first[minute_index..time_parts.first.length])
|
|
43
|
+
time_parts[0] = time_parts.first[0..minute_index - 1]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
ambiguous = false
|
|
47
|
+
hours = time_parts.first.to_i
|
|
48
|
+
|
|
49
|
+
if @options[:hours24].nil? or (not @options[:hours24].nil? and @options[:hours24] != true)
|
|
50
|
+
ambiguous = true if (time_parts.first.length == 1 and hours > 0) or (hours >= 10 and hours <= 12) or (@options[:hours24] == false and hours > 0)
|
|
51
|
+
hours = 0 if hours == 12 and ambiguous
|
|
53
52
|
end
|
|
53
|
+
|
|
54
|
+
hours *= 60 * 60
|
|
55
|
+
minutes = 0
|
|
56
|
+
seconds = 0
|
|
57
|
+
subseconds = 0
|
|
58
|
+
|
|
59
|
+
minutes = time_parts[1].to_i * 60 if time_parts.count > 1
|
|
60
|
+
seconds = time_parts[2].to_i if time_parts.count > 2
|
|
61
|
+
subseconds = time_parts[3].to_f / (10 ** time_parts[3].length) if time_parts.count > 3
|
|
62
|
+
|
|
63
|
+
@type = Tick.new(hours + minutes + seconds + subseconds, ambiguous)
|
|
54
64
|
end
|
|
55
65
|
|
|
56
66
|
# Return the next past or future Span for the time that this Repeater represents
|
|
@@ -125,4 +135,4 @@ module Chronic
|
|
|
125
135
|
super << '-time-' << @type.to_s
|
|
126
136
|
end
|
|
127
137
|
end
|
|
128
|
-
end
|
|
138
|
+
end
|
|
@@ -2,14 +2,15 @@ module Chronic
|
|
|
2
2
|
class RepeaterWeek < Repeater #:nodoc:
|
|
3
3
|
WEEK_SECONDS = 604800 # (7 * 24 * 60 * 60)
|
|
4
4
|
|
|
5
|
-
def initialize(type)
|
|
5
|
+
def initialize(type, options = {})
|
|
6
6
|
super
|
|
7
|
+
@current_week_start = nil
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def next(pointer)
|
|
10
11
|
super
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
unless @current_week_start
|
|
13
14
|
case pointer
|
|
14
15
|
when :future
|
|
15
16
|
sunday_repeater = RepeaterDayName.new(:sunday)
|
|
@@ -71,4 +72,4 @@ module Chronic
|
|
|
71
72
|
super << '-week'
|
|
72
73
|
end
|
|
73
74
|
end
|
|
74
|
-
end
|
|
75
|
+
end
|
|
@@ -11,8 +11,9 @@ module Chronic
|
|
|
11
11
|
:saturday => 6
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
def initialize(type)
|
|
14
|
+
def initialize(type, options = {})
|
|
15
15
|
super
|
|
16
|
+
@current_weekday_start = nil
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
def next(pointer)
|
|
@@ -20,7 +21,7 @@ module Chronic
|
|
|
20
21
|
|
|
21
22
|
direction = pointer == :future ? 1 : -1
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
unless @current_weekday_start
|
|
24
25
|
@current_weekday_start = Chronic.construct(@now.year, @now.month, @now.day)
|
|
25
26
|
@current_weekday_start += direction * DAY_SECONDS
|
|
26
27
|
|
|
@@ -82,4 +83,4 @@ module Chronic
|
|
|
82
83
|
DAYS[sym] || raise("Invalid symbol specified")
|
|
83
84
|
end
|
|
84
85
|
end
|
|
85
|
-
end
|
|
86
|
+
end
|
|
@@ -2,14 +2,15 @@ module Chronic
|
|
|
2
2
|
class RepeaterWeekend < Repeater #:nodoc:
|
|
3
3
|
WEEKEND_SECONDS = 172_800 # (2 * 24 * 60 * 60)
|
|
4
4
|
|
|
5
|
-
def initialize(type)
|
|
5
|
+
def initialize(type, options = {})
|
|
6
6
|
super
|
|
7
|
+
@current_week_start = nil
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def next(pointer)
|
|
10
11
|
super
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
unless @current_week_start
|
|
13
14
|
case pointer
|
|
14
15
|
when :future
|
|
15
16
|
saturday_repeater = RepeaterDayName.new(:saturday)
|
|
@@ -63,4 +64,4 @@ module Chronic
|
|
|
63
64
|
super << '-weekend'
|
|
64
65
|
end
|
|
65
66
|
end
|
|
66
|
-
end
|
|
67
|
+
end
|
|
@@ -2,14 +2,15 @@ module Chronic
|
|
|
2
2
|
class RepeaterYear < Repeater #:nodoc:
|
|
3
3
|
YEAR_SECONDS = 31536000 # 365 * 24 * 60 * 60
|
|
4
4
|
|
|
5
|
-
def initialize(type)
|
|
5
|
+
def initialize(type, options = {})
|
|
6
6
|
super
|
|
7
|
+
@current_year_start = nil
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def next(pointer)
|
|
10
11
|
super
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
unless @current_year_start
|
|
13
14
|
case pointer
|
|
14
15
|
when :future
|
|
15
16
|
@current_year_start = Chronic.construct(@now.year + 1)
|
|
@@ -29,7 +30,7 @@ module Chronic
|
|
|
29
30
|
|
|
30
31
|
case pointer
|
|
31
32
|
when :future
|
|
32
|
-
this_year_start = Chronic.construct(@now.year, @now.month, @now.day
|
|
33
|
+
this_year_start = Chronic.construct(@now.year, @now.month, @now.day + 1)
|
|
33
34
|
this_year_end = Chronic.construct(@now.year + 1, 1, 1)
|
|
34
35
|
when :past
|
|
35
36
|
this_year_start = Chronic.construct(@now.year, 1, 1)
|
|
@@ -67,11 +68,11 @@ module Chronic
|
|
|
67
68
|
end
|
|
68
69
|
|
|
69
70
|
def month_days(year, month)
|
|
70
|
-
if Date.leap?(year)
|
|
71
|
+
if ::Date.leap?(year)
|
|
71
72
|
RepeaterMonth::MONTH_DAYS_LEAP[month - 1]
|
|
72
73
|
else
|
|
73
74
|
RepeaterMonth::MONTH_DAYS[month - 1]
|
|
74
75
|
end
|
|
75
76
|
end
|
|
76
77
|
end
|
|
77
|
-
end
|
|
78
|
+
end
|
data/lib/chronic/scalar.rb
CHANGED
|
@@ -2,90 +2,62 @@ module Chronic
|
|
|
2
2
|
class Scalar < Tag
|
|
3
3
|
DAY_PORTIONS = %w( am pm morning afternoon evening night )
|
|
4
4
|
|
|
5
|
-
# Scan an Array of
|
|
6
|
-
# each token
|
|
5
|
+
# Scan an Array of Token objects and apply any necessary Scalar
|
|
6
|
+
# tags to each token.
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
8
|
+
# tokens - An Array of tokens to scan.
|
|
9
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
10
|
+
#
|
|
11
|
+
# Returns an Array of tokens.
|
|
11
12
|
def self.scan(tokens, options)
|
|
12
13
|
tokens.each_index do |i|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
14
|
+
token = tokens[i]
|
|
15
|
+
post_token = tokens[i + 1]
|
|
16
|
+
if token.word =~ /^\d+$/
|
|
17
|
+
scalar = token.word.to_i
|
|
18
|
+
token.tag(Scalar.new(scalar))
|
|
19
|
+
token.tag(ScalarSubsecond.new(scalar)) if Chronic::Time::could_be_subsecond?(scalar)
|
|
20
|
+
token.tag(ScalarSecond.new(scalar)) if Chronic::Time::could_be_second?(scalar)
|
|
21
|
+
token.tag(ScalarMinute.new(scalar)) if Chronic::Time::could_be_minute?(scalar)
|
|
22
|
+
token.tag(ScalarHour.new(scalar)) if Chronic::Time::could_be_hour?(scalar)
|
|
23
|
+
unless post_token and DAY_PORTIONS.include?(post_token.word)
|
|
24
|
+
token.tag(ScalarDay.new(scalar)) if Chronic::Date::could_be_day?(scalar)
|
|
25
|
+
token.tag(ScalarMonth.new(scalar)) if Chronic::Date::could_be_month?(scalar)
|
|
26
|
+
if Chronic::Date::could_be_year?(scalar)
|
|
27
|
+
year = Chronic::Date::make_year(scalar, options[:ambiguous_year_future_bias])
|
|
28
|
+
token.tag(ScalarYear.new(year.to_i))
|
|
29
|
+
end
|
|
30
|
+
end
|
|
27
31
|
end
|
|
28
32
|
end
|
|
29
33
|
end
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
# @return [ScalarDay, nil]
|
|
34
|
-
def self.scan_for_days(token, post_token)
|
|
35
|
-
if token.word =~ /^\d\d?$/
|
|
36
|
-
toi = token.word.to_i
|
|
37
|
-
unless toi > 31 || toi < 1 || (post_token && DAY_PORTIONS.include?(post_token.word))
|
|
38
|
-
return ScalarDay.new(toi)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
35
|
+
def to_s
|
|
36
|
+
'scalar'
|
|
41
37
|
end
|
|
38
|
+
end
|
|
42
39
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def self.scan_for_months(token, post_token)
|
|
47
|
-
if token.word =~ /^\d\d?$/
|
|
48
|
-
toi = token.word.to_i
|
|
49
|
-
unless toi > 12 || toi < 1 || (post_token && DAY_PORTIONS.include?(post_token.word))
|
|
50
|
-
return ScalarMonth.new(toi)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
40
|
+
class ScalarSubsecond < Scalar #:nodoc:
|
|
41
|
+
def to_s
|
|
42
|
+
super << '-subsecond-' << @type.to_s
|
|
53
43
|
end
|
|
44
|
+
end
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
# @return [ScalarYear, nil]
|
|
59
|
-
def self.scan_for_years(token, post_token, options)
|
|
60
|
-
if token.word =~ /^([1-9]\d)?\d\d?$/
|
|
61
|
-
unless post_token && DAY_PORTIONS.include?(post_token.word)
|
|
62
|
-
year = make_year(token.word.to_i, options[:ambiguous_year_future_bias])
|
|
63
|
-
return ScalarYear.new(year.to_i)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
46
|
+
class ScalarSecond < Scalar #:nodoc:
|
|
47
|
+
def to_s
|
|
48
|
+
super << '-second-' << @type.to_s
|
|
66
49
|
end
|
|
50
|
+
end
|
|
67
51
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# make_year(96, 50) #=> 1996
|
|
72
|
-
# make_year(79, 20) #=> 2079
|
|
73
|
-
# make_year(00, 50) #=> 2000
|
|
74
|
-
#
|
|
75
|
-
# @param [Integer] year The two digit year to build from
|
|
76
|
-
# @param [Integer] bias The amount of future years to bias
|
|
77
|
-
# @return [Integer] The 4 digit year
|
|
78
|
-
def self.make_year(year, bias)
|
|
79
|
-
return year if year.to_s.size > 2
|
|
80
|
-
start_year = Chronic.time_class.now.year - bias
|
|
81
|
-
century = (start_year / 100) * 100
|
|
82
|
-
full_year = century + year
|
|
83
|
-
full_year += 100 if full_year < start_year
|
|
84
|
-
full_year
|
|
52
|
+
class ScalarMinute < Scalar #:nodoc:
|
|
53
|
+
def to_s
|
|
54
|
+
super << '-minute-' << @type.to_s
|
|
85
55
|
end
|
|
56
|
+
end
|
|
86
57
|
|
|
58
|
+
class ScalarHour < Scalar #:nodoc:
|
|
87
59
|
def to_s
|
|
88
|
-
'
|
|
60
|
+
super << '-hour-' << @type.to_s
|
|
89
61
|
end
|
|
90
62
|
end
|
|
91
63
|
|
data/lib/chronic/season.rb
CHANGED
|
@@ -1,35 +1,24 @@
|
|
|
1
1
|
module Chronic
|
|
2
2
|
class Season
|
|
3
|
-
# @return [MiniDate]
|
|
4
|
-
attr_reader :start
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
attr_reader :start
|
|
7
5
|
attr_reader :end
|
|
8
6
|
|
|
9
|
-
# @param [MiniDate] start_date
|
|
10
|
-
# @param [MiniDate] end_date
|
|
11
7
|
def initialize(start_date, end_date)
|
|
12
8
|
@start = start_date
|
|
13
9
|
@end = end_date
|
|
14
10
|
end
|
|
15
11
|
|
|
16
|
-
# @param [Symbol] season The season name
|
|
17
|
-
# @param [Integer] pointer The direction (-1 for past, 1 for future)
|
|
18
|
-
# @return [Symbol] The new season name
|
|
19
12
|
def self.find_next_season(season, pointer)
|
|
20
13
|
lookup = [:spring, :summer, :autumn, :winter]
|
|
21
14
|
next_season_num = (lookup.index(season) + 1 * pointer) % 4
|
|
22
15
|
lookup[next_season_num]
|
|
23
16
|
end
|
|
24
17
|
|
|
25
|
-
# @param [Symbol] season The season name
|
|
26
|
-
# @return [Symbol] The new season name
|
|
27
18
|
def self.season_after(season)
|
|
28
19
|
find_next_season(season, +1)
|
|
29
20
|
end
|
|
30
21
|
|
|
31
|
-
# @param [Symbol] season The season name
|
|
32
|
-
# @return [Symbol] The new season name
|
|
33
22
|
def self.season_before(season)
|
|
34
23
|
find_next_season(season, -1)
|
|
35
24
|
end
|