chronic 0.6.5 → 0.8.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.
- data/.gitignore +1 -0
- data/HISTORY.md +25 -0
- data/README.md +5 -0
- data/chronic.gemspec +3 -0
- data/lib/chronic/chronic.rb +82 -67
- data/lib/chronic/grabber.rb +9 -7
- data/lib/chronic/handler.rb +10 -12
- data/lib/chronic/handlers.rb +84 -11
- data/lib/chronic/ordinal.rb +12 -9
- data/lib/chronic/pointer.rb +9 -7
- data/lib/chronic/repeater.rb +30 -20
- data/lib/chronic/repeaters/repeater_day_portion.rb +25 -11
- data/lib/chronic/scalar.rb +30 -23
- data/lib/chronic/season.rb +1 -12
- data/lib/chronic/separator.rb +21 -15
- data/lib/chronic/tag.rb +5 -11
- data/lib/chronic/time_zone.rb +9 -7
- data/lib/chronic/token.rb +12 -10
- data/lib/chronic.rb +50 -44
- data/test/helper.rb +7 -1
- data/test/{test_Chronic.rb → test_chronic.rb} +8 -6
- data/test/{test_DaylightSavings.rb → test_daylight_savings.rb} +1 -1
- data/test/{test_Handler.rb → test_handler.rb} +1 -1
- data/test/{test_MiniDate.rb → test_mini_date.rb} +9 -9
- data/test/{test_Numerizer.rb → test_numerizer.rb} +1 -1
- data/test/test_parsing.rb +149 -10
- 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} +1 -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} +1 -1
- data/test/{test_Token.rb → test_token.rb} +1 -1
- metadata +76 -44
- data/.gemtest +0 -0
- data/.yardopts +0 -3
data/lib/chronic/repeater.rb
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
module Chronic
|
|
2
2
|
class Repeater < Tag
|
|
3
3
|
|
|
4
|
-
# Scan an Array of
|
|
5
|
-
# each token
|
|
4
|
+
# Scan an Array of Token objects and apply any necessary Repeater
|
|
5
|
+
# tags to each token.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# tokens - An Array of tokens to scan.
|
|
8
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
9
|
+
#
|
|
10
|
+
# Returns an Array of tokens.
|
|
10
11
|
def self.scan(tokens, options)
|
|
11
12
|
tokens.each do |token|
|
|
12
13
|
if t = scan_for_season_names(token) then token.tag(t); next end
|
|
@@ -18,8 +19,9 @@ module Chronic
|
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
#
|
|
22
|
-
#
|
|
22
|
+
# token - The Token object we want to scan.
|
|
23
|
+
#
|
|
24
|
+
# Returns a new Repeater object.
|
|
23
25
|
def self.scan_for_season_names(token)
|
|
24
26
|
scan_for token, RepeaterSeasonName,
|
|
25
27
|
{
|
|
@@ -30,8 +32,9 @@ module Chronic
|
|
|
30
32
|
}
|
|
31
33
|
end
|
|
32
34
|
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
+
# token - The Token object we want to scan.
|
|
36
|
+
#
|
|
37
|
+
# Returns a new Repeater object.
|
|
35
38
|
def self.scan_for_month_names(token)
|
|
36
39
|
scan_for token, RepeaterMonthName,
|
|
37
40
|
{
|
|
@@ -50,23 +53,25 @@ module Chronic
|
|
|
50
53
|
}
|
|
51
54
|
end
|
|
52
55
|
|
|
53
|
-
#
|
|
54
|
-
#
|
|
56
|
+
# token - The Token object we want to scan.
|
|
57
|
+
#
|
|
58
|
+
# Returns a new Repeater object.
|
|
55
59
|
def self.scan_for_day_names(token)
|
|
56
60
|
scan_for token, RepeaterDayName,
|
|
57
61
|
{
|
|
58
62
|
/^m[ou]n(day)?$/ => :monday,
|
|
59
63
|
/^t(ue|eu|oo|u|)s?(day)?$/ => :tuesday,
|
|
60
64
|
/^we(d|dnes|nds|nns)(day)?$/ => :wednesday,
|
|
61
|
-
/^th(u
|
|
65
|
+
/^th(u|ur|urs|ers)(day)?$/ => :thursday,
|
|
62
66
|
/^fr[iy](day)?$/ => :friday,
|
|
63
67
|
/^sat(t?[ue]rday)?$/ => :saturday,
|
|
64
68
|
/^su[nm](day)?$/ => :sunday
|
|
65
69
|
}
|
|
66
70
|
end
|
|
67
71
|
|
|
68
|
-
#
|
|
69
|
-
#
|
|
72
|
+
# token - The Token object we want to scan.
|
|
73
|
+
#
|
|
74
|
+
# Returns a new Repeater object.
|
|
70
75
|
def self.scan_for_day_portions(token)
|
|
71
76
|
scan_for token, RepeaterDayPortion,
|
|
72
77
|
{
|
|
@@ -79,14 +84,16 @@ module Chronic
|
|
|
79
84
|
}
|
|
80
85
|
end
|
|
81
86
|
|
|
82
|
-
#
|
|
83
|
-
#
|
|
87
|
+
# token - The Token object we want to scan.
|
|
88
|
+
#
|
|
89
|
+
# Returns a new Repeater object.
|
|
84
90
|
def self.scan_for_times(token)
|
|
85
|
-
scan_for token, RepeaterTime, /^\d{1,2}(:?\d{2})?([\.:]?\d{2})?$/
|
|
91
|
+
scan_for token, RepeaterTime, /^\d{1,2}(:?\d{1,2})?([\.:]?\d{1,2})?$/
|
|
86
92
|
end
|
|
87
93
|
|
|
88
|
-
#
|
|
89
|
-
#
|
|
94
|
+
# token - The Token object we want to scan.
|
|
95
|
+
#
|
|
96
|
+
# Returns a new Repeater object.
|
|
90
97
|
def self.scan_for_units(token)
|
|
91
98
|
{
|
|
92
99
|
/^years?$/ => :year,
|
|
@@ -97,8 +104,11 @@ module Chronic
|
|
|
97
104
|
/^weekends?$/ => :weekend,
|
|
98
105
|
/^(week|business)days?$/ => :weekday,
|
|
99
106
|
/^days?$/ => :day,
|
|
107
|
+
/^hrs?$/ => :hour,
|
|
100
108
|
/^hours?$/ => :hour,
|
|
109
|
+
/^mins?$/ => :minute,
|
|
101
110
|
/^minutes?$/ => :minute,
|
|
111
|
+
/^secs?$/ => :second,
|
|
102
112
|
/^seconds?$/ => :second
|
|
103
113
|
}.each do |item, symbol|
|
|
104
114
|
if item =~ token.word
|
|
@@ -132,4 +142,4 @@ module Chronic
|
|
|
132
142
|
'repeater'
|
|
133
143
|
end
|
|
134
144
|
end
|
|
135
|
-
end
|
|
145
|
+
end
|
|
@@ -25,8 +25,6 @@ module Chronic
|
|
|
25
25
|
def next(pointer)
|
|
26
26
|
super
|
|
27
27
|
|
|
28
|
-
full_day = 60 * 60 * 24
|
|
29
|
-
|
|
30
28
|
if !@current_span
|
|
31
29
|
now_seconds = @now - Chronic.construct(@now.year, @now.month, @now.day)
|
|
32
30
|
if now_seconds < @range.begin
|
|
@@ -34,32 +32,38 @@ module Chronic
|
|
|
34
32
|
when :future
|
|
35
33
|
range_start = Chronic.construct(@now.year, @now.month, @now.day) + @range.begin
|
|
36
34
|
when :past
|
|
37
|
-
range_start = Chronic.construct(@now.year, @now.month, @now.day
|
|
35
|
+
range_start = Chronic.construct(@now.year, @now.month, @now.day - 1) + @range.begin
|
|
38
36
|
end
|
|
39
37
|
elsif now_seconds > @range.end
|
|
40
38
|
case pointer
|
|
41
39
|
when :future
|
|
42
|
-
range_start = Chronic.construct(@now.year, @now.month, @now.day
|
|
40
|
+
range_start = Chronic.construct(@now.year, @now.month, @now.day + 1) + @range.begin
|
|
43
41
|
when :past
|
|
44
42
|
range_start = Chronic.construct(@now.year, @now.month, @now.day) + @range.begin
|
|
45
43
|
end
|
|
46
44
|
else
|
|
47
45
|
case pointer
|
|
48
46
|
when :future
|
|
49
|
-
range_start = Chronic.construct(@now.year, @now.month, @now.day
|
|
47
|
+
range_start = Chronic.construct(@now.year, @now.month, @now.day + 1) + @range.begin
|
|
50
48
|
when :past
|
|
51
|
-
range_start = Chronic.construct(@now.year, @now.month, @now.day
|
|
49
|
+
range_start = Chronic.construct(@now.year, @now.month, @now.day - 1) + @range.begin
|
|
52
50
|
end
|
|
53
51
|
end
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
offset = (@range.end - @range.begin)
|
|
53
|
+
range_end = construct_date_from_reference_and_offset(range_start, offset)
|
|
54
|
+
@current_span = Span.new(range_start, range_end)
|
|
56
55
|
else
|
|
56
|
+
days_to_shift_window =
|
|
57
57
|
case pointer
|
|
58
58
|
when :future
|
|
59
|
-
|
|
59
|
+
1
|
|
60
60
|
when :past
|
|
61
|
-
|
|
61
|
+
-1
|
|
62
62
|
end
|
|
63
|
+
|
|
64
|
+
new_begin = Chronic.construct(@current_span.begin.year, @current_span.begin.month, @current_span.begin.day + days_to_shift_window, @current_span.begin.hour, @current_span.begin.min, @current_span.begin.sec)
|
|
65
|
+
new_end = Chronic.construct(@current_span.end.year, @current_span.end.month, @current_span.end.day + days_to_shift_window, @current_span.end.hour, @current_span.end.min, @current_span.end.sec)
|
|
66
|
+
@current_span = Span.new(new_begin, new_end)
|
|
63
67
|
end
|
|
64
68
|
end
|
|
65
69
|
|
|
@@ -67,7 +71,8 @@ module Chronic
|
|
|
67
71
|
super
|
|
68
72
|
|
|
69
73
|
range_start = Chronic.construct(@now.year, @now.month, @now.day) + @range.begin
|
|
70
|
-
|
|
74
|
+
range_end = construct_date_from_reference_and_offset(range_start)
|
|
75
|
+
@current_span = Span.new(range_start, range_end)
|
|
71
76
|
end
|
|
72
77
|
|
|
73
78
|
def offset(span, amount, pointer)
|
|
@@ -90,5 +95,14 @@ module Chronic
|
|
|
90
95
|
def to_s
|
|
91
96
|
super << '-dayportion-' << @type.to_s
|
|
92
97
|
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
def construct_date_from_reference_and_offset(reference, offset = nil)
|
|
101
|
+
elapsed_seconds_for_range = offset || (@range.end - @range.begin)
|
|
102
|
+
second_hand = ((elapsed_seconds_for_range - (12 * 60))) % 60
|
|
103
|
+
minute_hand = (elapsed_seconds_for_range - second_hand) / (60) % 60
|
|
104
|
+
hour_hand = (elapsed_seconds_for_range - minute_hand - second_hand) / (60 * 60) + reference.hour % 24
|
|
105
|
+
Chronic.construct(reference.year, reference.month, reference.day, hour_hand, minute_hand, second_hand)
|
|
106
|
+
end
|
|
93
107
|
end
|
|
94
108
|
end
|
data/lib/chronic/scalar.rb
CHANGED
|
@@ -2,12 +2,13 @@ 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
|
if t = scan_for_scalars(tokens[i], tokens[i + 1]) then tokens[i].tag(t) end
|
|
@@ -17,9 +18,10 @@ module Chronic
|
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
21
|
+
# token - The Token object we want to scan.
|
|
22
|
+
# post_token - The next Token object.
|
|
23
|
+
#
|
|
24
|
+
# Returns a new Scalar object.
|
|
23
25
|
def self.scan_for_scalars(token, post_token)
|
|
24
26
|
if token.word =~ /^\d*$/
|
|
25
27
|
unless post_token && DAY_PORTIONS.include?(post_token.word)
|
|
@@ -28,9 +30,10 @@ module Chronic
|
|
|
28
30
|
end
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
33
|
+
# token - The Token object we want to scan.
|
|
34
|
+
# post_token - The next Token object.
|
|
35
|
+
#
|
|
36
|
+
# Returns a new Scalar object.
|
|
34
37
|
def self.scan_for_days(token, post_token)
|
|
35
38
|
if token.word =~ /^\d\d?$/
|
|
36
39
|
toi = token.word.to_i
|
|
@@ -40,9 +43,10 @@ module Chronic
|
|
|
40
43
|
end
|
|
41
44
|
end
|
|
42
45
|
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
+
# token - The Token object we want to scan.
|
|
47
|
+
# post_token - The next Token object.
|
|
48
|
+
#
|
|
49
|
+
# Returns a new Scalar object.
|
|
46
50
|
def self.scan_for_months(token, post_token)
|
|
47
51
|
if token.word =~ /^\d\d?$/
|
|
48
52
|
toi = token.word.to_i
|
|
@@ -52,10 +56,11 @@ module Chronic
|
|
|
52
56
|
end
|
|
53
57
|
end
|
|
54
58
|
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
+
# token - The Token object we want to scan.
|
|
60
|
+
# post_token - The next Token object.
|
|
61
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
62
|
+
#
|
|
63
|
+
# Returns a new Scalar object.
|
|
59
64
|
def self.scan_for_years(token, post_token, options)
|
|
60
65
|
if token.word =~ /^([1-9]\d)?\d\d?$/
|
|
61
66
|
unless post_token && DAY_PORTIONS.include?(post_token.word)
|
|
@@ -65,16 +70,18 @@ module Chronic
|
|
|
65
70
|
end
|
|
66
71
|
end
|
|
67
72
|
|
|
68
|
-
# Build a year from a 2 digit suffix
|
|
73
|
+
# Build a year from a 2 digit suffix.
|
|
74
|
+
#
|
|
75
|
+
# year - The two digit Integer year to build from.
|
|
76
|
+
# bias - The Integer amount of future years to bias.
|
|
77
|
+
#
|
|
78
|
+
# Examples:
|
|
69
79
|
#
|
|
70
|
-
# @example
|
|
71
80
|
# make_year(96, 50) #=> 1996
|
|
72
81
|
# make_year(79, 20) #=> 2079
|
|
73
82
|
# make_year(00, 50) #=> 2000
|
|
74
83
|
#
|
|
75
|
-
#
|
|
76
|
-
# @param [Integer] bias The amount of future years to bias
|
|
77
|
-
# @return [Integer] The 4 digit year
|
|
84
|
+
# Returns The Integer 4 digit year.
|
|
78
85
|
def self.make_year(year, bias)
|
|
79
86
|
return year if year.to_s.size > 2
|
|
80
87
|
start_year = Chronic.time_class.now.year - bias
|
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
|
data/lib/chronic/separator.rb
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
module Chronic
|
|
2
2
|
class Separator < Tag
|
|
3
3
|
|
|
4
|
-
# Scan an Array of
|
|
5
|
-
# each token
|
|
4
|
+
# Scan an Array of Token objects and apply any necessary Separator
|
|
5
|
+
# tags to each token.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# tokens - An Array of tokens to scan.
|
|
8
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
9
|
+
#
|
|
10
|
+
# Returns an Array of tokens.
|
|
10
11
|
def self.scan(tokens, options)
|
|
11
12
|
tokens.each do |token|
|
|
12
13
|
if t = scan_for_commas(token) then token.tag(t); next end
|
|
@@ -17,14 +18,16 @@ module Chronic
|
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
20
|
-
#
|
|
21
|
-
#
|
|
21
|
+
# token - The Token object we want to scan.
|
|
22
|
+
#
|
|
23
|
+
# Returns a new SeparatorComma object.
|
|
22
24
|
def self.scan_for_commas(token)
|
|
23
25
|
scan_for token, SeparatorComma, { /^,$/ => :comma }
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
+
# token - The Token object we want to scan.
|
|
29
|
+
#
|
|
30
|
+
# Returns a new SeparatorSlashOrDash object.
|
|
28
31
|
def self.scan_for_slash_or_dash(token)
|
|
29
32
|
scan_for token, SeparatorSlashOrDash,
|
|
30
33
|
{
|
|
@@ -33,20 +36,23 @@ module Chronic
|
|
|
33
36
|
}
|
|
34
37
|
end
|
|
35
38
|
|
|
36
|
-
#
|
|
37
|
-
#
|
|
39
|
+
# token - The Token object we want to scan.
|
|
40
|
+
#
|
|
41
|
+
# Returns a new SeparatorAt object.
|
|
38
42
|
def self.scan_for_at(token)
|
|
39
43
|
scan_for token, SeparatorAt, { /^(at|@)$/ => :at }
|
|
40
44
|
end
|
|
41
45
|
|
|
42
|
-
#
|
|
43
|
-
#
|
|
46
|
+
# token - The Token object we want to scan.
|
|
47
|
+
#
|
|
48
|
+
# Returns a new SeparatorIn object.
|
|
44
49
|
def self.scan_for_in(token)
|
|
45
50
|
scan_for token, SeparatorIn, { /^in$/ => :in }
|
|
46
51
|
end
|
|
47
52
|
|
|
48
|
-
#
|
|
49
|
-
#
|
|
53
|
+
# token - The Token object we want to scan.
|
|
54
|
+
#
|
|
55
|
+
# Returns a new SeparatorOn object.
|
|
50
56
|
def self.scan_for_on(token)
|
|
51
57
|
scan_for token, SeparatorOn, { /^on$/ => :on }
|
|
52
58
|
end
|
data/lib/chronic/tag.rb
CHANGED
|
@@ -1,29 +1,23 @@
|
|
|
1
1
|
module Chronic
|
|
2
2
|
# Tokens are tagged with subclassed instances of this class when
|
|
3
|
-
# they match specific criteria
|
|
3
|
+
# they match specific criteria.
|
|
4
4
|
class Tag
|
|
5
5
|
|
|
6
|
-
# @return [Symbol]
|
|
7
6
|
attr_accessor :type
|
|
8
7
|
|
|
9
|
-
#
|
|
8
|
+
# type - The Symbol type of this tag.
|
|
10
9
|
def initialize(type)
|
|
11
10
|
@type = type
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
#
|
|
15
|
-
def start=(
|
|
16
|
-
@now =
|
|
13
|
+
# time - Set the start Time for this Tag.
|
|
14
|
+
def start=(time)
|
|
15
|
+
@now = time
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
class << self
|
|
20
19
|
private
|
|
21
20
|
|
|
22
|
-
# @param [Token] token
|
|
23
|
-
# @param [Class] klass The class instance to create
|
|
24
|
-
# @param [Regexp, Hash] items
|
|
25
|
-
# @return [Object, nil] either a new instance of `klass` or `nil` if
|
|
26
|
-
# no match is found
|
|
27
21
|
def scan_for(token, klass, items={})
|
|
28
22
|
case items
|
|
29
23
|
when Regexp
|
data/lib/chronic/time_zone.rb
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
module Chronic
|
|
2
2
|
class TimeZone < Tag
|
|
3
3
|
|
|
4
|
-
# Scan an Array of
|
|
5
|
-
# each token
|
|
4
|
+
# Scan an Array of Token objects and apply any necessary TimeZone
|
|
5
|
+
# tags to each token.
|
|
6
6
|
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# tokens - An Array of tokens to scan.
|
|
8
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
9
|
+
#
|
|
10
|
+
# Returns an Array of tokens.
|
|
10
11
|
def self.scan(tokens, options)
|
|
11
12
|
tokens.each do |token|
|
|
12
13
|
if t = scan_for_all(token) then token.tag(t); next end
|
|
13
14
|
end
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
#
|
|
17
|
-
#
|
|
17
|
+
# token - The Token object we want to scan.
|
|
18
|
+
#
|
|
19
|
+
# Returns a new Pointer object.
|
|
18
20
|
def self.scan_for_all(token)
|
|
19
21
|
scan_for token, self,
|
|
20
22
|
{
|
data/lib/chronic/token.rb
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
module Chronic
|
|
2
2
|
class Token
|
|
3
3
|
|
|
4
|
-
# @return [String] The word this Token represents
|
|
5
4
|
attr_accessor :word
|
|
6
|
-
|
|
7
|
-
# @return [Array] A list of tag associated with this Token
|
|
8
5
|
attr_accessor :tags
|
|
9
6
|
|
|
10
7
|
def initialize(word)
|
|
@@ -12,27 +9,32 @@ module Chronic
|
|
|
12
9
|
@tags = []
|
|
13
10
|
end
|
|
14
11
|
|
|
15
|
-
# Tag this token with the specified tag
|
|
12
|
+
# Tag this token with the specified tag.
|
|
13
|
+
#
|
|
14
|
+
# new_tag - The new Tag object.
|
|
16
15
|
#
|
|
17
|
-
#
|
|
16
|
+
# Returns nothing.
|
|
18
17
|
def tag(new_tag)
|
|
19
18
|
@tags << new_tag
|
|
20
19
|
end
|
|
21
20
|
|
|
22
|
-
# Remove all tags of the given class
|
|
21
|
+
# Remove all tags of the given class.
|
|
23
22
|
#
|
|
24
|
-
#
|
|
23
|
+
# tag_class - The tag Class to remove.
|
|
24
|
+
#
|
|
25
|
+
# Returns nothing.
|
|
25
26
|
def untag(tag_class)
|
|
26
27
|
@tags.delete_if { |m| m.kind_of? tag_class }
|
|
27
28
|
end
|
|
28
29
|
|
|
29
|
-
#
|
|
30
|
+
# Returns true if this token has any tags.
|
|
30
31
|
def tagged?
|
|
31
32
|
@tags.size > 0
|
|
32
33
|
end
|
|
33
34
|
|
|
34
|
-
#
|
|
35
|
-
#
|
|
35
|
+
# tag_class - The tag Class to search for.
|
|
36
|
+
#
|
|
37
|
+
# Returns The first Tag that matches the given class.
|
|
36
38
|
def get_tag(tag_class)
|
|
37
39
|
@tags.find { |m| m.kind_of? tag_class }
|
|
38
40
|
end
|
data/lib/chronic.rb
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
require 'time'
|
|
2
2
|
require 'date'
|
|
3
3
|
|
|
4
|
-
# Parse natural language dates and times into Time or
|
|
4
|
+
# Parse natural language dates and times into Time or Chronic::Span objects.
|
|
5
|
+
#
|
|
6
|
+
# Examples:
|
|
5
7
|
#
|
|
6
|
-
# @example
|
|
7
8
|
# require 'chronic'
|
|
8
9
|
#
|
|
9
10
|
# Time.now #=> Sun Aug 27 23:18:25 PDT 2006
|
|
@@ -25,17 +26,16 @@ require 'date'
|
|
|
25
26
|
#
|
|
26
27
|
# Chronic.parse('may 27th', :guess => false)
|
|
27
28
|
# #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
|
|
28
|
-
#
|
|
29
|
-
# @author Tom Preston-Werner, Lee Jarvis
|
|
30
29
|
module Chronic
|
|
31
|
-
VERSION = "0.
|
|
30
|
+
VERSION = "0.8.0"
|
|
32
31
|
|
|
33
32
|
class << self
|
|
34
33
|
|
|
35
|
-
#
|
|
34
|
+
# Returns true when debug mode is enabled.
|
|
36
35
|
attr_accessor :debug
|
|
37
36
|
|
|
38
|
-
#
|
|
37
|
+
# Examples:
|
|
38
|
+
#
|
|
39
39
|
# require 'chronic'
|
|
40
40
|
# require 'active_support/time'
|
|
41
41
|
#
|
|
@@ -44,63 +44,68 @@ module Chronic
|
|
|
44
44
|
# Chronic.parse('June 15 2006 at 5:54 AM')
|
|
45
45
|
# # => Thu, 15 Jun 2006 05:45:00 UTC +00:00
|
|
46
46
|
#
|
|
47
|
-
#
|
|
47
|
+
# Returns The Time class Chronic uses internally.
|
|
48
48
|
attr_accessor :time_class
|
|
49
49
|
|
|
50
|
-
# The current Time Chronic is using to base from
|
|
50
|
+
# The current Time Chronic is using to base from.
|
|
51
|
+
#
|
|
52
|
+
# Examples:
|
|
51
53
|
#
|
|
52
|
-
# @example
|
|
53
54
|
# Time.now #=> 2011-06-06 14:13:43 +0100
|
|
54
55
|
# Chronic.parse('yesterday') #=> 2011-06-05 12:00:00 +0100
|
|
55
56
|
#
|
|
56
57
|
# now = Time.local(2025, 12, 24)
|
|
57
58
|
# Chronic.parse('tomorrow', :now => now) #=> 2025-12-25 12:00:00 +0000
|
|
58
59
|
#
|
|
59
|
-
#
|
|
60
|
+
# Returns a Time object.
|
|
60
61
|
attr_accessor :now
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
self.debug = false
|
|
64
65
|
self.time_class = Time
|
|
66
|
+
|
|
67
|
+
autoload :Handler, 'chronic/handler'
|
|
68
|
+
autoload :Handlers, 'chronic/handlers'
|
|
69
|
+
autoload :MiniDate, 'chronic/mini_date'
|
|
70
|
+
autoload :Tag, 'chronic/tag'
|
|
71
|
+
autoload :Span, 'chronic/span'
|
|
72
|
+
autoload :Token, 'chronic/token'
|
|
73
|
+
autoload :Grabber, 'chronic/grabber'
|
|
74
|
+
autoload :Pointer, 'chronic/pointer'
|
|
75
|
+
autoload :Scalar, 'chronic/scalar'
|
|
76
|
+
autoload :Ordinal, 'chronic/ordinal'
|
|
77
|
+
autoload :OrdinalDay, 'chronic/ordinal'
|
|
78
|
+
autoload :Separator, 'chronic/separator'
|
|
79
|
+
autoload :TimeZone, 'chronic/time_zone'
|
|
80
|
+
autoload :Numerizer, 'chronic/numerizer'
|
|
81
|
+
autoload :Season, 'chronic/season'
|
|
82
|
+
|
|
83
|
+
autoload :Repeater, 'chronic/repeater'
|
|
84
|
+
autoload :RepeaterYear, 'chronic/repeaters/repeater_year'
|
|
85
|
+
autoload :RepeaterSeason, 'chronic/repeaters/repeater_season'
|
|
86
|
+
autoload :RepeaterSeasonName, 'chronic/repeaters/repeater_season_name'
|
|
87
|
+
autoload :RepeaterMonth, 'chronic/repeaters/repeater_month'
|
|
88
|
+
autoload :RepeaterMonthName, 'chronic/repeaters/repeater_month_name'
|
|
89
|
+
autoload :RepeaterFortnight, 'chronic/repeaters/repeater_fortnight'
|
|
90
|
+
autoload :RepeaterWeek, 'chronic/repeaters/repeater_week'
|
|
91
|
+
autoload :RepeaterWeekend, 'chronic/repeaters/repeater_weekend'
|
|
92
|
+
autoload :RepeaterWeekday, 'chronic/repeaters/repeater_weekday'
|
|
93
|
+
autoload :RepeaterDay, 'chronic/repeaters/repeater_day'
|
|
94
|
+
autoload :RepeaterDayName, 'chronic/repeaters/repeater_day_name'
|
|
95
|
+
autoload :RepeaterDayPortion, 'chronic/repeaters/repeater_day_portion'
|
|
96
|
+
autoload :RepeaterHour, 'chronic/repeaters/repeater_hour'
|
|
97
|
+
autoload :RepeaterMinute, 'chronic/repeaters/repeater_minute'
|
|
98
|
+
autoload :RepeaterSecond, 'chronic/repeaters/repeater_second'
|
|
99
|
+
autoload :RepeaterTime, 'chronic/repeaters/repeater_time'
|
|
100
|
+
|
|
65
101
|
end
|
|
66
102
|
|
|
67
103
|
require 'chronic/chronic'
|
|
68
|
-
require 'chronic/handler'
|
|
69
|
-
require 'chronic/handlers'
|
|
70
|
-
require 'chronic/mini_date'
|
|
71
|
-
require 'chronic/tag'
|
|
72
|
-
require 'chronic/span'
|
|
73
|
-
require 'chronic/token'
|
|
74
|
-
require 'chronic/grabber'
|
|
75
|
-
require 'chronic/pointer'
|
|
76
|
-
require 'chronic/scalar'
|
|
77
|
-
require 'chronic/ordinal'
|
|
78
|
-
require 'chronic/separator'
|
|
79
|
-
require 'chronic/time_zone'
|
|
80
|
-
require 'chronic/numerizer'
|
|
81
|
-
require 'chronic/season'
|
|
82
|
-
|
|
83
|
-
require 'chronic/repeater'
|
|
84
|
-
require 'chronic/repeaters/repeater_year'
|
|
85
|
-
require 'chronic/repeaters/repeater_season'
|
|
86
|
-
require 'chronic/repeaters/repeater_season_name'
|
|
87
|
-
require 'chronic/repeaters/repeater_month'
|
|
88
|
-
require 'chronic/repeaters/repeater_month_name'
|
|
89
|
-
require 'chronic/repeaters/repeater_fortnight'
|
|
90
|
-
require 'chronic/repeaters/repeater_week'
|
|
91
|
-
require 'chronic/repeaters/repeater_weekend'
|
|
92
|
-
require 'chronic/repeaters/repeater_weekday'
|
|
93
|
-
require 'chronic/repeaters/repeater_day'
|
|
94
|
-
require 'chronic/repeaters/repeater_day_name'
|
|
95
|
-
require 'chronic/repeaters/repeater_day_portion'
|
|
96
|
-
require 'chronic/repeaters/repeater_hour'
|
|
97
|
-
require 'chronic/repeaters/repeater_minute'
|
|
98
|
-
require 'chronic/repeaters/repeater_second'
|
|
99
|
-
require 'chronic/repeaters/repeater_time'
|
|
100
104
|
|
|
101
105
|
class Time
|
|
106
|
+
|
|
102
107
|
def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
|
|
103
|
-
warn "
|
|
108
|
+
warn "Time.construct will be deprecated in version 0.7.0. Please use Chronic.construct instead"
|
|
104
109
|
Chronic.construct(year, month, day, hour, minute, second)
|
|
105
110
|
end
|
|
106
111
|
|
|
@@ -108,4 +113,5 @@ class Time
|
|
|
108
113
|
warn "Time.to_minidate will be deprecated in version 0.7.0. Please use Chronic::MiniDate.from_time(time) instead"
|
|
109
114
|
Chronic::MiniDate.from_time(self)
|
|
110
115
|
end
|
|
116
|
+
|
|
111
117
|
end
|
data/test/helper.rb
CHANGED