horai 0.7.0
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/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +55 -0
- data/LICENSE.txt +20 -0
- data/README.md +3 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/horai.gemspec +76 -0
- data/lib/horai.rb +272 -0
- data/lib/ja_number.rb +56 -0
- data/spec/horai_spec.rb +222 -0
- data/spec/spec_helper.rb +12 -0
- metadata +162 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
-fs --color
|
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
|
4
|
+
gem "i18n", ">= 0.6.0"
|
5
|
+
gem "activesupport", ">= 3.0.0"
|
6
|
+
gem "rparsec-ruby19", ">= 1.0"
|
7
|
+
|
8
|
+
# Add dependencies to develop your gem here.
|
9
|
+
# Include everything needed to run rake, tests, features, etc.
|
10
|
+
group :development do
|
11
|
+
gem "rspec", "~> 2.8.0"
|
12
|
+
gem "rdoc", "~> 3.12"
|
13
|
+
gem "jeweler", "~> 1.8.3"
|
14
|
+
gem 'guard-shell'
|
15
|
+
gem 'guard-rspec'
|
16
|
+
gem 'pry'
|
17
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.0.12)
|
5
|
+
coderay (1.0.6)
|
6
|
+
diff-lcs (1.1.3)
|
7
|
+
ffi (1.0.11)
|
8
|
+
git (1.2.5)
|
9
|
+
guard (1.0.1)
|
10
|
+
ffi (>= 0.5.0)
|
11
|
+
thor (~> 0.14.6)
|
12
|
+
guard-rspec (0.7.0)
|
13
|
+
guard (>= 0.10.0)
|
14
|
+
guard-shell (0.4.0)
|
15
|
+
guard (>= 0.2.0)
|
16
|
+
i18n (0.6.0)
|
17
|
+
jeweler (1.8.3)
|
18
|
+
bundler (~> 1.0)
|
19
|
+
git (>= 1.2.5)
|
20
|
+
rake
|
21
|
+
rdoc
|
22
|
+
json (1.6.6)
|
23
|
+
method_source (0.7.1)
|
24
|
+
pry (0.9.9.3)
|
25
|
+
coderay (~> 1.0.5)
|
26
|
+
method_source (~> 0.7.1)
|
27
|
+
slop (>= 2.4.4, < 3)
|
28
|
+
rake (0.9.2.2)
|
29
|
+
rdoc (3.12)
|
30
|
+
json (~> 1.4)
|
31
|
+
rparsec-ruby19 (1.0)
|
32
|
+
rspec (2.8.0)
|
33
|
+
rspec-core (~> 2.8.0)
|
34
|
+
rspec-expectations (~> 2.8.0)
|
35
|
+
rspec-mocks (~> 2.8.0)
|
36
|
+
rspec-core (2.8.0)
|
37
|
+
rspec-expectations (2.8.0)
|
38
|
+
diff-lcs (~> 1.1.2)
|
39
|
+
rspec-mocks (2.8.0)
|
40
|
+
slop (2.4.4)
|
41
|
+
thor (0.14.6)
|
42
|
+
|
43
|
+
PLATFORMS
|
44
|
+
ruby
|
45
|
+
|
46
|
+
DEPENDENCIES
|
47
|
+
activesupport (>= 3.0.0)
|
48
|
+
guard-rspec
|
49
|
+
guard-shell
|
50
|
+
i18n (>= 0.6.0)
|
51
|
+
jeweler (~> 1.8.3)
|
52
|
+
pry
|
53
|
+
rdoc (~> 3.12)
|
54
|
+
rparsec-ruby19 (>= 1.0)
|
55
|
+
rspec (~> 2.8.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 AOKI Yuuto
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "horai"
|
18
|
+
gem.homepage = "http://github.com/wneko/horai"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = "日本語の時刻表現をパースし、DateTime型に変換する Gem"
|
21
|
+
gem.description = "Horai は日本語の時刻表現をパースし、DateTime型に変換することを目標としている Gem です。"
|
22
|
+
gem.email = "aoki@u-ne.co"
|
23
|
+
gem.authors = ["AOKI Yuuto"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rdoc/task'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "horai #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.7.0
|
data/horai.gemspec
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "horai"
|
8
|
+
s.version = "0.7.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["AOKI Yuuto"]
|
12
|
+
s.date = "2012-04-25"
|
13
|
+
s.description = "Horai \u{306f}\u{65e5}\u{672c}\u{8a9e}\u{306e}\u{6642}\u{523b}\u{8868}\u{73fe}\u{3092}\u{30d1}\u{30fc}\u{30b9}\u{3057}\u{3001}DateTime\u{578b}\u{306b}\u{5909}\u{63db}\u{3059}\u{308b}\u{3053}\u{3068}\u{3092}\u{76ee}\u{6a19}\u{3068}\u{3057}\u{3066}\u{3044}\u{308b} Gem \u{3067}\u{3059}\u{3002}"
|
14
|
+
s.email = "aoki@u-ne.co"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.md",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"horai.gemspec",
|
29
|
+
"lib/horai.rb",
|
30
|
+
"lib/ja_number.rb",
|
31
|
+
"spec/horai_spec.rb",
|
32
|
+
"spec/spec_helper.rb"
|
33
|
+
]
|
34
|
+
s.homepage = "http://github.com/wneko/horai"
|
35
|
+
s.licenses = ["MIT"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = "1.8.11"
|
38
|
+
s.summary = "\u{65e5}\u{672c}\u{8a9e}\u{306e}\u{6642}\u{523b}\u{8868}\u{73fe}\u{3092}\u{30d1}\u{30fc}\u{30b9}\u{3057}\u{3001}DateTime\u{578b}\u{306b}\u{5909}\u{63db}\u{3059}\u{308b} Gem"
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
s.specification_version = 3
|
42
|
+
|
43
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
44
|
+
s.add_runtime_dependency(%q<i18n>, [">= 0.6.0"])
|
45
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
|
46
|
+
s.add_runtime_dependency(%q<rparsec-ruby19>, [">= 1.0"])
|
47
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
48
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
49
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
50
|
+
s.add_development_dependency(%q<guard-shell>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
52
|
+
s.add_development_dependency(%q<pry>, [">= 0"])
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<i18n>, [">= 0.6.0"])
|
55
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
56
|
+
s.add_dependency(%q<rparsec-ruby19>, [">= 1.0"])
|
57
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
58
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
59
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
60
|
+
s.add_dependency(%q<guard-shell>, [">= 0"])
|
61
|
+
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
62
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
63
|
+
end
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<i18n>, [">= 0.6.0"])
|
66
|
+
s.add_dependency(%q<activesupport>, [">= 3.0.0"])
|
67
|
+
s.add_dependency(%q<rparsec-ruby19>, [">= 1.0"])
|
68
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
69
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
70
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
71
|
+
s.add_dependency(%q<guard-shell>, [">= 0"])
|
72
|
+
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
73
|
+
s.add_dependency(%q<pry>, [">= 0"])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
data/lib/horai.rb
ADDED
@@ -0,0 +1,272 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'active_support/time'
|
4
|
+
require "ja_number"
|
5
|
+
|
6
|
+
class Horai
|
7
|
+
NORMALIZE_FROM = '0-9a-zA-Z:'
|
8
|
+
NORMALIZE_TO = '0-9a-zA-Z:'
|
9
|
+
|
10
|
+
DATE_DELIMITER = (/[\/-]/)
|
11
|
+
TIME_DELIMITER = (/[:]/)
|
12
|
+
|
13
|
+
AFTERNOON_PATTERN = (/午後|ごご|夜|よる|(?<![a-z])pm(?![a-z])/i)
|
14
|
+
RELATIVE_KEYWORDS_PATTERN = (/(?<![明午])後(?![年月日])|(?:[経た]っ|し)たら/)
|
15
|
+
RELATIVE_PATTERN = (/(\d+)(?:(?:年|ねん)|(?:月|がつ)|(?:日|にち)|(?:分|ふん|ぷん)|(?:時間?|じ(?:かん)?)|(?:秒|びょう))#{RELATIVE_KEYWORDS_PATTERN}/)
|
16
|
+
|
17
|
+
def self.filter(pattern, type = :absolute, &block)
|
18
|
+
@filters = [] if @filters.nil?
|
19
|
+
@filters << { pattern: pattern, type => block }
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.truncate_time(date)
|
23
|
+
datetime_delta(date, hour: 0, minute: 0, second: 0)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.datetime_delta(date, methods = {})
|
27
|
+
date = date.dup
|
28
|
+
methods.each_pair do |key, value|
|
29
|
+
converter = 1.0.respond_to?(key) ? :to_f : :to_i;
|
30
|
+
date += value.send(converter).send(key) - date.send(key).send(key)
|
31
|
+
end
|
32
|
+
date
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.register_filters
|
36
|
+
dd = DATE_DELIMITER
|
37
|
+
td = TIME_DELIMITER
|
38
|
+
|
39
|
+
# 年 (絶対)
|
40
|
+
filter /(\d+)年/, :absolute do |text, matches, date|
|
41
|
+
year = year_normalize(matches[1].to_i)
|
42
|
+
truncate_time(datetime_delta(date, year: year, month: 1, day: 1))
|
43
|
+
end
|
44
|
+
|
45
|
+
filter /一昨[々昨]年|さきおととし|いっさくさくねん/, :absolute do |text, matches, date|
|
46
|
+
truncate_time(datetime_delta(date - 3.year, month: 1, day: 1))
|
47
|
+
end
|
48
|
+
|
49
|
+
filter /一昨年|おととし|いっさくねん/, :absolute do |text, matches, date|
|
50
|
+
truncate_time(datetime_delta(date - 2.year, month: 1, day: 1))
|
51
|
+
end
|
52
|
+
|
53
|
+
filter /去年|昨年|きょねん|さくねん/, :absolute do |text, matches, date|
|
54
|
+
truncate_time(datetime_delta(date - 1.year, month: 1, day: 1))
|
55
|
+
end
|
56
|
+
|
57
|
+
filter /今年|本年|ことし|ほんねん/, :absolute do |text, matches, date|
|
58
|
+
end
|
59
|
+
|
60
|
+
filter /来年|明年|らいねん|みょうねん/, :absolute do |text, matches, date|
|
61
|
+
truncate_time(datetime_delta(date + 1.year, month: 1, day: 1))
|
62
|
+
end
|
63
|
+
|
64
|
+
filter /再来年|明後年|さらいねん|みょうごねん/, :absolute do |text, matches, date|
|
65
|
+
truncate_time(datetime_delta(date + 2.year, month: 1, day: 1))
|
66
|
+
end
|
67
|
+
|
68
|
+
filter /明[々明]後年|みょうみょうごねん/, :absolute do |text, matches, date|
|
69
|
+
truncate_time(datetime_delta(date + 3.year, month: 1, day: 1))
|
70
|
+
end
|
71
|
+
|
72
|
+
# 月 (絶対)
|
73
|
+
filter /(\d+)月/, :absolute do |text, matches, date|
|
74
|
+
truncate_time(datetime_delta(date, month: matches[1].to_i, day: 1))
|
75
|
+
end
|
76
|
+
|
77
|
+
filter /[先前][々先前]{3}月|せんせんせんげつ/, :absolute do |text, matches, date|
|
78
|
+
truncate_time(datetime_delta(date - 3.month, day: 1))
|
79
|
+
end
|
80
|
+
|
81
|
+
filter /[先前][々先前]月|せんせんげつ/, :absolute do |text, matches, date|
|
82
|
+
truncate_time(datetime_delta(date - 2.month, day: 1))
|
83
|
+
end
|
84
|
+
|
85
|
+
filter /先月|前月|せんげつ/, :absolute do |text, matches, date|
|
86
|
+
truncate_time(datetime_delta(date - 1.month, day: 1))
|
87
|
+
end
|
88
|
+
|
89
|
+
filter /今月|こんげつ/, :absolute do |text, matches, date|
|
90
|
+
end
|
91
|
+
|
92
|
+
filter /来月|らいげつ/, :absolute do |text, matches, date|
|
93
|
+
truncate_time(datetime_delta(date + 1.month, day: 1))
|
94
|
+
end
|
95
|
+
|
96
|
+
filter /再来月|来[々来]月|さらいげつ|らいらいげつ/, :absolute do |text, matches, date|
|
97
|
+
truncate_time(datetime_delta(date + 2.month, day: 1))
|
98
|
+
end
|
99
|
+
|
100
|
+
filter /再[々再]来月|ささらいげつ/, :absolute do |text, matches, date|
|
101
|
+
truncate_time(datetime_delta(date + 3.month, day: 1))
|
102
|
+
end
|
103
|
+
|
104
|
+
# 日 (絶対)
|
105
|
+
filter /(\d+)日/, :absolute do |text, matches, date|
|
106
|
+
truncate_time(datetime_delta(date, day: matches[1]))
|
107
|
+
end
|
108
|
+
|
109
|
+
filter /一昨[々昨]日|さきおと[とつ]い|いっさくさくじつ/, :absolute do |text, matches, date|
|
110
|
+
truncate_time(date - 3.day)
|
111
|
+
end
|
112
|
+
|
113
|
+
filter /一昨日|おと[とつ]い|いっさくじつ/, :absolute do |text, matches, date|
|
114
|
+
truncate_time(date - 2.day)
|
115
|
+
end
|
116
|
+
|
117
|
+
filter /昨日|きのう|さくじつ/, :absolute do |text, matches, date|
|
118
|
+
truncate_time(date - 1.day)
|
119
|
+
end
|
120
|
+
|
121
|
+
filter /明日|あした|みょうじつ/, :absolute do |text, matches, date|
|
122
|
+
truncate_time(date + 1.day)
|
123
|
+
end
|
124
|
+
|
125
|
+
filter /明後日|あさって|みょうごにち/, :absolute do |text, matches, date|
|
126
|
+
truncate_time(date + 2.day)
|
127
|
+
end
|
128
|
+
|
129
|
+
filter /明[々明]後日|しあさって|みょうみょうごにち/, :absolute do |text, matches, date|
|
130
|
+
truncate_time(date + 3.day)
|
131
|
+
end
|
132
|
+
|
133
|
+
# 月日表現 (絶対)
|
134
|
+
filter /(?<![\d\/-])(?<!\d)(\d{1,2})#{dd}(\d{1,2})(?!#{dd})/, :absolute do |text, matches, date|
|
135
|
+
truncate_time(datetime_delta(date, month: matches[1], day: matches[2]))
|
136
|
+
end
|
137
|
+
|
138
|
+
# 年月日表現 (絶対)
|
139
|
+
filter /(?<![\d\/-])(\d{1,2}|\d{4})#{dd}(\d{1,2})#{dd}(\d{1,2})(?!#{dd})/, :absolute do |text, matches, date|
|
140
|
+
year = year_normalize(matches[1].to_i)
|
141
|
+
truncate_time(datetime_delta(date, year: year, month: matches[2], day: matches[3]))
|
142
|
+
end
|
143
|
+
|
144
|
+
# 時分表現 (絶対)
|
145
|
+
filter /(?<![\d:])(\d{1,2})#{td}(\d{2})(?!#{td})/, :absolute do |text, matches, date|
|
146
|
+
datetime_delta(date, hour: matches[1], minute: matches[2], second: 0)
|
147
|
+
end
|
148
|
+
|
149
|
+
# 時分秒表現 (絶対)
|
150
|
+
filter /(?<![\d:])(\d{1,2})#{td}(\d{2})#{td}(\d{2})(?!#{td})/, :absolute do |text, matches, date|
|
151
|
+
datetime_delta(date, hour: matches[1], minute: matches[2], second: matches[3])
|
152
|
+
end
|
153
|
+
|
154
|
+
# 時間 (絶対)
|
155
|
+
filter /正午/, :absolute do |text, matches, date|
|
156
|
+
datetime_delta(date, hour: 12, minute: 0, second: 0)
|
157
|
+
end
|
158
|
+
|
159
|
+
filter /(\d+)時(半)?/, :absolute do |text, matches, date|
|
160
|
+
hour = matches[1]
|
161
|
+
minute = matches[2] ? 30 : 0
|
162
|
+
date = datetime_delta(date, hour: hour, minute: minute, second: 0)
|
163
|
+
date += 12.hour if date.hour <= 12 && text =~ AFTERNOON_PATTERN
|
164
|
+
date
|
165
|
+
end
|
166
|
+
|
167
|
+
filter /(\d+)分(半)?/, :absolute do |text, matches, date|
|
168
|
+
minute = matches[1]
|
169
|
+
second = matches[2] ? 30 : 0
|
170
|
+
datetime_delta(date, minute: minute, second: second)
|
171
|
+
end
|
172
|
+
|
173
|
+
filter /(\d+)秒/, :absolute do |text, matches, date|
|
174
|
+
datetime_delta(date, second: matches[1])
|
175
|
+
end
|
176
|
+
|
177
|
+
# 年 (相対)
|
178
|
+
filter /(\d+)年/, :relative do |text, matches, date|
|
179
|
+
date + matches[1].to_i.year
|
180
|
+
end
|
181
|
+
|
182
|
+
# 月 (相対)
|
183
|
+
filter /(\d+)月/, :relative do |text, matches, date|
|
184
|
+
date + matches[1].to_i.month
|
185
|
+
end
|
186
|
+
|
187
|
+
# 日 (相対)
|
188
|
+
filter /(\d+)日/, :relative do |text, matches, date|
|
189
|
+
date + matches[1].to_f.day
|
190
|
+
end
|
191
|
+
|
192
|
+
# 時間 (相対)
|
193
|
+
filter /(\d+)時間(半)?/, :relative do |text, matches, date|
|
194
|
+
date + matches[1].to_f.hour + (matches[2] ? 0.5 : 0.0).hour
|
195
|
+
end
|
196
|
+
|
197
|
+
filter /(\d+)分(半)?/, :relative do |text, matches, date|
|
198
|
+
date + matches[1].to_f.minute + (matches[2] ? 0.5 : 0.0).minute
|
199
|
+
end
|
200
|
+
|
201
|
+
filter /(\d+)秒/, :relative do |text, matches, date|
|
202
|
+
date + matches[1].to_f.second
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.now
|
208
|
+
@now ||= DateTime.now
|
209
|
+
@now.dup
|
210
|
+
end
|
211
|
+
|
212
|
+
def self.filters
|
213
|
+
return @filters if @filters
|
214
|
+
register_filters
|
215
|
+
@filters
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.relative?(text)
|
219
|
+
text =~ RELATIVE_PATTERN
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.parse(text)
|
223
|
+
normalized = normalize(text)
|
224
|
+
contexts = (normalized + "$").split(RELATIVE_KEYWORDS_PATTERN)
|
225
|
+
date = now
|
226
|
+
|
227
|
+
filtered = false
|
228
|
+
|
229
|
+
contexts.each_with_index do |context, index|
|
230
|
+
if contexts.size >= 2 && index + 1 != contexts.size
|
231
|
+
mode = :relative
|
232
|
+
else
|
233
|
+
mode = :absolute
|
234
|
+
end
|
235
|
+
|
236
|
+
self.filters.each do |filter|
|
237
|
+
if (matches = context.match(filter[:pattern])) && filter[mode]
|
238
|
+
date = filter[mode].call(normalized, matches, date)
|
239
|
+
filtered = true unless filtered
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
@now = nil
|
245
|
+
|
246
|
+
return nil unless filtered
|
247
|
+
return date
|
248
|
+
end
|
249
|
+
|
250
|
+
def self.normalize(text)
|
251
|
+
normalized = text
|
252
|
+
normalized.tr!(NORMALIZE_FROM, NORMALIZE_TO)
|
253
|
+
digits = "一二三四五六七八九十百千"
|
254
|
+
classes = "万億兆"
|
255
|
+
normalized.gsub!(/[#{digits}][#{digits}#{classes}]*/) do |match|
|
256
|
+
JaNumber::JaNumberParser::parse(match)
|
257
|
+
end
|
258
|
+
return normalized
|
259
|
+
end
|
260
|
+
|
261
|
+
def self.year_normalize(year)
|
262
|
+
if year < 100
|
263
|
+
year_xx = (now.year / 100).to_i
|
264
|
+
if (year_xx - year).abs < 50
|
265
|
+
year += year_xx * 100
|
266
|
+
else
|
267
|
+
year += (year_xx - 1) * 100
|
268
|
+
end
|
269
|
+
end
|
270
|
+
year
|
271
|
+
end
|
272
|
+
end
|
data/lib/ja_number.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# original: http://d.hatena.ne.jp/terazzo/20101226/1293313464
|
3
|
+
|
4
|
+
module JaNumber
|
5
|
+
module Constants
|
6
|
+
DIGITS = "一二三四五六七八九"
|
7
|
+
CLASSES = "十百千"
|
8
|
+
UNITS = "万億兆" # 増やしたければどーぞ
|
9
|
+
end
|
10
|
+
|
11
|
+
module JaNumberParser
|
12
|
+
require 'rparsec'
|
13
|
+
|
14
|
+
# <digit> ::= "一" | "二" | "三" | "四" | "五" | "六" | "七" | "八" | "九"
|
15
|
+
digits =
|
16
|
+
Constants::DIGITS.split(//).map.with_index {
|
17
|
+
|c, i| RParsec::Parsers.char(c).map {|c| 1 + i}
|
18
|
+
}.inject(RParsec::Parsers.zero) {|result, p| result.plus(p)}
|
19
|
+
|
20
|
+
# <class> ::= "千" | "百" | "十"
|
21
|
+
classes =
|
22
|
+
Constants::CLASSES.split(//).map.with_index {
|
23
|
+
|c, i| RParsec::Parsers.char(c).map {|c| 10 ** (1 + i)}
|
24
|
+
}.inject(RParsec::Parsers.zero) {|result, p| result.plus(p)}
|
25
|
+
|
26
|
+
# <unit> ::= "万" | "億" | "兆"
|
27
|
+
units =
|
28
|
+
Constants::UNITS.split(//).map.with_index {
|
29
|
+
|c, i| RParsec::Parsers.char(c).map {|c| 10000 ** (1 + i)}
|
30
|
+
}.inject(RParsec::Parsers.zero) {|result, p| result.plus(p)}
|
31
|
+
|
32
|
+
# <singlet> ::= <digit>
|
33
|
+
singlet = digits
|
34
|
+
|
35
|
+
# <quadruplet> ::= <digit>? <class> <quadruplet>? | <singlet>
|
36
|
+
quadruplet = nil
|
37
|
+
lazy_quadruplet = RParsec::Parsers.lazy{quadruplet}
|
38
|
+
quadruplet =
|
39
|
+
RParsec::Parsers.sequence(digits.optional(1), classes, lazy_quadruplet.optional(0)) {
|
40
|
+
|digit_value, class_value, next_value| digit_value * class_value + next_value
|
41
|
+
} | singlet
|
42
|
+
|
43
|
+
# <number> ::= <quadruplet> <unit> <number>? | <quadruplet>
|
44
|
+
number = nil
|
45
|
+
lazy_number = RParsec::Parsers.lazy{number}
|
46
|
+
number =
|
47
|
+
RParsec::Parsers.sequence(quadruplet, units, lazy_number.optional(0)) {
|
48
|
+
|quadruplet_value, unit_value, next_value| quadruplet_value * unit_value + next_value
|
49
|
+
} | quadruplet
|
50
|
+
|
51
|
+
define_method :parse do |ja_number|
|
52
|
+
number.parse ja_number
|
53
|
+
end
|
54
|
+
module_function :parse
|
55
|
+
end
|
56
|
+
end
|
data/spec/horai_spec.rb
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
4
|
+
|
5
|
+
def now (year = nil, month = nil, day = nil, hour = nil, minute = nil, second = nil)
|
6
|
+
@now ||= Horai::now
|
7
|
+
|
8
|
+
# puts "{" + [year || @now.year,
|
9
|
+
# month || @now.month,
|
10
|
+
# day || @now.day,
|
11
|
+
# hour || @now.hour,
|
12
|
+
# minute || @now.minute,
|
13
|
+
# second || @now.second,
|
14
|
+
# Rational(9, 24)].join(',') + "}"
|
15
|
+
|
16
|
+
DateTime.new(year || @now.year,
|
17
|
+
month || @now.month,
|
18
|
+
day || @now.day,
|
19
|
+
hour || @now.hour,
|
20
|
+
minute || @now.minute,
|
21
|
+
second || @now.second,
|
22
|
+
Rational(9, 24))
|
23
|
+
end
|
24
|
+
|
25
|
+
describe Horai do
|
26
|
+
context 'normalize' do
|
27
|
+
it "number" do
|
28
|
+
Horai.normalize('01234').should === '01234'
|
29
|
+
end
|
30
|
+
it "alphabet" do
|
31
|
+
Horai.normalize('abcde').should === 'abcde'
|
32
|
+
Horai.normalize('ABCDE').should === 'ABCDE'
|
33
|
+
end
|
34
|
+
it "numeric kanji" do
|
35
|
+
Horai.normalize('十五').should === '15'
|
36
|
+
Horai.normalize('十四万二千三百四十五').should === '142345'
|
37
|
+
Horai.normalize('百五十時間後').should === '150時間後'
|
38
|
+
|
39
|
+
pending "漢数字パースライブラリがだめ"
|
40
|
+
Horai.normalize('1万秒').should === '10000秒'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'invalid cases' do
|
45
|
+
it 'not even one filter passed' do
|
46
|
+
Horai.parse("なにもなし").should be_nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'parse absolute' do
|
51
|
+
before :each do
|
52
|
+
@sample_date = DateTime.new(2012, 4, 11, 12, 45, 30, Rational(9, 24))
|
53
|
+
@sample_text = @sample_date.strftime('%Y年%m月%d日の%H時%M分%S秒')
|
54
|
+
end
|
55
|
+
it "year, month, day, hour, minute, second" do
|
56
|
+
time = Horai.parse(@sample_text)
|
57
|
+
time.to_s.should === @sample_date.to_s
|
58
|
+
end
|
59
|
+
it "year" do
|
60
|
+
time = Horai.parse("1999年")
|
61
|
+
time.to_s.should === now(1999, 1, 1, 0, 0, 0).to_s
|
62
|
+
end
|
63
|
+
it "month" do
|
64
|
+
time = Horai.parse("1月")
|
65
|
+
time.to_s.should === now(nil, 1, 1, 0, 0, 0).to_s
|
66
|
+
end
|
67
|
+
it "half time" do
|
68
|
+
time = Horai.parse("1時半")
|
69
|
+
time.to_s.should === now(nil, nil, nil, 1, 30, 0).to_s
|
70
|
+
end
|
71
|
+
it "half minute" do
|
72
|
+
time = Horai.parse("1分半後")
|
73
|
+
time.to_s.should === (now + 1.5.minute).to_s
|
74
|
+
end
|
75
|
+
it "half hour and minute" do
|
76
|
+
time = Horai.parse("5時間半と1分半後")
|
77
|
+
time.to_s.should === (now + 5.5.hour + 1.5.minute).to_s
|
78
|
+
end
|
79
|
+
it "at night" do
|
80
|
+
time = Horai.parse("夜の8時に")
|
81
|
+
time.to_s.should === (now(nil, nil, nil, 20, 0, 0)).to_s
|
82
|
+
end
|
83
|
+
it "at afternoon" do
|
84
|
+
time = Horai.parse("午後一時に")
|
85
|
+
time.to_s.should === (now(nil, nil, nil, 13, 0, 0)).to_s
|
86
|
+
end
|
87
|
+
it "at afternoon" do
|
88
|
+
time = Horai.parse("PM1時に")
|
89
|
+
time.to_s.should === (now(nil, nil, nil, 13, 0, 0)).to_s
|
90
|
+
end
|
91
|
+
it "at AM and contains *pm*" do
|
92
|
+
time = Horai.parse("rpm 6時に")
|
93
|
+
time.to_s.should === (now(nil, nil, nil, 6, 0, 0)).to_s
|
94
|
+
end
|
95
|
+
it "at noon" do
|
96
|
+
time = Horai.parse("10日の正午に")
|
97
|
+
time.to_s.should === (now(nil, nil, 10, 12, 0, 0)).to_s
|
98
|
+
end
|
99
|
+
it "at hh:mm" do
|
100
|
+
time = Horai.parse("10:20")
|
101
|
+
time.to_s.should === (now(nil, nil, nil, 10, 20, 0)).to_s
|
102
|
+
end
|
103
|
+
it "at hh:mm:ss" do
|
104
|
+
time = Horai.parse("10:20:30")
|
105
|
+
time.to_s.should === (now(nil, nil, nil, 10, 20, 30)).to_s
|
106
|
+
end
|
107
|
+
it "at MM/DD" do
|
108
|
+
time = Horai.parse("10/20")
|
109
|
+
time.to_s.should === now(nil, 10, 20, 0, 0, 0).to_s
|
110
|
+
end
|
111
|
+
it "at YYYY/MM/DD" do
|
112
|
+
time = Horai.parse("2000/10/20")
|
113
|
+
time.to_s.should === now(2000, 10, 20, 0, 0, 0).to_s
|
114
|
+
end
|
115
|
+
it "at YY/MM/DD" do
|
116
|
+
time = Horai.parse("10/10/20")
|
117
|
+
time.to_s.should === now(2010, 10, 20, 0, 0, 0).to_s
|
118
|
+
end
|
119
|
+
it "at YYYY/MM/DD hh:mm:ss" do
|
120
|
+
time = Horai.parse("2000/10/20 12:30:40")
|
121
|
+
time.to_s.should === now(2000, 10, 20, 12, 30, 40).to_s
|
122
|
+
end
|
123
|
+
it "at YY (near current year)" do
|
124
|
+
time = Horai.parse("10年")
|
125
|
+
time.to_s.should === now(2010, 1, 1, 0, 0, 0).to_s
|
126
|
+
end
|
127
|
+
it "at YY (near feature)" do
|
128
|
+
time = Horai.parse("30年")
|
129
|
+
time.to_s.should === now(2030, 1, 1, 0, 0, 0).to_s
|
130
|
+
end
|
131
|
+
it "at YY (not near feature)" do
|
132
|
+
time = Horai.parse("90年")
|
133
|
+
time.to_s.should === now(1990, 1, 1, 0, 0, 0).to_s
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'parse relative' do
|
138
|
+
it "check" do
|
139
|
+
Horai.relative?("10分後").should be_true
|
140
|
+
Horai.relative?("10分経ったら").should be_true
|
141
|
+
Horai.relative?("10分したら").should be_true
|
142
|
+
Horai.relative?("10分").should be_false
|
143
|
+
Horai.relative?("10時10分").should be_false
|
144
|
+
end
|
145
|
+
it "next year" do
|
146
|
+
time = Horai.parse("来年")
|
147
|
+
time.to_s.should === (now(nil, 1, 1, 0, 0, 0) + 1.year).to_s
|
148
|
+
end
|
149
|
+
it "next month" do
|
150
|
+
time = Horai.parse("来月")
|
151
|
+
time.to_s.should === (now(nil, nil, 1, 0, 0, 0) + 1.month).to_s
|
152
|
+
end
|
153
|
+
it "tomorrow" do
|
154
|
+
time = Horai.parse("明日")
|
155
|
+
time.to_s.should === (now(nil, nil, nil, 0, 0, 0) + 1.day).to_s
|
156
|
+
end
|
157
|
+
it "day after tomorrow" do
|
158
|
+
time = Horai.parse("明後日")
|
159
|
+
time.to_s.should === (now(nil, nil, nil, 0, 0, 0) + 2.day).to_s
|
160
|
+
end
|
161
|
+
it "yesterday" do
|
162
|
+
time = Horai.parse("昨日")
|
163
|
+
time.to_s.should === (now(nil, nil, nil, 0, 0, 0) - 1.day).to_s
|
164
|
+
end
|
165
|
+
it "numeric year after and absolute month" do
|
166
|
+
time = Horai.parse("10年後の8月")
|
167
|
+
time.to_s.should === (now(nil, 8, 1, 0, 0, 0) + 10.year).to_s
|
168
|
+
end
|
169
|
+
it "numeric minute after" do
|
170
|
+
time = Horai.parse("10分後")
|
171
|
+
time.to_s.should === (now + 10.minute).to_s
|
172
|
+
end
|
173
|
+
it "numeric day after" do
|
174
|
+
time = Horai.parse("10日後")
|
175
|
+
time.to_s.should === (now + 10.day).to_s
|
176
|
+
end
|
177
|
+
it "tomorrow and absolute time" do
|
178
|
+
time = Horai.parse("明日の10時")
|
179
|
+
time.to_s.should === (now(nil, nil, nil, 10, 0, 0) + 1.day).to_s
|
180
|
+
end
|
181
|
+
it "tomorrow and absolute hh:mm:ss" do
|
182
|
+
time = Horai.parse("明日の10:20:30")
|
183
|
+
time.to_s.should === (now(nil, nil, nil, 10, 20, 30) + 1.day).to_s
|
184
|
+
end
|
185
|
+
it "tomorrow and afternoon" do
|
186
|
+
time = Horai.parse("明日の午後5時")
|
187
|
+
time.to_s.should === (now(nil, nil, nil, 17, 0, 0) + 1.day).to_s
|
188
|
+
end
|
189
|
+
it "tomorrow and noon" do
|
190
|
+
time = Horai.parse("明日の正午")
|
191
|
+
time.to_s.should === (now(nil, nil, nil, 12, 0, 0) + 1.day).to_s
|
192
|
+
end
|
193
|
+
it "numeric day after and absolute time" do
|
194
|
+
time = Horai.parse("3日後の12時")
|
195
|
+
time.to_s.should === (now(nil, nil, nil, 12, 0, 0) + 3.day).to_s
|
196
|
+
end
|
197
|
+
it "numeric day after and absolute time" do
|
198
|
+
time = Horai.parse("3日後の12時45分")
|
199
|
+
time.to_s.should === (now(nil, nil, nil, 12, 45, 0) + 3.day).to_s
|
200
|
+
end
|
201
|
+
it "numeric day after and absolute hh:mm:ss" do
|
202
|
+
time = Horai.parse("3日後の12:45:55")
|
203
|
+
time.to_s.should === (now(nil, nil, nil, 12, 45, 55) + 3.day).to_s
|
204
|
+
end
|
205
|
+
it "numeric day after and relative time" do
|
206
|
+
time = Horai.parse("3日12時間45分後")
|
207
|
+
time.to_s.should === (now + 3.day + 12.hour + 45.minute).to_s
|
208
|
+
end
|
209
|
+
it "half time after" do
|
210
|
+
time = Horai.parse("1時間半後")
|
211
|
+
time.to_s.should === (now + 1.5.hour).to_s
|
212
|
+
end
|
213
|
+
it "half minute after" do
|
214
|
+
time = Horai.parse("1分半後")
|
215
|
+
time.to_s.should === (now + 1.5.minute).to_s
|
216
|
+
end
|
217
|
+
it "half hour and half minute after" do
|
218
|
+
time = Horai.parse("5時間半と1分半後")
|
219
|
+
time.to_s.should === (now + 5.5.hour + 1.5.minute).to_s
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'horai'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: horai
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- AOKI Yuuto
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: i18n
|
16
|
+
requirement: &2157979040 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.6.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2157979040
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
requirement: &2157978480 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.0
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2157978480
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rparsec-ruby19
|
38
|
+
requirement: &2157977980 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2157977980
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &2157977440 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.8.0
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2157977440
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rdoc
|
60
|
+
requirement: &2157976920 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '3.12'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2157976920
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: jeweler
|
71
|
+
requirement: &2157976440 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.8.3
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2157976440
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: guard-shell
|
82
|
+
requirement: &2157975860 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2157975860
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: guard-rspec
|
93
|
+
requirement: &2157975360 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *2157975360
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: pry
|
104
|
+
requirement: &2157974880 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *2157974880
|
113
|
+
description: Horai は日本語の時刻表現をパースし、DateTime型に変換することを目標としている Gem です。
|
114
|
+
email: aoki@u-ne.co
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files:
|
118
|
+
- LICENSE.txt
|
119
|
+
- README.md
|
120
|
+
files:
|
121
|
+
- .document
|
122
|
+
- .rspec
|
123
|
+
- Gemfile
|
124
|
+
- Gemfile.lock
|
125
|
+
- LICENSE.txt
|
126
|
+
- README.md
|
127
|
+
- Rakefile
|
128
|
+
- VERSION
|
129
|
+
- horai.gemspec
|
130
|
+
- lib/horai.rb
|
131
|
+
- lib/ja_number.rb
|
132
|
+
- spec/horai_spec.rb
|
133
|
+
- spec/spec_helper.rb
|
134
|
+
homepage: http://github.com/wneko/horai
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
post_install_message:
|
138
|
+
rdoc_options: []
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
hash: -3122584729073349609
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ! '>='
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
requirements: []
|
157
|
+
rubyforge_project:
|
158
|
+
rubygems_version: 1.8.11
|
159
|
+
signing_key:
|
160
|
+
specification_version: 3
|
161
|
+
summary: 日本語の時刻表現をパースし、DateTime型に変換する Gem
|
162
|
+
test_files: []
|