night-time 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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.new("テレビ7月8日(土)24:30~25:00")
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.time
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
@@ -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 to_array; [year, month, day, hour, min, sec]; end
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 parsedate
42
+ def trace
26
43
  build!
27
- @build.to_array
44
+ return @trace
28
45
  end
29
46
 
30
47
  def parse
31
- parsedate
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
- catch(:completed) {
68
- parse_nengappi
69
- parse_gappi
70
- parse_iso8601
71
- parse_jifunbyou
72
- parse_jifun
73
- parse_month_slash_day
74
- parse_hour_colon_min
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
- @build.year ||= $1.to_i
81
- @build.month ||= $2.to_i
82
- @build.day ||= $3.to_i
83
- return validate!
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
- @build.month ||= $1.to_i
90
- @build.day ||= $2.to_i
91
- return validate!
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
- @build.year ||= $1.to_i
98
- @build.month ||= $2.to_i
99
- @build.day ||= $3.to_i
100
- return validate!
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
- @build.month ||= $1.to_i
107
- @build.day ||= $2.to_i
108
- return validate!
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
- hour_margin = ($1 and $2.to_i < 5) ? 24 : 0
115
- @build.hour ||= hour_margin + $2.to_i
116
- @build.min ||= $3.to_i
117
- @build.sec ||= $4.to_i
118
- return validate!
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
- hour_margin = ($1 and $2.to_i < 5) ? 24 : 0
125
- @build.hour ||= hour_margin + $2.to_i
126
- @build.min ||= $3.to_i
127
- return validate!
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
- hour_margin = ($1 and $2.to_i < 5) ? 24 : 0
134
- @build.hour ||= hour_margin + $2.to_i
135
- @build.min ||= $3.to_i
136
- return validate!
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
- throw(:completed) if @build.full?
183
+ raise Completed if @build.full?
142
184
  end
143
185
  end
144
186
  end
@@ -1,3 +1,3 @@
1
1
  module NightTime
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
@@ -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: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
- - 1
10
- version: 1.0.1
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-03 00:00:00 Z
18
+ date: 2012-07-04 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec