night-time 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +4 -4
- data/lib/night-time/jst.rb +85 -43
- data/lib/night-time/version.rb +1 -1
- data/spec/jst_spec.rb +74 -0
- metadata +4 -4
data/README
CHANGED
@@ -27,16 +27,16 @@ SYNOPSIS
|
|
27
27
|
DESCRIPTION
|
28
28
|
* NightTime.mktime(*args)
|
29
29
|
* NightTime.parse(text)
|
30
|
-
* NightTime::Jst.parse(text)
|
30
|
+
* NightTime::Jst.parse(text, now = nil) # => a Time
|
31
|
+
* NightTime::Jst.parsedate(text) # => an Array
|
31
32
|
|
32
33
|
JST
|
33
34
|
NightTime::Jst can extract time from Japanese texts.
|
34
35
|
|
35
|
-
jst = NightTime::Jst.
|
36
|
-
jst.parse
|
36
|
+
jst = NightTime::Jst.parsedate("テレビ7月8日(土)24:30~25:00")
|
37
37
|
=> [nil,7,8,24,30,nil]
|
38
38
|
|
39
|
-
jst.
|
39
|
+
jst = NightTime::Jst.parse("テレビ7月8日(土)24:30~25:00")
|
40
40
|
=> Mon Jul 09 00:30:00 +0900 2012
|
41
41
|
|
42
42
|
CHANGES
|
data/lib/night-time/jst.rb
CHANGED
@@ -3,32 +3,50 @@ require 'nkf'
|
|
3
3
|
|
4
4
|
module NightTime
|
5
5
|
class Jst
|
6
|
+
######################################################################
|
7
|
+
### Class Methods
|
8
|
+
|
6
9
|
def self.parse(text, now = nil)
|
7
10
|
new(text).time(now)
|
8
11
|
end
|
9
12
|
|
13
|
+
def self.parsedate(text)
|
14
|
+
new(text).parse
|
15
|
+
end
|
16
|
+
|
17
|
+
######################################################################
|
18
|
+
### Builder
|
19
|
+
|
10
20
|
class Build < RuntimeError
|
11
21
|
attr_accessor :year,:month,:day,:hour,:min,:sec
|
12
22
|
def date?; month and day; end
|
13
23
|
def time?; hour and min; end
|
14
24
|
def full?; date? and time?; end
|
15
|
-
def
|
25
|
+
def to_a; [year, month, day, hour, min, sec]; end
|
16
26
|
def to_time; NightTime.mktime(year, month, day, hour||0, min||0, sec||0); end
|
17
27
|
def inspect; "<Build: %s>" % [year,month,day,hour,min,sec].inspect; end
|
18
28
|
end
|
19
29
|
|
30
|
+
class Changed < RuntimeError; end
|
31
|
+
class Completed < RuntimeError; end
|
32
|
+
|
33
|
+
######################################################################
|
34
|
+
### Jst class
|
35
|
+
|
20
36
|
def initialize(text)
|
21
37
|
@text = NKF.nkf('-Wwxm0Z0', text).gsub(/\s+/m,' ').strip
|
22
38
|
@build = Build.new
|
39
|
+
@trace = []
|
23
40
|
end
|
24
41
|
|
25
|
-
def
|
42
|
+
def trace
|
26
43
|
build!
|
27
|
-
@
|
44
|
+
return @trace
|
28
45
|
end
|
29
46
|
|
30
47
|
def parse
|
31
|
-
|
48
|
+
build!
|
49
|
+
@build.to_a
|
32
50
|
end
|
33
51
|
|
34
52
|
def time(now = nil)
|
@@ -64,81 +82,105 @@ module NightTime
|
|
64
82
|
|
65
83
|
private
|
66
84
|
def build!
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
}
|
85
|
+
try :parse_nengappi
|
86
|
+
try :parse_gappi
|
87
|
+
try :parse_iso8601
|
88
|
+
try :parse_jifunbyou
|
89
|
+
try :parse_jifun
|
90
|
+
try :parse_month_slash_day
|
91
|
+
try :parse_hour_colon_min
|
92
|
+
rescue Completed
|
76
93
|
end
|
77
94
|
|
78
95
|
def parse_nengappi
|
79
96
|
@text.scan(/(\d{4})\s*年\s*(\d{1,2})\s*月\s*(\d{1,2})\s*日/) {
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
97
|
+
return observe {
|
98
|
+
@build.year ||= $1.to_i
|
99
|
+
@build.month ||= $2.to_i
|
100
|
+
@build.day ||= $3.to_i
|
101
|
+
}
|
84
102
|
}
|
85
103
|
end
|
86
104
|
|
87
105
|
def parse_gappi
|
88
106
|
@text.scan(/(\d{1,2})\s*月\s*(\d{1,2})\s*日/) {
|
89
|
-
|
90
|
-
|
91
|
-
|
107
|
+
return observe {
|
108
|
+
@build.month ||= $1.to_i
|
109
|
+
@build.day ||= $2.to_i
|
110
|
+
}
|
92
111
|
}
|
93
112
|
end
|
94
113
|
|
95
114
|
def parse_iso8601
|
96
|
-
@text.scan(/(\d{4})[-\/](\d{1,2})[-\/](\d{1,2})/) {
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
115
|
+
@text.scan(/(?:^|[^\d\/])(\d{4})[-\/](\d{1,2})[-\/](\d{1,2})($|[^\d\/])/) {
|
116
|
+
(1..12).include?($2.to_i) or return false
|
117
|
+
(1..31).include?($3.to_i) or return false
|
118
|
+
return observe {
|
119
|
+
@build.year ||= $1.to_i
|
120
|
+
@build.month ||= $2.to_i
|
121
|
+
@build.day ||= $3.to_i
|
122
|
+
}
|
101
123
|
}
|
102
124
|
end
|
103
125
|
|
104
126
|
def parse_month_slash_day
|
105
|
-
@text.scan(/(\d{1,2})\/(\d{1,2})/) {
|
106
|
-
|
107
|
-
|
108
|
-
return
|
127
|
+
@text.scan(/(?:^|[^\d\/])(\d{1,2})\/(\d{1,2})($|[^\d\/])/) {
|
128
|
+
(1..12).include?($1.to_i) or return false
|
129
|
+
(1..31).include?($2.to_i) or return false
|
130
|
+
return observe {
|
131
|
+
@build.month ||= $1.to_i
|
132
|
+
@build.day ||= $2.to_i
|
133
|
+
}
|
109
134
|
}
|
110
135
|
end
|
111
136
|
|
112
137
|
def parse_jifunbyou
|
113
138
|
@text.scan(/(夜)?\s*(\d{1,2})\s*時\s*(\d{1,2})\s*分\s*(\d{1,2})秒/) {
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
139
|
+
return observe {
|
140
|
+
hour_margin = ($1 and $2.to_i < 5) ? 24 : 0
|
141
|
+
@build.hour ||= hour_margin + $2.to_i
|
142
|
+
@build.min ||= $3.to_i
|
143
|
+
@build.sec ||= $4.to_i
|
144
|
+
}
|
119
145
|
}
|
120
146
|
end
|
121
147
|
|
122
148
|
def parse_jifun
|
123
149
|
@text.scan(/(夜)?\s*(\d{1,2})\s*時\s*(\d{1,2})\s*分/) {
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
150
|
+
return observe {
|
151
|
+
hour_margin = ($1 and $2.to_i < 5) ? 24 : 0
|
152
|
+
@build.hour ||= hour_margin + $2.to_i
|
153
|
+
@build.min ||= $3.to_i
|
154
|
+
}
|
128
155
|
}
|
129
156
|
end
|
130
157
|
|
131
158
|
def parse_hour_colon_min
|
132
159
|
@text.scan(/(夜)?\s*(\d{1,2}):(\d{1,2})/) {
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
160
|
+
return observe {
|
161
|
+
hour_margin = ($1 and $2.to_i < 5) ? 24 : 0
|
162
|
+
@build.hour ||= hour_margin + $2.to_i
|
163
|
+
@build.min ||= $3.to_i
|
164
|
+
}
|
137
165
|
}
|
138
166
|
end
|
139
167
|
|
168
|
+
def try(method)
|
169
|
+
__send__(method)
|
170
|
+
rescue Changed
|
171
|
+
@trace << method
|
172
|
+
validate!
|
173
|
+
end
|
174
|
+
|
175
|
+
def observe(&block)
|
176
|
+
a1 = @build.to_a
|
177
|
+
block.call
|
178
|
+
a2 = @build.to_a
|
179
|
+
raise Changed if a1 != a2
|
180
|
+
end
|
181
|
+
|
140
182
|
def validate!
|
141
|
-
|
183
|
+
raise Completed if @build.full?
|
142
184
|
end
|
143
185
|
end
|
144
186
|
end
|
data/lib/night-time/version.rb
CHANGED
data/spec/jst_spec.rb
CHANGED
@@ -8,6 +8,12 @@ describe NightTime::Jst do
|
|
8
8
|
NightTime::Jst.parse("2012/7/3 11:30").should == Time.mktime(2012,7,3,11,30)
|
9
9
|
end
|
10
10
|
end
|
11
|
+
|
12
|
+
describe ".parsedate" do
|
13
|
+
it "should return an Array" do
|
14
|
+
NightTime::Jst.parsedate("2012/7/3 11:30").should == [2012, 7, 3, 11, 30, nil]
|
15
|
+
end
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
describe NightTime::Jst do
|
@@ -28,6 +34,12 @@ describe NightTime::Jst do
|
|
28
34
|
its(:time ) { should == Time.mktime(2012,7,3) }
|
29
35
|
end
|
30
36
|
|
37
|
+
context "(X/X)" do
|
38
|
+
let(:text ) { "7/3" }
|
39
|
+
its(:parse) { should == [nil,7,3,nil,nil,nil] }
|
40
|
+
its(:time ) { should == Time.mktime(2012,7,3) }
|
41
|
+
end
|
42
|
+
|
31
43
|
context "(XX月XX日)[半角]" do
|
32
44
|
let(:text ) { "テレビ7月8日(土)24:30~25:00" }
|
33
45
|
its(:parse) { should == [nil,7,8,24,30,nil] }
|
@@ -75,4 +87,66 @@ describe NightTime::Jst do
|
|
75
87
|
its(:parse) { should == [nil, nil, nil, 23, 30, nil] }
|
76
88
|
its(:time ) { should == Time.mktime(year,month,day,23,30) }
|
77
89
|
end
|
90
|
+
|
91
|
+
######################################################################
|
92
|
+
### ignore range error
|
93
|
+
|
94
|
+
context "(13/X)" do
|
95
|
+
let(:text ) { "13/3" }
|
96
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
97
|
+
end
|
98
|
+
|
99
|
+
context "(X/32)" do
|
100
|
+
let(:text ) { "1/32" }
|
101
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
102
|
+
end
|
103
|
+
|
104
|
+
context "(0/X)" do
|
105
|
+
let(:text ) { "0/1" }
|
106
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
107
|
+
end
|
108
|
+
|
109
|
+
context "(X/0)" do
|
110
|
+
let(:text ) { "1/0" }
|
111
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
112
|
+
end
|
113
|
+
|
114
|
+
context "(XXXX/0/X)" do
|
115
|
+
let(:text ) { "2012/0/3" }
|
116
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
117
|
+
end
|
118
|
+
|
119
|
+
context "(XXXX/X/0)" do
|
120
|
+
let(:text ) { "2012/1/0" }
|
121
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
122
|
+
end
|
123
|
+
|
124
|
+
context "(XXXX/13/X)" do
|
125
|
+
let(:text ) { "2012/13/1" }
|
126
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
127
|
+
end
|
128
|
+
|
129
|
+
context "(XXXX/X/32)" do
|
130
|
+
let(:text ) { "2012/1/32" }
|
131
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
132
|
+
end
|
133
|
+
|
134
|
+
context "(YYYYY/MM/DD)" do
|
135
|
+
let(:text ) { "11994-04-12" }
|
136
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
137
|
+
end
|
138
|
+
|
139
|
+
######################################################################
|
140
|
+
### ambiguous value
|
141
|
+
|
142
|
+
context "(2012/1/1/1)" do
|
143
|
+
let(:text ) { "2012/1/1/1" }
|
144
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
145
|
+
end
|
146
|
+
|
147
|
+
context "(1/1/1)" do
|
148
|
+
let(:text ) { "1/1/1" }
|
149
|
+
its(:parse) { should == [nil,nil,nil,nil,nil,nil] }
|
150
|
+
end
|
151
|
+
|
78
152
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: night-time
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 2
|
10
|
+
version: 1.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- maiha
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-07-
|
18
|
+
date: 2012-07-04 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rspec
|