chronic 0.4.3 → 0.4.4
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/.gemtest +0 -0
- data/.gitignore +1 -0
- data/.yardopts +1 -1
- data/HISTORY.md +12 -0
- data/Manifest.txt +1 -2
- data/README.md +3 -2
- data/lib/chronic.rb +1 -1
- data/lib/chronic/chronic.rb +2 -1
- data/lib/chronic/handlers.rb +29 -12
- data/lib/chronic/repeaters/repeater_day.rb +0 -1
- data/lib/chronic/repeaters/repeater_day_name.rb +0 -1
- data/lib/chronic/repeaters/repeater_day_portion.rb +0 -1
- data/lib/chronic/repeaters/repeater_fortnight.rb +0 -1
- data/lib/chronic/repeaters/repeater_hour.rb +0 -1
- data/lib/chronic/repeaters/repeater_minute.rb +0 -1
- data/lib/chronic/repeaters/repeater_month.rb +0 -1
- data/lib/chronic/repeaters/repeater_month_name.rb +0 -1
- data/lib/chronic/repeaters/repeater_season.rb +25 -8
- data/lib/chronic/repeaters/repeater_second.rb +0 -1
- data/lib/chronic/repeaters/repeater_time.rb +0 -1
- data/lib/chronic/repeaters/repeater_week.rb +0 -1
- data/lib/chronic/repeaters/repeater_weekday.rb +0 -1
- data/lib/chronic/repeaters/repeater_weekend.rb +0 -1
- data/lib/chronic/repeaters/repeater_year.rb +19 -8
- data/lib/chronic/token.rb +1 -1
- data/test/test_RepeaterYear.rb +7 -0
- metadata +5 -18
- data/benchmark/benchmark.rb +0 -13
data/.gemtest
ADDED
File without changes
|
data/.gitignore
CHANGED
data/.yardopts
CHANGED
data/HISTORY.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
# 0.4.4
|
2
|
+
|
3
|
+
* Fix RepeaterYear for fetching past year offsets when the current day is
|
4
|
+
later than the last day of the same month in a past year (leap years) ie
|
5
|
+
on 29th/feb (leap year) `last year` should (and now does) return 28th/feb
|
6
|
+
instead of 1st/march
|
7
|
+
|
8
|
+
# 0.4.3 / 2011-06-08
|
9
|
+
|
10
|
+
* Fix issue with parsing 1:xxPM -- Ensure 1 is treated as ambiguous, not
|
11
|
+
just >1
|
12
|
+
|
1
13
|
# 0.4.2 / 2011-06-07
|
2
14
|
|
3
15
|
* Fix MonthRepeater for fetching past month offsets when current day is
|
data/Manifest.txt
CHANGED
@@ -3,7 +3,6 @@ LICENSE
|
|
3
3
|
Manifest.txt
|
4
4
|
README.md
|
5
5
|
Rakefile
|
6
|
-
benchmark/benchmark.rb
|
7
6
|
chronic.gemspec
|
8
7
|
lib/chronic.rb
|
9
8
|
lib/chronic/chronic.rb
|
@@ -56,4 +55,4 @@ test/test_RepeaterYear.rb
|
|
56
55
|
test/test_Span.rb
|
57
56
|
test/test_Time.rb
|
58
57
|
test/test_Token.rb
|
59
|
-
test/test_parsing.rb
|
58
|
+
test/test_parsing.rb
|
data/README.md
CHANGED
@@ -133,8 +133,9 @@ Specific Times (many of the above with an added time)
|
|
133
133
|
|
134
134
|
Chronic allows you to set which Time class to use when constructing times. By
|
135
135
|
default, the built in Ruby time class creates times in your system's local
|
136
|
-
time zone. You can set this to something like ActiveSupport's
|
137
|
-
|
136
|
+
time zone. You can set this to something like ActiveSupport's
|
137
|
+
[TimeZone](http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html)
|
138
|
+
class to get full time zone support.
|
138
139
|
|
139
140
|
>> Time.zone = "UTC"
|
140
141
|
>> Chronic.time_class = Time.zone
|
data/lib/chronic.rb
CHANGED
data/lib/chronic/chronic.rb
CHANGED
@@ -17,6 +17,8 @@ module Chronic
|
|
17
17
|
# will be returned (depending on the value of `:guess`). If no
|
18
18
|
# date or time can be found, `nil` will be returned
|
19
19
|
#
|
20
|
+
# @param [String] text The text to parse
|
21
|
+
#
|
20
22
|
# @option opts [Symbol] :context (:future)
|
21
23
|
# * If your string represents a birthday, you can set `:context` to
|
22
24
|
# `:past` and if an ambiguous string is given, it will assume it is
|
@@ -57,7 +59,6 @@ module Chronic
|
|
57
59
|
#
|
58
60
|
# @return [Time, Chronic::Span, nil]
|
59
61
|
def parse(text, opts={})
|
60
|
-
@text = text
|
61
62
|
options = DEFAULT_OPTIONS.merge opts
|
62
63
|
|
63
64
|
# ensure the specified options are valid
|
data/lib/chronic/handlers.rb
CHANGED
@@ -102,7 +102,7 @@ module Chronic
|
|
102
102
|
def handle_sd_rmn_sy(tokens, options) #:nodoc:
|
103
103
|
new_tokens = [tokens[1], tokens[0], tokens[2]]
|
104
104
|
time_tokens = tokens.last(tokens.size - 3)
|
105
|
-
|
105
|
+
handle_rmn_sd_sy(new_tokens + time_tokens, options)
|
106
106
|
end
|
107
107
|
|
108
108
|
# Handle scalar-month/scalar-day/scalar-year (endian middle)
|
@@ -125,14 +125,14 @@ module Chronic
|
|
125
125
|
def handle_sd_sm_sy(tokens, options) #:nodoc:
|
126
126
|
new_tokens = [tokens[1], tokens[0], tokens[2]]
|
127
127
|
time_tokens = tokens.last(tokens.size - 3)
|
128
|
-
|
128
|
+
handle_sm_sd_sy(new_tokens + time_tokens, options)
|
129
129
|
end
|
130
130
|
|
131
131
|
# Handle scalar-year/scalar-month/scalar-day
|
132
132
|
def handle_sy_sm_sd(tokens, options) #:nodoc:
|
133
133
|
new_tokens = [tokens[1], tokens[2], tokens[0]]
|
134
134
|
time_tokens = tokens.last(tokens.size - 3)
|
135
|
-
|
135
|
+
handle_sm_sd_sy(new_tokens + time_tokens, options)
|
136
136
|
end
|
137
137
|
|
138
138
|
# Handle scalar-month/scalar-year
|
@@ -160,13 +160,13 @@ module Chronic
|
|
160
160
|
# Handle repeaters
|
161
161
|
def handle_r(tokens, options) #:nodoc:
|
162
162
|
dd_tokens = dealias_and_disambiguate_times(tokens, options)
|
163
|
-
|
163
|
+
get_anchor(dd_tokens, options)
|
164
164
|
end
|
165
165
|
|
166
166
|
# Handle repeater/grabber/repeater
|
167
167
|
def handle_r_g_r(tokens, options) #:nodoc:
|
168
168
|
new_tokens = [tokens[1], tokens[0], tokens[2]]
|
169
|
-
|
169
|
+
handle_r(new_tokens, options)
|
170
170
|
end
|
171
171
|
|
172
172
|
# arrows
|
@@ -185,19 +185,19 @@ module Chronic
|
|
185
185
|
repeater = tokens[1].get_tag(Repeater)
|
186
186
|
span = Span.new(Chronic.now, Chronic.now + 1)
|
187
187
|
|
188
|
-
|
188
|
+
handle_srp(tokens, span, options)
|
189
189
|
end
|
190
190
|
|
191
191
|
# Handle pointer/scalar/repeater
|
192
192
|
def handle_p_s_r(tokens, options) #:nodoc:
|
193
193
|
new_tokens = [tokens[1], tokens[2], tokens[0]]
|
194
|
-
|
194
|
+
handle_s_r_p(new_tokens, options)
|
195
195
|
end
|
196
196
|
|
197
197
|
# Handle scalar/repeater/pointer/anchor
|
198
198
|
def handle_s_r_p_a(tokens, options) #:nodoc:
|
199
199
|
anchor_span = get_anchor(tokens[3..tokens.size - 1], options)
|
200
|
-
|
200
|
+
handle_srp(tokens, anchor_span, options)
|
201
201
|
end
|
202
202
|
|
203
203
|
# narrows
|
@@ -247,7 +247,7 @@ module Chronic
|
|
247
247
|
grabber = Grabber.new(:this)
|
248
248
|
pointer = :future
|
249
249
|
|
250
|
-
repeaters =
|
250
|
+
repeaters = get_repeaters(tokens)
|
251
251
|
repeaters.size.times { tokens.pop }
|
252
252
|
|
253
253
|
if tokens.first && tokens.first.get_tag(Grabber)
|
@@ -358,18 +358,33 @@ module Chronic
|
|
358
358
|
|
359
359
|
end
|
360
360
|
|
361
|
-
class Handler
|
362
|
-
|
361
|
+
class Handler
|
362
|
+
# @return [Array] A list of patterns
|
363
|
+
attr_accessor :pattern
|
363
364
|
|
365
|
+
# @return [Symbol] The method which handles this list of patterns.
|
366
|
+
# This method should exist inside the {Handlers} module
|
367
|
+
attr_accessor :handler_method
|
368
|
+
|
369
|
+
# @param [Array] pattern A list of patterns to match tokens against
|
370
|
+
# @param [Symbol] handler_method The method to be invoked when patterns
|
371
|
+
# are matched. This method should exist inside the {Handlers} module
|
364
372
|
def initialize(pattern, handler_method)
|
365
373
|
@pattern = pattern
|
366
374
|
@handler_method = handler_method
|
367
375
|
end
|
368
376
|
|
377
|
+
# @param [#to_s] The snake_case name representing a Chronic constant
|
378
|
+
# @return [Class] The class represented by `name`
|
379
|
+
# @raise [NameError] Raises if this constant could not be found
|
369
380
|
def constantize(name)
|
370
381
|
Chronic.const_get name.to_s.gsub(/(^|_)(.)/) { $2.upcase }
|
371
382
|
end
|
372
383
|
|
384
|
+
# @param [Array] tokens
|
385
|
+
# @param [Hash] definitions
|
386
|
+
# @return [Boolean]
|
387
|
+
# @see Chronic.tokens_to_span
|
373
388
|
def match(tokens, definitions)
|
374
389
|
token_index = 0
|
375
390
|
@pattern.each do |element|
|
@@ -397,8 +412,10 @@ module Chronic
|
|
397
412
|
return true
|
398
413
|
end
|
399
414
|
|
415
|
+
# @param [Handler] The handler to compare
|
416
|
+
# @return [Boolean] True if these handlers match
|
400
417
|
def ==(other)
|
401
|
-
|
418
|
+
@pattern == other.pattern
|
402
419
|
end
|
403
420
|
end
|
404
421
|
|
@@ -1,20 +1,38 @@
|
|
1
1
|
module Chronic
|
2
2
|
class Season
|
3
|
-
|
3
|
+
# @return [MiniDate]
|
4
|
+
attr_reader :start
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
# @return [MiniDate]
|
7
|
+
attr_reader :end
|
8
|
+
|
9
|
+
# @param [MiniDate] start_date
|
10
|
+
# @param [MiniDate] end_date
|
11
|
+
def initialize(start_date, end_date)
|
12
|
+
@start = start_date
|
13
|
+
@end = end_date
|
8
14
|
end
|
9
15
|
|
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
|
10
19
|
def self.find_next_season(season, pointer)
|
11
20
|
lookup = {:spring => 0, :summer => 1, :autumn => 2, :winter => 3}
|
12
|
-
next_season_num = (lookup[season]+1*pointer) % 4
|
21
|
+
next_season_num = (lookup[season] + 1 * pointer) % 4
|
13
22
|
lookup.invert[next_season_num]
|
14
23
|
end
|
15
24
|
|
16
|
-
|
17
|
-
|
25
|
+
# @param [Symbol] season The season name
|
26
|
+
# @return [Symbol] The new season name
|
27
|
+
def self.season_after(season)
|
28
|
+
find_next_season(season, +1)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [Symbol] season The season name
|
32
|
+
# @return [Symbol] The new season name
|
33
|
+
def self.season_before(season)
|
34
|
+
find_next_season(season, -1)
|
35
|
+
end
|
18
36
|
end
|
19
37
|
|
20
38
|
class RepeaterSeason < Repeater #:nodoc:
|
@@ -28,7 +46,6 @@ module Chronic
|
|
28
46
|
|
29
47
|
def initialize(type)
|
30
48
|
super
|
31
|
-
@next_season_start = nil
|
32
49
|
end
|
33
50
|
|
34
51
|
def next(pointer)
|
@@ -4,7 +4,6 @@ module Chronic
|
|
4
4
|
|
5
5
|
def initialize(type)
|
6
6
|
super
|
7
|
-
@current_year_start = nil
|
8
7
|
end
|
9
8
|
|
10
9
|
def next(pointer)
|
@@ -45,13 +44,8 @@ module Chronic
|
|
45
44
|
|
46
45
|
def offset(span, amount, pointer)
|
47
46
|
direction = pointer == :future ? 1 : -1
|
48
|
-
|
49
|
-
|
50
|
-
new_begin = Time.construct(sb.year + (amount * direction), sb.month, sb.day, sb.hour, sb.min, sb.sec)
|
51
|
-
|
52
|
-
se = span.end
|
53
|
-
new_end = Time.construct(se.year + (amount * direction), se.month, se.day, se.hour, se.min, se.sec)
|
54
|
-
|
47
|
+
new_begin = build_offset_time(span.begin, amount, direction)
|
48
|
+
new_end = build_offset_time(span.end, amount, direction)
|
55
49
|
Span.new(new_begin, new_end)
|
56
50
|
end
|
57
51
|
|
@@ -62,5 +56,22 @@ module Chronic
|
|
62
56
|
def to_s
|
63
57
|
super << '-year'
|
64
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def build_offset_time(time, amount, direction)
|
63
|
+
year = time.year + (amount * direction)
|
64
|
+
days = month_days(year, time.month)
|
65
|
+
day = time.day > days ? days : time.day
|
66
|
+
Time.construct(year, time.month, day, time.hour, time.min, time.sec)
|
67
|
+
end
|
68
|
+
|
69
|
+
def month_days(year, month)
|
70
|
+
if Date.leap?(year)
|
71
|
+
RepeaterMonth::MONTH_DAYS_LEAP[month - 1]
|
72
|
+
else
|
73
|
+
RepeaterMonth::MONTH_DAYS[month - 1]
|
74
|
+
end
|
75
|
+
end
|
65
76
|
end
|
66
77
|
end
|
data/lib/chronic/token.rb
CHANGED
data/test/test_RepeaterYear.rb
CHANGED
@@ -57,6 +57,13 @@ class TestRepeaterYear < Test::Unit::TestCase
|
|
57
57
|
|
58
58
|
assert_equal Time.local(1996, 8, 16, 14), offset_span.begin
|
59
59
|
assert_equal Time.local(1996, 8, 16, 14, 0, 1), offset_span.end
|
60
|
+
|
61
|
+
now = Time.local(2008, 2, 29)
|
62
|
+
span = Chronic::Span.new(now, now + 1)
|
63
|
+
offset_span = Chronic::RepeaterYear.new(:year).offset(span, 1, :past)
|
64
|
+
|
65
|
+
assert_equal Time.local(2007, 2, 28), offset_span.begin
|
66
|
+
assert_equal Time.local(2007, 2, 28, 0, 0, 1), offset_span.end
|
60
67
|
end
|
61
68
|
|
62
69
|
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chronic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
- 3
|
10
|
-
version: 0.4.3
|
4
|
+
prerelease:
|
5
|
+
version: 0.4.4
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Tom Preston-Werner
|
@@ -16,8 +11,7 @@ autorequire:
|
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
13
|
|
19
|
-
date: 2011-06-
|
20
|
-
default_executable:
|
14
|
+
date: 2011-06-12 00:00:00 Z
|
21
15
|
dependencies: []
|
22
16
|
|
23
17
|
description: Chronic is a natural language date/time parser written in pure Ruby.
|
@@ -33,6 +27,7 @@ extra_rdoc_files:
|
|
33
27
|
- HISTORY.md
|
34
28
|
- LICENSE
|
35
29
|
files:
|
30
|
+
- .gemtest
|
36
31
|
- .gitignore
|
37
32
|
- .yardopts
|
38
33
|
- HISTORY.md
|
@@ -40,7 +35,6 @@ files:
|
|
40
35
|
- Manifest.txt
|
41
36
|
- README.md
|
42
37
|
- Rakefile
|
43
|
-
- benchmark/benchmark.rb
|
44
38
|
- chronic.gemspec
|
45
39
|
- lib/chronic.rb
|
46
40
|
- lib/chronic/chronic.rb
|
@@ -94,7 +88,6 @@ files:
|
|
94
88
|
- test/test_Time.rb
|
95
89
|
- test/test_Token.rb
|
96
90
|
- test/test_parsing.rb
|
97
|
-
has_rdoc: true
|
98
91
|
homepage: http://github.com/mojombo/chronic
|
99
92
|
licenses: []
|
100
93
|
|
@@ -108,23 +101,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
101
|
requirements:
|
109
102
|
- - ">="
|
110
103
|
- !ruby/object:Gem::Version
|
111
|
-
hash: 3
|
112
|
-
segments:
|
113
|
-
- 0
|
114
104
|
version: "0"
|
115
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
106
|
none: false
|
117
107
|
requirements:
|
118
108
|
- - ">="
|
119
109
|
- !ruby/object:Gem::Version
|
120
|
-
hash: 3
|
121
|
-
segments:
|
122
|
-
- 0
|
123
110
|
version: "0"
|
124
111
|
requirements: []
|
125
112
|
|
126
113
|
rubyforge_project: chronic
|
127
|
-
rubygems_version: 1.
|
114
|
+
rubygems_version: 1.8.5
|
128
115
|
signing_key:
|
129
116
|
specification_version: 3
|
130
117
|
summary: Natural language date/time parsing.
|
data/benchmark/benchmark.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'chronic'
|
2
|
-
require 'benchmark'
|
3
|
-
|
4
|
-
print "jan 3 2010: "
|
5
|
-
puts Benchmark.measure { Chronic.parse("jan 3 2010") }
|
6
|
-
|
7
|
-
print "7 hours before tomorrow at midnight: "
|
8
|
-
puts Benchmark.measure { Chronic.parse("7 hours before tomorrow at midnight") }
|
9
|
-
|
10
|
-
# n = 100
|
11
|
-
# Benchmark.bm(14) do |x|
|
12
|
-
# x.report("jan 3 2010:") { for i in 1..n; Chronic.parse("jan 3 2010"); end }
|
13
|
-
# end
|