timelord 0.0.7 → 0.0.9
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 +4 -4
- data/README.md +33 -0
- data/lib/timelord.rb +5 -23
- data/lib/timelord/current_weekday.rb +26 -24
- data/lib/timelord/future.rb +16 -14
- data/lib/timelord/matcher.rb +21 -19
- data/lib/timelord/matcher_loader.rb +22 -20
- data/lib/timelord/matchers/current_thursday_matcher.rb +10 -8
- data/lib/timelord/matchers/current_tuesday_matcher.rb +10 -8
- data/lib/timelord/matchers/current_weekday_matcher.rb +10 -8
- data/lib/timelord/matchers/day_long_month_matcher.rb +10 -8
- data/lib/timelord/matchers/day_numeric_month_matcher.rb +13 -11
- data/lib/timelord/matchers/day_short_month_matcher.rb +10 -8
- data/lib/timelord/matchers/long_month_day_matcher.rb +10 -8
- data/lib/timelord/matchers/long_month_matcher.rb +15 -0
- data/lib/timelord/matchers/next_thursday_matcher.rb +6 -4
- data/lib/timelord/matchers/next_tuesday_matcher.rb +6 -4
- data/lib/timelord/matchers/next_weekday_matcher.rb +10 -8
- data/lib/timelord/matchers/ordinal_matcher.rb +10 -8
- data/lib/timelord/matchers/short_month_day_matcher.rb +10 -8
- data/lib/timelord/matchers/short_month_matcher.rb +15 -0
- data/lib/timelord/matchers/today_matcher.rb +6 -4
- data/lib/timelord/matchers/tomorrow_matcher.rb +6 -4
- data/lib/timelord/matchers/year_first_matcher.rb +6 -4
- data/lib/timelord/matchers/year_last_matcher.rb +9 -7
- data/lib/timelord/next_weekday.rb +26 -24
- data/lib/timelord/no_matcher.rb +10 -8
- data/lib/timelord/time_parser.rb +30 -0
- data/spec/timelord_spec.rb +7 -9
- metadata +6 -3
- data/README.rdoc +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e16c0c0b745d53b8f4553109faf2a416b110265
|
4
|
+
data.tar.gz: 4986c60f6647d7bcb6534f197419544db9ad9fa0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f8a573e32f56e46f28e0003af6ec5775cac28cc9d0302119e9e37c13e75ed30bbe6fffd9f179c9180d91b4adbd4d3db9b2ffebc6f0a4c9a7a244bd3708081ef7
|
7
|
+
data.tar.gz: b89cdddbe2e9993578115c7125fe76d82a368266bac956f0ec67dfeb71c6f56f83de237cabe2e4f8c775dddb297b19e8cfc02ebb61a82f01390337b442dc4740
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Timelord
|
2
|
+
[](https://codeclimate.com/github/halogenandtoast/timelord)
|
3
|
+
[](https://travis-ci.org/halogenandtoast/timelord)
|
4
|
+
|
5
|
+
Timelord parses dates out of strings. The string itself can contain non-date text - for instance: "Call Matt on Tuesday"
|
6
|
+
will return a date object for the upcoming Tuesday.
|
7
|
+
|
8
|
+
## Usage
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
require 'timelord'
|
12
|
+
Timelord.parse("Tuesday").to_s # "2011-01-04"
|
13
|
+
Timelord.parse("On Tuesday go for a walk").to_s # "2011-01-04"
|
14
|
+
```
|
15
|
+
|
16
|
+
|
17
|
+
For more examples, check out the [spec](https://github.com/halogenandtoast/timelord/blob/master/spec/timelord_spec.rb)
|
18
|
+
|
19
|
+
## Date format
|
20
|
+
|
21
|
+
The default date format is the international format. 11/01 is January 11th.
|
22
|
+
|
23
|
+
To use the american date format pass in :american as the second parameter
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
Timelord.parse("11/01").to_s # "2011-01-11"
|
27
|
+
Timelord.parse("11/01", :american) # "2011-11-01"
|
28
|
+
```
|
29
|
+
|
30
|
+
## In the future
|
31
|
+
|
32
|
+
As of version 0.0.1 all dates without a year automatically choose the next occurrence of that date. If there is demand
|
33
|
+
for the ability to retrieve previous dates, then the functionality will be added.
|
data/lib/timelord.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'date'
|
2
|
+
require 'timelord/time_parser'
|
2
3
|
require 'timelord/matcher'
|
3
4
|
require 'timelord/no_matcher'
|
4
5
|
require 'timelord/future'
|
@@ -6,24 +7,8 @@ require 'timelord/next_weekday'
|
|
6
7
|
require 'timelord/current_weekday'
|
7
8
|
require 'timelord/matcher_loader'
|
8
9
|
|
9
|
-
|
10
|
-
VERSION = "0.0.
|
11
|
-
|
12
|
-
def self.set_date(date)
|
13
|
-
@today = date
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.today
|
17
|
-
@today ||= Date.today
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.reset
|
21
|
-
@today = Date.today
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.matchers
|
25
|
-
@matchers ||= MatcherLoader.new.load_all
|
26
|
-
end
|
10
|
+
module Timelord
|
11
|
+
VERSION = "0.0.9"
|
27
12
|
|
28
13
|
# Parses a date str. Second parameter switches between international and american date formats.
|
29
14
|
#
|
@@ -32,10 +17,7 @@ class Timelord
|
|
32
17
|
# Timelord.parse("11/01", :american) # "2011-11-01"
|
33
18
|
#
|
34
19
|
# For more examples, check out the spec[https://github.com/halogenandtoast/timelord/blob/master/spec/timelord_spec.rb]
|
35
|
-
def self.parse(
|
36
|
-
|
37
|
-
map { |matcher| matcher.new(str, format: format, today: today) }.
|
38
|
-
detect(&:matches?).
|
39
|
-
to_date
|
20
|
+
def self.parse(string, options = {})
|
21
|
+
TimeParser.new(string, options).to_date
|
40
22
|
end
|
41
23
|
end
|
@@ -1,33 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Timelord
|
2
|
+
class CurrentWeekday
|
3
|
+
ONE_WEEK = 7
|
4
|
+
ZERO_WEEKS = 0
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def initialize(date_index, today)
|
7
|
+
@date_index = date_index
|
8
|
+
@today = today
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
def to_date
|
12
|
+
today + amount_to_increase
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
private
|
16
|
+
attr_reader :today, :date_index
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def current_index
|
19
|
+
today.cwday - 1
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
def amount_to_increase
|
23
|
+
diff = date_index - current_index
|
24
|
+
diff + number_of_weeks
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
def number_of_weeks
|
28
|
+
if date_index <= current_index
|
29
|
+
ONE_WEEK
|
30
|
+
else
|
31
|
+
ZERO_WEEKS
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
data/lib/timelord/future.rb
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Timelord
|
2
|
+
class Future
|
3
|
+
def initialize(date)
|
4
|
+
@current_date = date.dup
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
def to_date
|
8
|
+
if current_date < today
|
9
|
+
current_date.next_year
|
10
|
+
else
|
11
|
+
current_date
|
12
|
+
end
|
11
13
|
end
|
12
|
-
end
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
private
|
16
|
+
attr_reader :current_date
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
def today
|
19
|
+
Date.today
|
20
|
+
end
|
19
21
|
end
|
20
22
|
end
|
data/lib/timelord/matcher.rb
CHANGED
@@ -1,24 +1,26 @@
|
|
1
|
-
|
1
|
+
module Timelord
|
2
|
+
class Matcher
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
SHORT_MONTHS = %w(jan feb mar apr may jun jul aug sep oct nov dec).freeze
|
5
|
+
LONG_MONTHS = %w(january febuary march april may june july august september october november december).freeze
|
6
|
+
SHORT_MATCHER = SHORT_MONTHS.join('|').freeze
|
7
|
+
LONG_MATCHER = LONG_MONTHS.join('|').freeze
|
8
|
+
ORDINAL_MATCHER = "st|nd|rd|th".freeze
|
9
|
+
DAY_NAMES = %w(monday tuesday wednesday thursday friday saturday sunday).freeze
|
10
|
+
SHORT_DAY_NAMES = %w(mon tue wed thu fri sat sun).freeze
|
11
|
+
DAY_MATCHER = (DAY_NAMES + SHORT_DAY_NAMES).join('|').freeze
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
def initialize(string, options = {})
|
14
|
+
@string = string
|
15
|
+
@format = options[:format] || :international
|
16
|
+
@today = options[:today] || Date.today
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def matches?
|
20
|
+
@match ||= self.class::REGEX.match(string)
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
23
|
+
private
|
24
|
+
attr_reader :string, :match, :format, :today
|
25
|
+
end
|
24
26
|
end
|
@@ -1,27 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Timelord
|
2
|
+
class MatcherLoader
|
3
|
+
def load_all
|
4
|
+
matchers = files.map { |file| get_class(file) }
|
5
|
+
sort_matchers(matchers) + [NoMatcher]
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
+
private
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def files
|
11
|
+
Dir.glob(File.join(File.dirname(__FILE__), "matchers", "**"))
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
def get_class(file)
|
15
|
+
require file
|
16
|
+
Timelord.const_get(get_class_name(file))
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def get_class_name(file)
|
20
|
+
File.basename(file, ".rb").
|
21
|
+
gsub(/(_[a-z])/) { |a| a[1..-1].upcase }.
|
22
|
+
gsub(/^[a-z]/) { |a| a.upcase }
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
def sort_matchers(matchers)
|
26
|
+
matchers.sort { |a, b| b::REGEX.to_s.length <=> a::REGEX.to_s.length }
|
27
|
+
end
|
26
28
|
end
|
27
29
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class CurrentThursdayMatcher < Matcher
|
3
|
+
REGEX = /\b(thur|thurs)\b/
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
CurrentWeekday.new(date_index, today).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def date_index
|
12
|
+
DAY_NAMES.index("thursday")
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class CurrentTuesdayMatcher < Matcher
|
3
|
+
REGEX = /\btues\b/
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
CurrentWeekday.new(date_index, today).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def date_index
|
12
|
+
DAY_NAMES.index("tuesday")
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class CurrentWeekdayMatcher < Matcher
|
3
|
+
REGEX = /\b(#{DAY_MATCHER})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
CurrentWeekday.new(date_index, today).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def date_index
|
12
|
+
DAY_NAMES.index(match[1].downcase) || SHORT_DAY_NAMES.index(match[1].downcase)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class DayLongMonthMatcher < Matcher
|
3
|
+
REGEX = /\b(\d{1,2})\s+(#{LONG_MATCHER})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def parse_date
|
12
|
+
Date.civil(today.year, LONG_MONTHS.index(match[2].downcase) + 1, match[1].to_i)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,17 +1,19 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class DayNumericMonthMatcher < Matcher
|
3
|
+
REGEX = /\b(\d{1,2})\/(\d{1,2})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
def parse_date
|
12
|
+
if format == :american
|
13
|
+
Date.civil(today.year, match[1].to_i, match[2].to_i)
|
14
|
+
else
|
15
|
+
Date.civil(today.year, match[2].to_i, match[1].to_i)
|
16
|
+
end
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class DayShortMonthMatcher < Matcher
|
3
|
+
REGEX = /\b(\d{1,2})\s+(#{SHORT_MATCHER})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def parse_date
|
12
|
+
Date.civil(today.year, SHORT_MONTHS.index(match[2].downcase) + 1, match[1].to_i)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class LongMonthDayMatcher < Matcher
|
3
|
+
REGEX = /\b(#{LONG_MATCHER})\s+(\d{1,2})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def parse_date
|
12
|
+
Date.civil(today.year, LONG_MONTHS.index(match[1].downcase) + 1, match[2].to_i)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Timelord
|
2
|
+
class LongMonthMatcher < Matcher
|
3
|
+
REGEX = /\b(#{LONG_MATCHER})\b/i
|
4
|
+
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def parse_date
|
12
|
+
Date.civil(today.year, LONG_MONTHS.index(match[1].downcase) + 1)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class NextThursdayMatcher < Matcher
|
3
|
+
REGEX = /\bnext (thur|thurs)\b/
|
3
4
|
|
4
|
-
|
5
|
-
|
5
|
+
def to_date
|
6
|
+
NextWeekday.new(DAY_NAMES.index("thursday"), today).to_date
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class NextTuesdayMatcher < Matcher
|
3
|
+
REGEX = /\bnext tues\b/
|
3
4
|
|
4
|
-
|
5
|
-
|
5
|
+
def to_date
|
6
|
+
NextWeekday.new(DAY_NAMES.index("tuesday"), today).to_date
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class NextWeekdayMatcher < Matcher
|
3
|
+
REGEX = /\bnext (#{DAY_MATCHER})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
NextWeekday.new(date_index, today).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def date_index
|
12
|
+
DAY_NAMES.index(match[1].downcase) || SHORT_DAY_NAMES.index(match[1].downcase)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class OrdinalMatcher < Matcher
|
3
|
+
REGEX = /\b(\d{1,2})(#{ORDINAL_MATCHER})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def parse_date
|
12
|
+
Date.civil(today.year, today.month, match[1].to_i)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class ShortMonthDayMatcher < Matcher
|
3
|
+
REGEX = /\b(#{SHORT_MATCHER})\s+(\d{1,2})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
+
private
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
def parse_date
|
12
|
+
Date.civil(today.year, SHORT_MONTHS.index(match[1].downcase) + 1, match[2].to_i)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Timelord
|
2
|
+
class ShortMonthMatcher < Matcher
|
3
|
+
REGEX = /\b(#{SHORT_MATCHER})\b/i
|
4
|
+
|
5
|
+
def to_date
|
6
|
+
Future.new(parse_date).to_date
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def parse_date
|
12
|
+
Date.civil(today.year, SHORT_MONTHS.index(match[1].downcase) + 1)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class YearFirstMatcher < Matcher
|
3
|
+
REGEX = /\b(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
5
|
+
def to_date
|
6
|
+
Date.civil(match[1].to_i, match[2].to_i, match[3].to_i)
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Timelord
|
2
|
+
class YearLastMatcher < Matcher
|
3
|
+
REGEX = /\b(\d{1,2})\/(\d{1,2})\/(\d{2}(\d{2})?)\b/i
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
def to_date
|
6
|
+
if format == :american
|
7
|
+
Date.civil(match[3].to_i, match[1].to_i, match[2].to_i)
|
8
|
+
else
|
9
|
+
Date.civil(match[3].to_i, match[2].to_i, match[1].to_i)
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -1,33 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Timelord
|
2
|
+
class NextWeekday
|
3
|
+
ONE_WEEK = 7
|
4
|
+
TWO_WEEKS = 14
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def initialize(date_index, today)
|
7
|
+
@date_index = date_index
|
8
|
+
@today = today
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
def to_date
|
12
|
+
today + amount_to_increase
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
private
|
16
|
+
attr_reader :today, :date_index
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def amount_to_increase
|
19
|
+
diff = date_index - current_index
|
20
|
+
diff + number_of_weeks
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def number_of_weeks
|
24
|
+
if date_index <= current_index
|
25
|
+
TWO_WEEKS
|
26
|
+
else
|
27
|
+
ONE_WEEK
|
28
|
+
end
|
27
29
|
end
|
28
|
-
end
|
29
30
|
|
30
|
-
|
31
|
-
|
31
|
+
def current_index
|
32
|
+
today.cwday - 1
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
data/lib/timelord/no_matcher.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module Timelord
|
2
|
+
class NoMatcher
|
3
|
+
def initialize(string, options)
|
4
|
+
end
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
def matches?
|
7
|
+
true
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
def to_date
|
11
|
+
nil
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Timelord
|
2
|
+
class TimeParser
|
3
|
+
def initialize(string, options)
|
4
|
+
@string = string
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_date
|
9
|
+
matchers.
|
10
|
+
map { |matcher| matcher.new(string, format: format, today: today) }.
|
11
|
+
detect(&:matches?).
|
12
|
+
to_date
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
attr_reader :string, :options
|
17
|
+
|
18
|
+
def matchers
|
19
|
+
@matchers ||= MatcherLoader.new.load_all
|
20
|
+
end
|
21
|
+
|
22
|
+
def today
|
23
|
+
@today ||= options.fetch(:today) { Date.today }
|
24
|
+
end
|
25
|
+
|
26
|
+
def format
|
27
|
+
@format||= options.fetch(:format, :international)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/timelord_spec.rb
CHANGED
@@ -8,9 +8,7 @@ describe Timelord, 'parse' do
|
|
8
8
|
|
9
9
|
it "can set today to a different value" do
|
10
10
|
actual_date = Time.local(2010,12,5,10,5,0)
|
11
|
-
Timelord.
|
12
|
-
Timelord.parse("today").should == actual_date
|
13
|
-
Timelord.set_date(Date.today)
|
11
|
+
Timelord.parse("today", today: actual_date).should == actual_date
|
14
12
|
end
|
15
13
|
|
16
14
|
it "returns nil when no time is present" do
|
@@ -51,12 +49,12 @@ describe Timelord, 'parse' do
|
|
51
49
|
|
52
50
|
it "parses American style dates" do
|
53
51
|
first_of_december = Date.today
|
54
|
-
Timelord.parse("On 12/1/2010 I need to do something.", :american).should == first_of_december
|
52
|
+
Timelord.parse("On 12/1/2010 I need to do something.", format: :american).should == first_of_december
|
55
53
|
end
|
56
54
|
|
57
55
|
it "parses Internation style dates by default" do
|
58
56
|
first_of_december = Date.today
|
59
|
-
Timelord.parse("On 1/12/2010 I need to do something.", :international).should == first_of_december
|
57
|
+
Timelord.parse("On 1/12/2010 I need to do something.", format: :international).should == first_of_december
|
60
58
|
end
|
61
59
|
|
62
60
|
it "parses yyyy/mm/dd" do
|
@@ -81,10 +79,10 @@ describe Timelord, 'parse' do
|
|
81
79
|
|
82
80
|
it "parses mm/dd" do
|
83
81
|
first_of_december = Date.today
|
84
|
-
Timelord.parse("On 12/1 I need to do something.", :american).should == first_of_december
|
85
|
-
Timelord.parse("On 12/01 I need to do something.", :american).should == first_of_december
|
86
|
-
Timelord.parse("On 1/12 I need to do something.", :international).should == first_of_december
|
87
|
-
Timelord.parse("On 01/12 I need to do something.", :international).should == first_of_december
|
82
|
+
Timelord.parse("On 12/1 I need to do something.", format: :american).should == first_of_december
|
83
|
+
Timelord.parse("On 12/01 I need to do something.", format: :american).should == first_of_december
|
84
|
+
Timelord.parse("On 1/12 I need to do something.", format: :international).should == first_of_december
|
85
|
+
Timelord.parse("On 01/12 I need to do something.", format: :international).should == first_of_december
|
88
86
|
end
|
89
87
|
|
90
88
|
it "parses formats like 1st,2nd,3rd,4th,25th" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timelord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Mongeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: timecop
|
@@ -59,7 +59,7 @@ extensions: []
|
|
59
59
|
extra_rdoc_files: []
|
60
60
|
files:
|
61
61
|
- LICENSE
|
62
|
-
- README.
|
62
|
+
- README.md
|
63
63
|
- Rakefile
|
64
64
|
- lib/timelord.rb
|
65
65
|
- lib/timelord/current_weekday.rb
|
@@ -73,17 +73,20 @@ files:
|
|
73
73
|
- lib/timelord/matchers/day_numeric_month_matcher.rb
|
74
74
|
- lib/timelord/matchers/day_short_month_matcher.rb
|
75
75
|
- lib/timelord/matchers/long_month_day_matcher.rb
|
76
|
+
- lib/timelord/matchers/long_month_matcher.rb
|
76
77
|
- lib/timelord/matchers/next_thursday_matcher.rb
|
77
78
|
- lib/timelord/matchers/next_tuesday_matcher.rb
|
78
79
|
- lib/timelord/matchers/next_weekday_matcher.rb
|
79
80
|
- lib/timelord/matchers/ordinal_matcher.rb
|
80
81
|
- lib/timelord/matchers/short_month_day_matcher.rb
|
82
|
+
- lib/timelord/matchers/short_month_matcher.rb
|
81
83
|
- lib/timelord/matchers/today_matcher.rb
|
82
84
|
- lib/timelord/matchers/tomorrow_matcher.rb
|
83
85
|
- lib/timelord/matchers/year_first_matcher.rb
|
84
86
|
- lib/timelord/matchers/year_last_matcher.rb
|
85
87
|
- lib/timelord/next_weekday.rb
|
86
88
|
- lib/timelord/no_matcher.rb
|
89
|
+
- lib/timelord/time_parser.rb
|
87
90
|
- spec/spec_helper.rb
|
88
91
|
- spec/timelord_spec.rb
|
89
92
|
homepage: http://github.com/halogenandtoast/timelord
|
data/README.rdoc
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
=Timelord
|
2
|
-
|
3
|
-
Timelord parses dates out of strings. The string itself can contain non-date text - for instance: "Call Matt on Tuesday"
|
4
|
-
will return a date object for the upcoming Tuesday.
|
5
|
-
|
6
|
-
==Usage
|
7
|
-
|
8
|
-
require 'timelord'
|
9
|
-
Timelord.parse("Tuesday").to_s # "2011-01-04"
|
10
|
-
Timelord.parse("On Tuesday go for a walk").to_s # "2011-01-04"
|
11
|
-
|
12
|
-
For more examples, check out the spec[https://github.com/halogenandtoast/timelord/blob/master/spec/timelord_spec.rb]
|
13
|
-
|
14
|
-
==Date format
|
15
|
-
|
16
|
-
The default date format is the international format. 11/01 is January 11th.
|
17
|
-
|
18
|
-
To use the american date format pass in :american as the second parameter
|
19
|
-
|
20
|
-
Timelord.parse("11/01").to_s # "2011-01-11"
|
21
|
-
Timelord.parse("11/01", :american) # "2011-11-01"
|
22
|
-
|
23
|
-
==In the future
|
24
|
-
|
25
|
-
As of version 0.0.1 all dates without a year automatically choose the next occurrence of that date. If there is demand
|
26
|
-
for the ability to retrieve previous dates, then the functionality will be added.
|