halftime 0.0.1
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 +14 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/halftime.gemspec +26 -0
- data/lib/halftime.rb +2 -0
- data/lib/halftime/date_factories.rb +68 -0
- data/lib/halftime/internal_parser.rb +207 -0
- data/lib/halftime/meridies.rb +55 -0
- data/lib/halftime/parser.rb +32 -0
- data/lib/halftime/time_factory.rb +83 -0
- data/lib/halftime/time_of_day.rb +28 -0
- data/lib/halftime/time_zones.rb +26 -0
- data/lib/halftime/transform.rb +96 -0
- data/lib/halftime/version.rb +3 -0
- data/spec/lib/halftime/parser_spec.rb +260 -0
- data/spec/spec_helper.rb +0 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ec5f550eafbca8996051a85422fef96961fb4eb6
|
4
|
+
data.tar.gz: 24afbba15ed8e4046482ce8edf22e803d148eabf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6ca382c6ad2f0a435fb59ff46da92c8ed47ae89f21f5e6183fb931567ff9fefd91521e270c7311ebccc8568dc36f75d68a7d16e909bf21d7379daf455e212478
|
7
|
+
data.tar.gz: fb045141667c9aa781f183137f462c2573cfe14f4cb3404f82116c1c92f9b46737ae2e8b335bd66efdc0e97ccec32c90b2f99643455fb95e84204c65091e193b
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.4
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Carl Olof Erlandsson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Halftime
|
2
|
+
========
|
3
|
+
|
4
|
+
A natural language time parser.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem "halftime"
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install halftime
|
20
|
+
|
21
|
+
Usage
|
22
|
+
-----
|
23
|
+
|
24
|
+
require "halftime"
|
25
|
+
|
26
|
+
Halftime::Parser.new("tomorrow at 12", now: Time.now).time
|
27
|
+
|
28
|
+
If a time can not be parsed from the passed string, `Halftime::Parser#time` will
|
29
|
+
return `nil`.
|
data/Rakefile
ADDED
data/halftime.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'halftime/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "halftime"
|
8
|
+
spec.version = Halftime::VERSION
|
9
|
+
spec.authors = ["Calle Erlandsson"]
|
10
|
+
spec.email = ["calle@calleerlandsson.com"]
|
11
|
+
spec.summary = %q{Natural language time parser.}
|
12
|
+
spec.homepage = "https://github.com/calleerlandsson/halftime"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "activesupport"
|
21
|
+
spec.add_dependency "parslet"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
end
|
data/lib/halftime.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
module Halftime
|
2
|
+
module DateFactories
|
3
|
+
class Unambiguous
|
4
|
+
def initialize(year, month, day)
|
5
|
+
@year = year
|
6
|
+
@month = month
|
7
|
+
@day = day
|
8
|
+
end
|
9
|
+
|
10
|
+
def new(_)
|
11
|
+
Date.new(year, month, day)
|
12
|
+
end
|
13
|
+
|
14
|
+
def ambiguous?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :year, :month, :day
|
21
|
+
end
|
22
|
+
|
23
|
+
class Ambiguous
|
24
|
+
def new
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
|
28
|
+
def ambiguous?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Today < Ambiguous
|
34
|
+
def new(current)
|
35
|
+
current
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Tomorrow < Ambiguous
|
40
|
+
def new(current)
|
41
|
+
current.tomorrow
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class MonthDay < Ambiguous
|
46
|
+
def initialize(month, day)
|
47
|
+
@month = month
|
48
|
+
@day = day
|
49
|
+
end
|
50
|
+
|
51
|
+
def new(current)
|
52
|
+
advance(Date.new(current.year, month, day), current)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
attr_reader :month, :day
|
58
|
+
|
59
|
+
def advance(date, current)
|
60
|
+
if date <= current
|
61
|
+
date.advance(years: 1)
|
62
|
+
else
|
63
|
+
date
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require "parslet"
|
2
|
+
|
3
|
+
module Halftime
|
4
|
+
class InternalParser < Parslet::Parser
|
5
|
+
root :time_components
|
6
|
+
|
7
|
+
rule :time_components do
|
8
|
+
(date_and_or_time_of_day >> time_zone?).as(:time_components)
|
9
|
+
end
|
10
|
+
|
11
|
+
rule :date_and_or_time_of_day do
|
12
|
+
on? >> date >> at? >> time_of_day.maybe |
|
13
|
+
at? >> time_of_day >> on? >> date.maybe
|
14
|
+
end
|
15
|
+
|
16
|
+
rule :date do
|
17
|
+
(tomorrow | numerical_date | date_with_month_name).as(:date_factory)
|
18
|
+
end
|
19
|
+
|
20
|
+
rule :on? do
|
21
|
+
spaces? >> str("on").maybe >> spaces?
|
22
|
+
end
|
23
|
+
|
24
|
+
rule :tomorrow do
|
25
|
+
str("tomorrow").as(:tomorrow)
|
26
|
+
end
|
27
|
+
|
28
|
+
rule :numerical_date do
|
29
|
+
numerical_month_day >> (date_separator >> year).maybe |
|
30
|
+
(year >> date_separator).maybe >> numerical_month_day
|
31
|
+
end
|
32
|
+
|
33
|
+
rule :numerical_month_day do
|
34
|
+
month_number >> date_separator >> day |
|
35
|
+
day >> date_separator >> month_number
|
36
|
+
end
|
37
|
+
|
38
|
+
rule :date_with_month_name do
|
39
|
+
named_month_day >> (spaces >> year).maybe |
|
40
|
+
(year >> spaces).maybe >> named_month_day
|
41
|
+
end
|
42
|
+
|
43
|
+
rule :named_month_day do
|
44
|
+
month_name >> spaces? >> day | day >> spaces? >> month_name
|
45
|
+
end
|
46
|
+
|
47
|
+
rule :month_name do
|
48
|
+
(january | february | march | april | may | june | july | august |
|
49
|
+
september | october | november | december).as(:month)
|
50
|
+
end
|
51
|
+
|
52
|
+
rule :january do
|
53
|
+
(stri("January") | stri("Jan")).as(:january)
|
54
|
+
end
|
55
|
+
|
56
|
+
rule :february do
|
57
|
+
(stri("February") | stri("Feb")).as(:february)
|
58
|
+
end
|
59
|
+
|
60
|
+
rule :march do
|
61
|
+
(stri("March") | stri("Mar")).as(:march)
|
62
|
+
end
|
63
|
+
|
64
|
+
rule :april do
|
65
|
+
(stri("April") | stri("Apr")).as(:april)
|
66
|
+
end
|
67
|
+
|
68
|
+
rule :may do
|
69
|
+
stri("May").as(:may)
|
70
|
+
end
|
71
|
+
|
72
|
+
rule :june do
|
73
|
+
(stri("June") | stri("Jun")).as(:june)
|
74
|
+
end
|
75
|
+
|
76
|
+
rule :july do
|
77
|
+
(stri("July") | stri("Jul")).as(:july)
|
78
|
+
end
|
79
|
+
|
80
|
+
rule :august do
|
81
|
+
(stri("August") | stri("Aug")).as(:august)
|
82
|
+
end
|
83
|
+
|
84
|
+
rule :september do
|
85
|
+
(stri("September") | stri("Sep")).as(:september)
|
86
|
+
end
|
87
|
+
|
88
|
+
rule :october do
|
89
|
+
(stri("October") | stri("Oct")).as(:october)
|
90
|
+
end
|
91
|
+
|
92
|
+
rule :november do
|
93
|
+
(stri("November") | stri("Nov")).as(:november)
|
94
|
+
end
|
95
|
+
|
96
|
+
rule :december do
|
97
|
+
(stri("December") | stri("Dec")).as(:december)
|
98
|
+
end
|
99
|
+
|
100
|
+
rule :month_number do
|
101
|
+
one_to_twelve.as(:month)
|
102
|
+
end
|
103
|
+
|
104
|
+
rule :one_to_twelve do
|
105
|
+
(str("1") >> match("[0-2]") |
|
106
|
+
str("0").maybe >> match("[1-9]")).as(:integer)
|
107
|
+
end
|
108
|
+
|
109
|
+
rule :date_separator do
|
110
|
+
match("[/\-]")
|
111
|
+
end
|
112
|
+
|
113
|
+
rule :day do
|
114
|
+
one_to_thirty.as(:day)
|
115
|
+
end
|
116
|
+
|
117
|
+
rule :one_to_thirty do
|
118
|
+
(str("3") >> match("[0-1]") |
|
119
|
+
match("[1-2]") >> digit |
|
120
|
+
str("0").maybe >> match("[1-9]")).as(:integer)
|
121
|
+
end
|
122
|
+
|
123
|
+
rule :year do
|
124
|
+
digit.repeat(4).as(:integer).as(:year)
|
125
|
+
end
|
126
|
+
|
127
|
+
rule :digit do
|
128
|
+
match("[0-9]")
|
129
|
+
end
|
130
|
+
|
131
|
+
rule :time_of_day do
|
132
|
+
time_of_day_components.as(:time_of_day)
|
133
|
+
end
|
134
|
+
|
135
|
+
rule :time_of_day_components do
|
136
|
+
(hour >>
|
137
|
+
time_separator? >> minute? >>
|
138
|
+
time_separator? >> second? >>
|
139
|
+
spaces? >> meridiem?).as(:time_of_day_components)
|
140
|
+
end
|
141
|
+
|
142
|
+
rule :at? do
|
143
|
+
str("T") | spaces? >> (str("at") | str("@")).maybe >> spaces?
|
144
|
+
end
|
145
|
+
|
146
|
+
rule :hour do
|
147
|
+
zero_to_twentyfour.as(:hour)
|
148
|
+
end
|
149
|
+
|
150
|
+
rule :zero_to_twentyfour do
|
151
|
+
(str("2") >> match("[0-4]") |
|
152
|
+
match("[0-1]").maybe >> digit |
|
153
|
+
digit).as(:integer)
|
154
|
+
end
|
155
|
+
|
156
|
+
rule :time_separator? do
|
157
|
+
match("[:.]").maybe
|
158
|
+
end
|
159
|
+
|
160
|
+
rule :minute? do
|
161
|
+
zero_to_fiftynine.as(:minute).maybe
|
162
|
+
end
|
163
|
+
|
164
|
+
rule :second? do
|
165
|
+
zero_to_fiftynine.as(:second).maybe
|
166
|
+
end
|
167
|
+
|
168
|
+
rule :zero_to_fiftynine do
|
169
|
+
(match("[0-5]").maybe >> digit | digit).as(:integer)
|
170
|
+
end
|
171
|
+
|
172
|
+
rule :meridiem? do
|
173
|
+
(am | pm).as(:meridiem_factory).maybe
|
174
|
+
end
|
175
|
+
|
176
|
+
rule :am do
|
177
|
+
str("am").as(:am)
|
178
|
+
end
|
179
|
+
|
180
|
+
rule :pm do
|
181
|
+
str("pm").as(:pm)
|
182
|
+
end
|
183
|
+
|
184
|
+
rule :time_zone? do
|
185
|
+
(utc).as(:time_zone).maybe
|
186
|
+
end
|
187
|
+
|
188
|
+
rule :utc do
|
189
|
+
str("Z").as(:utc)
|
190
|
+
end
|
191
|
+
|
192
|
+
rule :spaces? do
|
193
|
+
spaces.maybe
|
194
|
+
end
|
195
|
+
|
196
|
+
rule :spaces do
|
197
|
+
str(" ").repeat(1)
|
198
|
+
end
|
199
|
+
|
200
|
+
def stri(string)
|
201
|
+
string.
|
202
|
+
split(//).
|
203
|
+
map! { |char| match("[#{char.upcase}#{char.downcase}]") }.
|
204
|
+
reduce(:>>)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Halftime
|
2
|
+
module Meridies
|
3
|
+
class Meridiem
|
4
|
+
def initialize(hour)
|
5
|
+
@hour = hour
|
6
|
+
end
|
7
|
+
|
8
|
+
def unspecified?
|
9
|
+
raise NotImplementedError
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_reader :hour
|
15
|
+
end
|
16
|
+
|
17
|
+
class Am < Meridiem
|
18
|
+
def hour
|
19
|
+
if super == 12
|
20
|
+
0
|
21
|
+
else
|
22
|
+
super
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def unspecified?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Pm < Meridiem
|
32
|
+
def hour
|
33
|
+
if super < 12
|
34
|
+
super + 12
|
35
|
+
else
|
36
|
+
super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def unspecified?
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Unspecified < Meridiem
|
46
|
+
def hour
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
def unspecified?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "parslet"
|
2
|
+
require "halftime/internal_parser"
|
3
|
+
require "halftime/transform"
|
4
|
+
|
5
|
+
module Halftime
|
6
|
+
class Parser
|
7
|
+
def initialize(string, now:)
|
8
|
+
@string = string
|
9
|
+
@now = now
|
10
|
+
@parser = InternalParser.new
|
11
|
+
@transform = Transform.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def time
|
15
|
+
time_factory.time(now)
|
16
|
+
rescue Parslet::ParseFailed
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def time_factory
|
23
|
+
transform.apply(tree)
|
24
|
+
end
|
25
|
+
|
26
|
+
def tree
|
27
|
+
parser.parse(string)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :string, :now, :parser, :transform
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require "active_support"
|
2
|
+
require "active_support/core_ext"
|
3
|
+
require "halftime/date_factories"
|
4
|
+
require "halftime/time_of_day"
|
5
|
+
require "halftime/time_zones"
|
6
|
+
|
7
|
+
module Halftime
|
8
|
+
class TimeFactory
|
9
|
+
def initialize(
|
10
|
+
date_factory: DateFactories::Today.new,
|
11
|
+
time_of_day: TimeOfDay.new,
|
12
|
+
time_zone: TimeZones::Current
|
13
|
+
)
|
14
|
+
@date_factory = date_factory
|
15
|
+
@time_of_day = time_of_day
|
16
|
+
@time_zone = time_zone
|
17
|
+
end
|
18
|
+
|
19
|
+
def time(now)
|
20
|
+
advance(base_time(now), now)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
delegate :hour, :minute, :second, to: :time_of_day
|
26
|
+
|
27
|
+
def base_time(now)
|
28
|
+
Time.new(
|
29
|
+
year(now),
|
30
|
+
month(now),
|
31
|
+
day(now),
|
32
|
+
hour,
|
33
|
+
minute,
|
34
|
+
second,
|
35
|
+
offset(now),
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def year(now)
|
40
|
+
date(now).year
|
41
|
+
end
|
42
|
+
|
43
|
+
def month(now)
|
44
|
+
date(now).month
|
45
|
+
end
|
46
|
+
|
47
|
+
def day(now)
|
48
|
+
date(now).day
|
49
|
+
end
|
50
|
+
|
51
|
+
def date(now)
|
52
|
+
date_factory.new(now.to_date)
|
53
|
+
end
|
54
|
+
|
55
|
+
def offset(now)
|
56
|
+
time_zone.new(now).offset
|
57
|
+
end
|
58
|
+
|
59
|
+
def advance(time, now)
|
60
|
+
if past?(time, now)
|
61
|
+
time + distance
|
62
|
+
else
|
63
|
+
time
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def past?(time, now)
|
68
|
+
date_factory.ambiguous? &&
|
69
|
+
time.to_date == now.to_date &&
|
70
|
+
time <= now
|
71
|
+
end
|
72
|
+
|
73
|
+
def distance
|
74
|
+
if time_of_day.ambiguous? && hour.between?(1, 11)
|
75
|
+
12.hours
|
76
|
+
else
|
77
|
+
1.day
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
attr_reader :date_factory, :time_of_day, :time_zone
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "halftime/meridies"
|
2
|
+
|
3
|
+
module Halftime
|
4
|
+
class TimeOfDay
|
5
|
+
attr_reader :minute, :second
|
6
|
+
|
7
|
+
delegate :hour, to: :meridiem
|
8
|
+
|
9
|
+
def initialize(
|
10
|
+
hour: 12,
|
11
|
+
minute: 0,
|
12
|
+
second: 0,
|
13
|
+
meridiem_factory: Meridies::Unspecified
|
14
|
+
)
|
15
|
+
@minute = minute
|
16
|
+
@second = second
|
17
|
+
@meridiem = meridiem_factory.new(hour)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ambiguous?
|
21
|
+
meridiem.unspecified?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :meridiem
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Halftime
|
2
|
+
module TimeZones
|
3
|
+
class Current
|
4
|
+
def initialize(now)
|
5
|
+
@now = now
|
6
|
+
end
|
7
|
+
|
8
|
+
def offset
|
9
|
+
now.utc_offset
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
attr_reader :now
|
15
|
+
end
|
16
|
+
|
17
|
+
class UTC
|
18
|
+
def initialize(_)
|
19
|
+
end
|
20
|
+
|
21
|
+
def offset
|
22
|
+
0
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require "active_support"
|
2
|
+
require "active_support/core_ext"
|
3
|
+
require "halftime/meridies"
|
4
|
+
require "halftime/time_factory"
|
5
|
+
require "halftime/time_of_day"
|
6
|
+
require "halftime/date_factories"
|
7
|
+
require "halftime/time_zones"
|
8
|
+
require "parslet"
|
9
|
+
|
10
|
+
module Halftime
|
11
|
+
class Transform < Parslet::Transform
|
12
|
+
rule integer: simple(:string) do
|
13
|
+
string.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
rule january: simple(:january) do
|
17
|
+
1
|
18
|
+
end
|
19
|
+
|
20
|
+
rule february: simple(:january) do
|
21
|
+
2
|
22
|
+
end
|
23
|
+
|
24
|
+
rule march: simple(:march) do
|
25
|
+
3
|
26
|
+
end
|
27
|
+
|
28
|
+
rule april: simple(:april) do
|
29
|
+
4
|
30
|
+
end
|
31
|
+
|
32
|
+
rule may: simple(:may) do
|
33
|
+
5
|
34
|
+
end
|
35
|
+
|
36
|
+
rule june: simple(:june) do
|
37
|
+
6
|
38
|
+
end
|
39
|
+
|
40
|
+
rule july: simple(:july) do
|
41
|
+
7
|
42
|
+
end
|
43
|
+
|
44
|
+
rule august: simple(:august) do
|
45
|
+
8
|
46
|
+
end
|
47
|
+
|
48
|
+
rule september: simple(:september) do
|
49
|
+
9
|
50
|
+
end
|
51
|
+
|
52
|
+
rule october: simple(:october) do
|
53
|
+
10
|
54
|
+
end
|
55
|
+
|
56
|
+
rule november: simple(:november) do
|
57
|
+
11
|
58
|
+
end
|
59
|
+
|
60
|
+
rule december: simple(:december) do
|
61
|
+
12
|
62
|
+
end
|
63
|
+
|
64
|
+
rule tomorrow: simple(:tomorrow) do
|
65
|
+
DateFactories::Tomorrow.new
|
66
|
+
end
|
67
|
+
|
68
|
+
rule month: simple(:month), day: simple(:day) do
|
69
|
+
DateFactories::MonthDay.new(month, day)
|
70
|
+
end
|
71
|
+
|
72
|
+
rule month: simple(:month), day: simple(:day), year: simple(:year) do
|
73
|
+
DateFactories::Unambiguous.new(year, month, day)
|
74
|
+
end
|
75
|
+
|
76
|
+
rule am: simple(:am) do
|
77
|
+
Meridies::Am
|
78
|
+
end
|
79
|
+
|
80
|
+
rule pm: simple(:am) do
|
81
|
+
Meridies::Pm
|
82
|
+
end
|
83
|
+
|
84
|
+
rule time_of_day_components: subtree(:time_of_day_components) do
|
85
|
+
TimeOfDay.new(time_of_day_components)
|
86
|
+
end
|
87
|
+
|
88
|
+
rule utc: simple(:utc) do
|
89
|
+
TimeZones::UTC
|
90
|
+
end
|
91
|
+
|
92
|
+
rule time_components: subtree(:time_components) do
|
93
|
+
TimeFactory.new(time_components)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "active_support"
|
3
|
+
require "active_support/core_ext"
|
4
|
+
require "active_support/testing/time_helpers"
|
5
|
+
require "halftime/parser"
|
6
|
+
|
7
|
+
describe Halftime::Parser do
|
8
|
+
include ActiveSupport::Testing::TimeHelpers
|
9
|
+
|
10
|
+
describe "#time" do
|
11
|
+
context "at 2014-11-14 8:00:00" do
|
12
|
+
def now
|
13
|
+
Time.new(2014, 11, 14, 8, 0, 0, 0)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when unparseable" do
|
17
|
+
it "returns nil" do
|
18
|
+
expect(time("this is not a time")).to eq nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "hours" do
|
23
|
+
specify { expect(time("07")).to eq Time.new(2014, 11, 14, 19, 0, 0, 0) }
|
24
|
+
specify { expect(time("7")).to eq Time.new(2014, 11, 14, 19, 0, 0, 0) }
|
25
|
+
specify { expect(time("7am")).to eq Time.new(2014, 11, 15, 7, 0, 0, 0) }
|
26
|
+
specify { expect(time("7pm")).to eq Time.new(2014, 11, 14, 19, 0, 0, 0) }
|
27
|
+
specify { expect(time("8")).to eq Time.new(2014, 11, 14, 20, 0, 0, 0) }
|
28
|
+
specify { expect(time("8am")).to eq Time.new(2014, 11, 15, 8, 0, 0, 0) }
|
29
|
+
specify { expect(time("8pm")).to eq Time.new(2014, 11, 14, 20, 0, 0, 0) }
|
30
|
+
specify { expect(time("9")).to eq Time.new(2014, 11, 14, 9, 0, 0, 0) }
|
31
|
+
specify { expect(time("9am")).to eq Time.new(2014, 11, 14, 9, 0, 0, 0) }
|
32
|
+
specify { expect(time("9pm")).to eq Time.new(2014, 11, 14, 21, 0, 0, 0) }
|
33
|
+
specify { expect(time("22")).to eq Time.new(2014, 11, 14, 22, 0, 0, 0) }
|
34
|
+
specify { expect(time("22am")).to eq Time.new(2014, 11, 14, 22, 0, 0, 0) }
|
35
|
+
specify { expect(time("22pm")).to eq Time.new(2014, 11, 14, 22, 0, 0, 0) }
|
36
|
+
specify { expect(time("12")).to eq Time.new(2014, 11, 14, 12, 0, 0, 0) }
|
37
|
+
specify { expect(time("12am")).to eq Time.new(2014, 11, 15, 0, 0, 0, 0) }
|
38
|
+
specify { expect(time("12pm")).to eq Time.new(2014, 11, 14, 12, 0, 0, 0) }
|
39
|
+
specify { expect(time("at 3")).to eq Time.new(2014, 11, 14, 15, 0, 0, 0) }
|
40
|
+
specify { expect(time("at 2pm")).to eq Time.new(2014, 11, 14, 14, 0, 0, 0) }
|
41
|
+
specify { expect(time("at 22")).to eq Time.new(2014, 11, 14, 22, 0, 0, 0) }
|
42
|
+
specify { expect(time("at 04am")).to eq Time.new(2014, 11, 15, 4, 0, 0, 0) }
|
43
|
+
specify { expect(time("at 12")).to eq Time.new(2014, 11, 14, 12, 0, 0, 0) }
|
44
|
+
specify { expect(time("at 0")).to eq Time.new(2014, 11, 15, 0, 0, 0, 0) }
|
45
|
+
specify { expect(time("@ 4")).to eq Time.new(2014, 11, 14, 16, 0, 0, 0) }
|
46
|
+
specify { expect(time("@ 5am")).to eq Time.new(2014, 11, 15, 5, 0, 0, 0) }
|
47
|
+
specify { expect(time("@ 00")).to eq Time.new(2014, 11, 15, 0, 0, 0, 0) }
|
48
|
+
specify { expect(time("@ 23")).to eq Time.new(2014, 11, 14, 23, 0, 0, 0) }
|
49
|
+
specify { expect(time("@ 2pm")).to eq Time.new(2014, 11, 14, 14, 0, 0, 0) }
|
50
|
+
specify { expect(time("@1 am")).to eq Time.new(2014, 11, 15, 1, 0, 0, 0) }
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "hours and minutes" do
|
54
|
+
specify { expect(time("7:01")).to eq Time.new(2014, 11, 14, 19, 1, 0, 0) }
|
55
|
+
specify { expect(time("7:01am")).to eq Time.new(2014, 11, 15, 7, 1, 0, 0) }
|
56
|
+
specify { expect(time("7:01pm")).to eq Time.new(2014, 11, 14, 19, 1, 0, 0) }
|
57
|
+
specify { expect(time("8:01")).to eq Time.new(2014, 11, 14, 8, 1, 0, 0) }
|
58
|
+
specify { expect(time("8:01am")).to eq Time.new(2014, 11, 14, 8, 1, 0, 0) }
|
59
|
+
specify { expect(time("8:01pm")).to eq Time.new(2014, 11, 14, 20, 1, 0, 0) }
|
60
|
+
specify { expect(time("9:01")).to eq Time.new(2014, 11, 14, 9, 1, 0, 0) }
|
61
|
+
specify { expect(time("9:01am")).to eq Time.new(2014, 11, 14, 9, 1, 0, 0) }
|
62
|
+
specify { expect(time("9:01pm")).to eq Time.new(2014, 11, 14, 21, 1, 0, 0) }
|
63
|
+
specify { expect(time("22:01")).to eq Time.new(2014, 11, 14, 22, 1, 0, 0) }
|
64
|
+
specify { expect(time("22:01am")).to eq Time.new(2014, 11, 14, 22, 1, 0, 0) }
|
65
|
+
specify { expect(time("22:01pm")).to eq Time.new(2014, 11, 14, 22, 1, 0, 0) }
|
66
|
+
specify { expect(time("12:01")).to eq Time.new(2014, 11, 14, 12, 1, 0, 0) }
|
67
|
+
specify { expect(time("12:01am")).to eq Time.new(2014, 11, 15, 0, 1, 0, 0) }
|
68
|
+
specify { expect(time("12:01pm")).to eq Time.new(2014, 11, 14, 12, 1, 0, 0) }
|
69
|
+
specify { expect(time("00:00")).to eq Time.new(2014, 11, 15, 0, 0, 0, 0) }
|
70
|
+
specify { expect(time("04:01pm")).to eq Time.new(2014, 11, 14, 16, 1, 0, 0) }
|
71
|
+
specify { expect(time("15.32pm")).to eq Time.new(2014, 11, 14, 15, 32, 0, 0) }
|
72
|
+
specify { expect(time("4.01")).to eq Time.new(2014, 11, 14, 16, 1, 0, 0) }
|
73
|
+
specify { expect(time("05.59")).to eq Time.new(2014, 11, 14, 17, 59, 0, 0) }
|
74
|
+
specify { expect(time("323")).to eq Time.new(2014, 11, 14, 15, 23, 0, 0) }
|
75
|
+
specify { expect(time("2312")).to eq Time.new(2014, 11, 14, 23, 12, 0, 0) }
|
76
|
+
specify { expect(time("0902")).to eq Time.new(2014, 11, 14, 9, 2, 0, 0) }
|
77
|
+
specify { expect(time("1123am")).to eq Time.new(2014, 11, 14, 11, 23, 0, 0) }
|
78
|
+
specify { expect(time("0902")).to eq Time.new(2014, 11, 14, 9, 2, 0, 0) }
|
79
|
+
specify { expect(time("2.06")).to eq Time.new(2014, 11, 14, 14, 6, 0, 0) }
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "month and day" do
|
83
|
+
specify { expect(time("11/15")).to eq Time.new(2014, 11, 15, 12, 0, 0, 0) }
|
84
|
+
specify { expect(time("15/11")).to eq Time.new(2014, 11, 15, 12, 0, 0, 0) }
|
85
|
+
specify { expect(time("1/3")).to eq Time.new(2015, 1, 3, 12, 0, 0, 0) }
|
86
|
+
specify { expect(time("7/8")).to eq Time.new(2015, 7, 8, 12, 0, 0, 0) }
|
87
|
+
specify { expect(time("01/05")).to eq Time.new(2015, 1, 5, 12, 0, 0, 0) }
|
88
|
+
specify { expect(time("on 11/15")).to eq Time.new(2014, 11, 15, 12, 0, 0, 0) }
|
89
|
+
specify { expect(time("Nov 15")).to eq Time.new(2014, 11, 15, 12, 0, 0, 0) }
|
90
|
+
specify { expect(time("December 3")).to eq Time.new(2014, 12, 3, 12, 0, 0, 0) }
|
91
|
+
specify { expect(time("oct 30")).to eq Time.new(2015, 10, 30, 12, 0, 0, 0) }
|
92
|
+
specify { expect(time("july 02")).to eq Time.new(2015, 7, 2, 12, 0, 0, 0) }
|
93
|
+
specify { expect(time("3 Jun")).to eq Time.new(2015, 6, 3, 12, 0, 0, 0) }
|
94
|
+
specify { expect(time("12 January")).to eq Time.new(2015, 1, 12, 12, 0, 0, 0) }
|
95
|
+
specify { expect(time("28 feb")).to eq Time.new(2015, 2, 28, 12, 0, 0, 0) }
|
96
|
+
specify { expect(time("04 september")).to eq Time.new(2015, 9, 4, 12, 0, 0, 0) }
|
97
|
+
specify { expect(time("2june")).to eq Time.new(2015, 6, 2, 12, 0, 0, 0) }
|
98
|
+
specify { expect(time("feb09")).to eq Time.new(2015, 2, 9, 12, 0, 0, 0) }
|
99
|
+
specify { expect(time("tomorrow")).to eq Time.new(2014, 11, 15, 12, 0, 0, 0) }
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "year, month and day" do
|
103
|
+
specify { expect(time("11/15/2016")).to eq Time.new(2016, 11, 15, 12, 0, 0, 0) }
|
104
|
+
specify { expect(time("2/5/1900")).to eq Time.new(1900, 2, 5, 12, 0, 0, 0) }
|
105
|
+
specify { expect(time("31/7/1900")).to eq Time.new(1900, 7, 31, 12, 0, 0, 0) }
|
106
|
+
specify { expect(time("2015/05/30")).to eq Time.new(2015, 5, 30, 12, 0, 0, 0) }
|
107
|
+
specify { expect(time("2015/12/05")).to eq Time.new(2015, 12, 5, 12, 0, 0, 0) }
|
108
|
+
specify { expect(time("2015/31/05")).to eq Time.new(2015, 5, 31, 12, 0, 0, 0) }
|
109
|
+
specify { expect(time("1723-04-07")).to eq Time.new(1723, 4, 7, 12, 0, 0, 0) }
|
110
|
+
specify { expect(time("2014-30-09")).to eq Time.new(2014, 9, 30, 12, 0, 0, 0) }
|
111
|
+
specify { expect(time("22-08-2013")).to eq Time.new(2013, 8, 22, 12, 0, 0, 0) }
|
112
|
+
specify { expect(time("07-08-2013")).to eq Time.new(2013, 7, 8, 12, 0, 0, 0) }
|
113
|
+
specify { expect(time("Nov 15 1923")).to eq Time.new(1923, 11, 15, 12, 0, 0, 0) }
|
114
|
+
specify { expect(time("December 3 2013")).to eq Time.new(2013, 12, 3, 12, 0, 0, 0) }
|
115
|
+
specify { expect(time("oct 30 1999")).to eq Time.new(1999, 10, 30, 12, 0, 0, 0) }
|
116
|
+
specify { expect(time("july 02 2020")).to eq Time.new(2020, 7, 2, 12, 0, 0, 0) }
|
117
|
+
specify { expect(time("3 Jun 2004")).to eq Time.new(2004, 6, 3, 12, 0, 0, 0) }
|
118
|
+
specify { expect(time("12 January 1787")).to eq Time.new(1787, 1, 12, 12, 0, 0, 0) }
|
119
|
+
specify { expect(time("28 feb 1245")).to eq Time.new(1245, 2, 28, 12, 0, 0, 0) }
|
120
|
+
specify { expect(time("04 september 1955")).to eq Time.new(1955, 9, 4, 12, 0, 0, 0) }
|
121
|
+
specify { expect(time("2009 Mar 3")).to eq Time.new(2009, 3, 3, 12, 0, 0, 0) }
|
122
|
+
specify { expect(time("1991 June 30")).to eq Time.new(1991, 6, 30, 12, 0, 0, 0) }
|
123
|
+
specify { expect(time("1756 apr 23")).to eq Time.new(1756, 4, 23, 12, 0, 0, 0) }
|
124
|
+
specify { expect(time("1976 august 13")).to eq Time.new(1976, 8, 13, 12, 0, 0, 0) }
|
125
|
+
specify { expect(time("1955 18 Sep")).to eq Time.new(1955, 9, 18, 12, 0, 0, 0) }
|
126
|
+
specify { expect(time("1233 12 March")).to eq Time.new(1233, 3, 12, 12, 0, 0, 0) }
|
127
|
+
specify { expect(time("1959 21 nov")).to eq Time.new(1959, 11, 21, 12, 0, 0, 0) }
|
128
|
+
specify { expect(time("1877 08 october")).to eq Time.new(1877, 10, 8, 12, 0, 0, 0) }
|
129
|
+
specify { expect(time("on 1923 23july")).to eq Time.new(1923, 7, 23, 12, 0, 0, 0) }
|
130
|
+
specify { expect(time("on 2134 mar14")).to eq Time.new(2134, 3, 14, 12, 0, 0, 0) }
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "month, day and hours" do
|
134
|
+
specify { expect(time("7/8 9pm")).to eq Time.new(2015, 7, 8, 21, 0, 0, 0) }
|
135
|
+
specify { expect(time("10/8 1")).to eq Time.new(2015, 10, 8, 1, 0, 0, 0) }
|
136
|
+
specify { expect(time("10/5 @ 3pm")).to eq Time.new(2015, 10, 5, 15, 0, 0, 0) }
|
137
|
+
specify { expect(time("on 11/15 at 3")).to eq Time.new(2014, 11, 15, 3, 0, 0, 0) }
|
138
|
+
specify { expect(time("@ 3pm 10/5")).to eq Time.new(2015, 10, 5, 15, 0, 0, 0) }
|
139
|
+
specify { expect(time("Jul 03 3")).to eq Time.new(2015, 7, 3, 3, 0, 0, 0) }
|
140
|
+
specify { expect(time("February 14 4pm")).to eq Time.new(2015, 2, 14, 16, 0, 0, 0) }
|
141
|
+
specify { expect(time("dec 23 @ 22")).to eq Time.new(2014, 12, 23, 22, 0, 0, 0) }
|
142
|
+
specify { expect(time("august 02 at 1")).to eq Time.new(2015, 8, 2, 1, 0, 0, 0) }
|
143
|
+
specify { expect(time("on 16 Mar 3")).to eq Time.new(2015, 3, 16, 3, 0, 0, 0) }
|
144
|
+
specify { expect(time("5 March @ 1am")).to eq Time.new(2015, 3, 5, 1, 0, 0, 0) }
|
145
|
+
specify { expect(time("28 dec 14")).to eq Time.new(2014, 12, 28, 14, 0, 0, 0) }
|
146
|
+
specify { expect(time("04 july at 5am")).to eq Time.new(2015, 7, 4, 5, 0, 0, 0) }
|
147
|
+
specify { expect(time("12pm Dec 04")).to eq Time.new(2014, 12, 4, 12, 0, 0, 0) }
|
148
|
+
specify { expect(time("1am August 12")).to eq Time.new(2015, 8, 12, 1, 0, 0, 0) }
|
149
|
+
specify { expect(time("03 on apr 19")).to eq Time.new(2015, 4, 19, 3, 0, 0, 0) }
|
150
|
+
specify { expect(time("@ 20 january 22")).to eq Time.new(2015, 1, 22, 20, 0, 0, 0) }
|
151
|
+
specify { expect(time("3 12 Feb")).to eq Time.new(2015, 2, 12, 3, 0, 0, 0) }
|
152
|
+
specify { expect(time("8pm on 16 October")).to eq Time.new(2015, 10, 16, 20, 0, 0, 0) }
|
153
|
+
specify { expect(time("13 02 mar")).to eq Time.new(2015, 3, 2, 13, 0, 0, 0) }
|
154
|
+
specify { expect(time("@ 11 on 04 november")).to eq Time.new(2015, 11, 4, 11, 0, 0, 0) }
|
155
|
+
specify { expect(time("tomorrow @ 1pm")).to eq Time.new(2014, 11, 15, 13, 0, 0, 0) }
|
156
|
+
specify { expect(time("tomorrow 20")).to eq Time.new(2014, 11, 15, 20, 0, 0, 0) }
|
157
|
+
specify { expect(time("tomorrow at 01")).to eq Time.new(2014, 11, 15, 1, 0, 0, 0) }
|
158
|
+
specify { expect(time("4am tomorrow")).to eq Time.new(2014, 11, 15, 4, 0, 0, 0) }
|
159
|
+
specify { expect(time("17 tomorrow")).to eq Time.new(2014, 11, 15, 17, 0, 0, 0) }
|
160
|
+
specify { expect(time("@ 3 tomorrow")).to eq Time.new(2014, 11, 15, 3, 0, 0, 0) }
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "month, day, hours and minutes" do
|
164
|
+
specify { expect(time("11/14 04:23")).to eq Time.new(2015, 11, 14, 4, 23, 0, 0) }
|
165
|
+
specify { expect(time("11/15 05:44")).to eq Time.new(2014, 11, 15, 5, 44, 0, 0) }
|
166
|
+
specify { expect(time("15/11 1533")).to eq Time.new(2014, 11, 15, 15, 33, 0, 0) }
|
167
|
+
specify { expect(time("1/3 13.00")).to eq Time.new(2015, 1, 3, 13, 0, 0, 0) }
|
168
|
+
specify { expect(time("01/05 0213")).to eq Time.new(2015, 1, 5, 2, 13, 0, 0) }
|
169
|
+
specify { expect(time("Jul 03 3")).to eq Time.new(2015, 7, 3, 3, 0, 0, 0) }
|
170
|
+
specify { expect(time("February 14 423pm")).to eq Time.new(2015, 2, 14, 16, 23, 0, 0) }
|
171
|
+
specify { expect(time("dec 23 @ 22:11")).to eq Time.new(2014, 12, 23, 22, 11, 0, 0) }
|
172
|
+
specify { expect(time("august 02 at 112")).to eq Time.new(2015, 8, 2, 11, 2, 0, 0) }
|
173
|
+
specify { expect(time("on 16 Mar 303")).to eq Time.new(2015, 3, 16, 3, 3, 0, 0) }
|
174
|
+
specify { expect(time("5 March @ 1.42")).to eq Time.new(2015, 3, 5, 1, 42, 0, 0) }
|
175
|
+
specify { expect(time("28 dec 14:59")).to eq Time.new(2014, 12, 28, 14, 59, 0, 0) }
|
176
|
+
specify { expect(time("04 july at 5:10am")).to eq Time.new(2015, 7, 4, 5, 10, 0, 0) }
|
177
|
+
specify { expect(time("1238pm Dec 04")).to eq Time.new(2014, 12, 4, 12, 38, 0, 0) }
|
178
|
+
specify { expect(time("1:54am August 12")).to eq Time.new(2015, 8, 12, 1, 54, 0, 0) }
|
179
|
+
specify { expect(time("0300 on apr 19")).to eq Time.new(2015, 4, 19, 3, 0, 0, 0) }
|
180
|
+
specify { expect(time("@ 20.10 january 22")).to eq Time.new(2015, 1, 22, 20, 10, 0, 0) }
|
181
|
+
specify { expect(time("3.56 12 Feb")).to eq Time.new(2015, 2, 12, 3, 56, 0, 0) }
|
182
|
+
specify { expect(time("841pm on 16 October")).to eq Time.new(2015, 10, 16, 20, 41, 0, 0) }
|
183
|
+
specify { expect(time("13.11 02 mar")).to eq Time.new(2015, 3, 2, 13, 11, 0, 0) }
|
184
|
+
specify { expect(time("@ 1101 on 04 november")).to eq Time.new(2015, 11, 4, 11, 1, 0, 0) }
|
185
|
+
specify { expect(time("tomorrow 14:23")).to eq Time.new(2014, 11, 15, 14, 23, 0, 0) }
|
186
|
+
specify { expect(time("tomorrow at 0300")).to eq Time.new(2014, 11, 15, 3, 0, 0, 0) }
|
187
|
+
specify { expect(time("tomorrow 345pm")).to eq Time.new(2014, 11, 15, 15, 45, 0, 0) }
|
188
|
+
specify { expect(time("@ 0353 tomorrow")).to eq Time.new(2014, 11, 15, 3, 53, 0, 0) }
|
189
|
+
specify { expect(time("at19.33 tomorrow")).to eq Time.new(2014, 11, 15, 19, 33, 0, 0) }
|
190
|
+
specify { expect(time("1130 tomorrow")).to eq Time.new(2014, 11, 15, 11, 30, 0, 0) }
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "year, month, day and hours" do
|
194
|
+
specify { expect(time("22-08-2013 11")).to eq Time.new(2013, 8, 22, 11, 0, 0, 0) }
|
195
|
+
specify { expect(time("07-08-2013 12")).to eq Time.new(2013, 7, 8, 12, 0, 0, 0) }
|
196
|
+
specify { expect(time("2/5/1900 2am")).to eq Time.new(1900, 2, 5, 2, 0, 0, 0) }
|
197
|
+
specify { expect(time("31/7/1900 12am")).to eq Time.new(1900, 7, 31, 0, 0, 0, 0) }
|
198
|
+
specify { expect(time("2015-12-22 at 10")).to eq Time.new(2015, 12, 22, 10, 0, 0, 0) }
|
199
|
+
specify { expect(time("at 10 2015-12-22")).to eq Time.new(2015, 12, 22, 10, 0, 0, 0) }
|
200
|
+
specify { expect(time("Nov 15 1923 13")).to eq Time.new(1923, 11, 15, 13, 0, 0, 0) }
|
201
|
+
specify { expect(time("5pm December 3 2013")).to eq Time.new(2013, 12, 3, 17, 0, 0, 0) }
|
202
|
+
specify { expect(time("oct 30 1999 @ 1")).to eq Time.new(1999, 10, 30, 1, 0, 0, 0) }
|
203
|
+
specify { expect(time("20 on july 02 2020")).to eq Time.new(2020, 7, 2, 20, 0, 0, 0) }
|
204
|
+
specify { expect(time("3 Jun 2004 8am")).to eq Time.new(2004, 6, 3, 8, 0, 0, 0) }
|
205
|
+
specify { expect(time("23pm 12 January 1787")).to eq Time.new(1787, 1, 12, 23, 0, 0, 0) }
|
206
|
+
specify { expect(time("28 feb 1245 at 11")).to eq Time.new(1245, 2, 28, 11, 0, 0, 0) }
|
207
|
+
specify { expect(time("@ 7am 04 september 1955")).to eq Time.new(1955, 9, 4, 7, 0, 0, 0) }
|
208
|
+
specify { expect(time("on 2009 Mar 3 @ 4")).to eq Time.new(2009, 3, 3, 4, 0, 0, 0) }
|
209
|
+
specify { expect(time("1991 June 30 at 7")).to eq Time.new(1991, 6, 30, 7, 0, 0, 0) }
|
210
|
+
specify { expect(time("10 on 1756 apr 23")).to eq Time.new(1756, 4, 23, 10, 0, 0, 0) }
|
211
|
+
specify { expect(time("1976 august 13 at 6pm")).to eq Time.new(1976, 8, 13, 18, 0, 0, 0) }
|
212
|
+
specify { expect(time("2am 1955 18 Sep")).to eq Time.new(1955, 9, 18, 2, 0, 0, 0) }
|
213
|
+
specify { expect(time("1233 12 March 4")).to eq Time.new(1233, 3, 12, 4, 0, 0, 0) }
|
214
|
+
specify { expect(time("@ 04 1959 21 nov")).to eq Time.new(1959, 11, 21, 4, 0, 0, 0) }
|
215
|
+
specify { expect(time("1877 08 october 03pm")).to eq Time.new(1877, 10, 8, 15, 0, 0, 0) }
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "year, month, day, hour and minutes" do
|
219
|
+
specify { expect(time("11/15/2016 333pm")).to eq Time.new(2016, 11, 15, 15, 33, 0, 0) }
|
220
|
+
specify { expect(time("2015/05/30 1300")).to eq Time.new(2015, 5, 30, 13, 0, 0, 0) }
|
221
|
+
specify { expect(time("2015/12/05 730")).to eq Time.new(2015, 12, 5, 7, 30, 0, 0) }
|
222
|
+
specify { expect(time("2015/31/05 0000")).to eq Time.new(2015, 5, 31, 0, 0, 0, 0) }
|
223
|
+
specify { expect(time("1723-04-07 22:59")).to eq Time.new(1723, 4, 7, 22, 59, 0, 0) }
|
224
|
+
specify { expect(time("2014-30-09 11.2")).to eq Time.new(2014, 9, 30, 11, 2, 0, 0) }
|
225
|
+
specify { expect(time("Nov 15 1923 13:10")).to eq Time.new(1923, 11, 15, 13, 10, 0, 0) }
|
226
|
+
specify { expect(time("523pm December 3 2013")).to eq Time.new(2013, 12, 3, 17, 23, 0, 0) }
|
227
|
+
specify { expect(time("oct 30 1999 @ 0100")).to eq Time.new(1999, 10, 30, 1, 0, 0, 0) }
|
228
|
+
specify { expect(time("20:54 on july 02 2020")).to eq Time.new(2020, 7, 2, 20, 54, 0, 0) }
|
229
|
+
specify { expect(time("3 Jun 2004 8.15am")).to eq Time.new(2004, 6, 3, 8, 15, 0, 0) }
|
230
|
+
specify { expect(time("23.1pm 12 January 1787")).to eq Time.new(1787, 1, 12, 23, 1, 0, 0) }
|
231
|
+
specify { expect(time("28 feb 1245 at 1112")).to eq Time.new(1245, 2, 28, 11, 12, 0, 0) }
|
232
|
+
specify { expect(time("@ 7.45am 04 september 1955")).to eq Time.new(1955, 9, 4, 7, 45, 0, 0) }
|
233
|
+
specify { expect(time("on 2009 Mar 3 @ 4:59")).to eq Time.new(2009, 3, 3, 4, 59, 0, 0) }
|
234
|
+
specify { expect(time("1991 June 30 at 7.3")).to eq Time.new(1991, 6, 30, 7, 3, 0, 0) }
|
235
|
+
specify { expect(time("10:34 on 1756 apr 23")).to eq Time.new(1756, 4, 23, 10, 34, 0, 0) }
|
236
|
+
specify { expect(time("1976 august 13 at 620pm")).to eq Time.new(1976, 8, 13, 18, 20, 0, 0) }
|
237
|
+
specify { expect(time("0203am 1955 18 Sep")).to eq Time.new(1955, 9, 18, 2, 3, 0, 0) }
|
238
|
+
specify { expect(time("1233 12 March 444")).to eq Time.new(1233, 3, 12, 4, 44, 0, 0) }
|
239
|
+
specify { expect(time("@ 04.37 1959 21 nov")).to eq Time.new(1959, 11, 21, 4, 37, 0, 0) }
|
240
|
+
specify { expect(time("1877 08 october 03:18pm")).to eq Time.new(1877, 10, 8, 15, 18, 0, 0) }
|
241
|
+
specify { expect(time("2014-11-20T18:46:41Z")).to eq Time.new(2014, 11, 20, 18, 46, 41, 0) }
|
242
|
+
specify { expect(time("2014-11-14T07:00:00Z")).to eq Time.new(2014, 11, 14, 7, 0, 0, 0) }
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context "at 2014-12-31 13:00:00" do
|
247
|
+
def now
|
248
|
+
Time.new(2014, 12, 31, 13, 0, 0, 0)
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "month and day" do
|
252
|
+
specify { expect(time("tomorrow")).to eq Time.new(2015, 1, 1, 12, 0, 0, 0) }
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def time(string)
|
257
|
+
described_class.new(string, now: now).time
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
data/spec/spec_helper.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: halftime
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Calle Erlandsson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: parslet
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- calle@calleerlandsson.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".ruby-version"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- halftime.gemspec
|
97
|
+
- lib/halftime.rb
|
98
|
+
- lib/halftime/date_factories.rb
|
99
|
+
- lib/halftime/internal_parser.rb
|
100
|
+
- lib/halftime/meridies.rb
|
101
|
+
- lib/halftime/parser.rb
|
102
|
+
- lib/halftime/time_factory.rb
|
103
|
+
- lib/halftime/time_of_day.rb
|
104
|
+
- lib/halftime/time_zones.rb
|
105
|
+
- lib/halftime/transform.rb
|
106
|
+
- lib/halftime/version.rb
|
107
|
+
- spec/lib/halftime/parser_spec.rb
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
homepage: https://github.com/calleerlandsson/halftime
|
110
|
+
licenses:
|
111
|
+
- MIT
|
112
|
+
metadata: {}
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 2.2.2
|
130
|
+
signing_key:
|
131
|
+
specification_version: 4
|
132
|
+
summary: Natural language time parser.
|
133
|
+
test_files:
|
134
|
+
- spec/lib/halftime/parser_spec.rb
|
135
|
+
- spec/spec_helper.rb
|