wareki 0.2.1 → 0.2.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.
- checksums.yaml +5 -5
- data/ChangeLog +5 -0
- data/README.rdoc +3 -8
- data/lib/wareki/common.rb +14 -15
- data/lib/wareki/date.rb +73 -79
- data/lib/wareki/kansuji.rb +108 -0
- data/lib/wareki/std_ext.rb +10 -10
- data/lib/wareki/utils.rb +17 -110
- data/lib/wareki/version.rb +1 -1
- metadata +21 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 790c42a6f6b07acda3701e35d179140baf9435df3866c3e4604ab5bcc484e55f
|
4
|
+
data.tar.gz: ddf6f052c60fe43faec942b48b3ffaef9ac7d801e9a8ac67c6cdd2ea9672156d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02a4b54f5f344cb75c64bf16be764cc073d503a0c7efe9a6b6695a3aff62fb7bedbdaa1c6ef7a2e9a6e86f83e396c2b38a257e19f84034b6766bc0879c200c29
|
7
|
+
data.tar.gz: 2c8581f1e91da2535d335136fafaa55f6b8a901169a4003df570801ab8c548f2109fc0e98108b0752427e55590f88178681d9ffb41efcf17b4367ee382bfe6a3
|
data/ChangeLog
CHANGED
data/README.rdoc
CHANGED
@@ -87,11 +87,12 @@ Gemfile に以下のようにするか、
|
|
87
87
|
== 仕様、限界、制限など
|
88
88
|
|
89
89
|
* 作者は暦の専門家ではまったくありません。ツッコミお待ちしています。
|
90
|
-
* 皇紀と旧暦が出力できますが、旧暦445年1月1日(先発グレゴリオ暦で445年1月25日)より前の日付はサポートしていません。扱おうとすると UnsupportedDateRange 例外を上げます。
|
90
|
+
* 皇紀と旧暦が出力できますが、旧暦445年1月1日(先発グレゴリオ暦で445年1月25日)より前の日付はサポートしていません。扱おうとすると Wareki::UnsupportedDateRange 例外を上げます。
|
91
|
+
* また Date 型からの変換の場合、 現状「大化」で1年1月1日扱いになる日(ユリウス暦で645年2月2日、先発グレゴリオ暦では645年2月5日)より前の日付はサポートしていません。こちらも Wareki::UnsupportedDateRange 例外がおきます。
|
91
92
|
* 日本暦日原典の対照表が、どの暦法を元にしているのか分かっていません。単にデータだけを利用しています。
|
92
93
|
* 内部的には全てユリウス日を経由して変換しています。
|
93
94
|
* パース時には元号の存在しない年(例: 霊亀百年)を受け入れます。しかし現状、Date に変換した場合この情報は捨てられ、パース時の元号を復元することはできません。(Wareki::Date を直接扱えば可能です)
|
94
|
-
* 改暦による存在しない日(明治5年12月3日〜31日)
|
95
|
+
* 改暦による存在しない日(明治5年12月3日〜31日)は基本的に例外(ArgumentError)を上げます。が、現状このチェックは完全ではありません。
|
95
96
|
* 北朝の元号も解釈できます。しかし現在の所、北朝の元号で文字列にフォーマットすることはできません。
|
96
97
|
* 10月の別名は「神無月」しかサポートしていません
|
97
98
|
* 将来の日付に関しては、現在の元号がずっと継続しているとみなします
|
@@ -111,9 +112,3 @@ Gemfile に以下のようにするか、
|
|
111
112
|
== 作者
|
112
113
|
|
113
114
|
Tatsuki Sugiura <sugi@nemui.org>
|
114
|
-
|
115
|
-
== TODO
|
116
|
-
* 北朝モード
|
117
|
-
* Wareki::Date で各種計算のサポート
|
118
|
-
* 元号として "西暦" サポート?
|
119
|
-
* 元号の切り替え日を和暦ベースで計算するようにする?
|
data/lib/wareki/common.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
require 'wareki/calendar_def'
|
3
2
|
require 'wareki/era_def'
|
4
3
|
require 'date'
|
4
|
+
# Wareki module common constants definitions
|
5
5
|
module Wareki
|
6
|
-
GREGORIAN_START =
|
6
|
+
GREGORIAN_START = 2_405_160 # Date.new(1873, 1, 1, Date::GREGORIAN).jd
|
7
7
|
GREGORIAN_START_YEAR = 1873
|
8
|
-
IMPERIAL_START =
|
8
|
+
IMPERIAL_START = 1_480_041 # Date.new(-660, 2, 11, Date::GREGORIAN).jd
|
9
9
|
IMPERIAL_START_YEAR = -660
|
10
|
-
DATE_INFINITY = ::Date.new(
|
11
|
-
YEAR_BY_NUM = Hash[*YEAR_DEFS.map{|y| [y.year, y]}.flatten].freeze
|
12
|
-
ERA_BY_NAME = Hash[*(ERA_NORTH_DEFS + ERA_DEFS).map {|g| [g.name, g]}.flatten]
|
13
|
-
ERA_BY_NAME['皇紀'] = ERA_BY_NAME['神武天皇即位紀元'] = Era.new('皇紀', -660,
|
14
|
-
ERA_BY_NAME['西暦'] = ERA_BY_NAME[''] = Era.new('西暦', 1,
|
10
|
+
DATE_INFINITY = ::Date.new(280_000_000, 12, 31) # Use 280000000 for jruby limitation...
|
11
|
+
YEAR_BY_NUM = Hash[*YEAR_DEFS.map { |y| [y.year, y] }.flatten].freeze
|
12
|
+
ERA_BY_NAME = Hash[*(ERA_NORTH_DEFS + ERA_DEFS).map { |g| [g.name, g] }.flatten]
|
13
|
+
ERA_BY_NAME['皇紀'] = ERA_BY_NAME['神武天皇即位紀元'] = Era.new('皇紀', -660, 1_480_041, DATE_INFINITY.jd)
|
14
|
+
ERA_BY_NAME['西暦'] = ERA_BY_NAME[''] = Era.new('西暦', 1, 1_721_424, DATE_INFINITY.jd)
|
15
15
|
ERA_BY_NAME.keys.each do |era_name|
|
16
|
-
alt_era_name = era_name.tr(
|
16
|
+
alt_era_name = era_name.tr('宝霊神応暦祥寿斎観寛徳禄万福禎国亀', '寳靈神應曆祥壽斉觀寬德祿萬福禎國龜')
|
17
17
|
alt_era_name == era_name and next
|
18
18
|
ERA_BY_NAME[alt_era_name] = ERA_BY_NAME[era_name]
|
19
19
|
end
|
@@ -21,7 +21,7 @@ module Wareki
|
|
21
21
|
ERA_BY_NAME[short] = ERA_BY_NAME[canon]
|
22
22
|
end
|
23
23
|
ERA_BY_NAME.freeze
|
24
|
-
NUM_CHARS =
|
24
|
+
NUM_CHARS = '零〇一二三四五六七八九十卄廿卅丗卌肆百皕千万億兆01234567890123456789'.freeze
|
25
25
|
ALT_MONTH_NAME = %w(睦月 如月 弥生 卯月 皐月 水無月 文月 葉月 長月 神無月 霜月 師走).freeze
|
26
26
|
REGEX = %r{^
|
27
27
|
(?<era_name>西暦|紀元前|#{ERA_BY_NAME.keys.join('|')})?
|
@@ -35,11 +35,10 @@ module Wareki
|
|
35
35
|
class UnsupportedDateRange < StandardError; end
|
36
36
|
|
37
37
|
module_function
|
38
|
+
|
38
39
|
def parse_to_date(str, start = ::Date::ITALY)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
::Date.parse(str, true, start)
|
43
|
-
end
|
40
|
+
Date.parse(str).to_date(start)
|
41
|
+
rescue ArgumentError
|
42
|
+
::Date.parse(str, true, start)
|
44
43
|
end
|
45
44
|
end
|
data/lib/wareki/date.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
require 'date'
|
3
2
|
require 'wareki/common'
|
4
3
|
require 'wareki/utils'
|
4
|
+
require 'wareki/kansuji'
|
5
5
|
module Wareki
|
6
|
+
# Wareki date handling class, main implementation.
|
6
7
|
class Date
|
7
|
-
attr_reader :jd
|
8
8
|
attr_accessor :year, :month, :day, :era_year, :era_name
|
9
9
|
|
10
10
|
def self.today
|
@@ -14,27 +14,26 @@ module Wareki
|
|
14
14
|
def self._check_invalid_date(era, year, month, day)
|
15
15
|
month == 12 or return true
|
16
16
|
day > 2 or return true
|
17
|
-
(era ==
|
18
|
-
era.to_s == "" && year == GREGORIAN_START_YEAR - 1 ||
|
17
|
+
(era == '明治' && year == 5 ||
|
19
18
|
%w(皇紀 神武天皇即位紀元).member?(era) &&
|
20
|
-
year == GREGORIAN_START_YEAR - IMPERIAL_START_YEAR - 1)
|
21
|
-
return
|
22
|
-
|
19
|
+
year == GREGORIAN_START_YEAR - IMPERIAL_START_YEAR - 1) and
|
20
|
+
return false
|
21
|
+
true
|
23
22
|
end
|
24
23
|
|
25
24
|
def self._parse(str)
|
26
|
-
match = REGEX.match(str.to_s.gsub(/[[:space:]]/, '')) or
|
25
|
+
match = REGEX.match(str.to_s.gsub(/[[:space:]]/, '')) or
|
27
26
|
raise ArgumentError, "Invaild Date: #{str}"
|
28
27
|
era = match[:era_name]
|
29
|
-
(year =
|
28
|
+
(year = Kansuji.k2i(match[:year])) > 0 or
|
30
29
|
raise ArgumentError, "Invalid year: #{str}"
|
31
30
|
month = day = 1
|
32
31
|
|
33
|
-
era.to_s !=
|
32
|
+
era.to_s != '' && era.to_s != '紀元前' && !ERA_BY_NAME[era] and
|
34
33
|
raise ArgumentError, "Date parse failed: Invalid era name '#{match[:era_name]}'"
|
35
34
|
|
36
35
|
if match[:month]
|
37
|
-
month =
|
36
|
+
month = Kansuji.k2i(match[:month])
|
38
37
|
elsif match[:alt_month]
|
39
38
|
month = Utils.alt_month_name_to_i(match[:alt_month])
|
40
39
|
end
|
@@ -43,10 +42,10 @@ module Wareki
|
|
43
42
|
raise ArgumentError, "Invalid month: #{str}"
|
44
43
|
|
45
44
|
if match[:day]
|
46
|
-
if match[:day] ==
|
47
|
-
day = Utils.last_day_of_month(ERA_BY_NAME[era].year + year -1, month, match[:is_leap])
|
45
|
+
if match[:day] == '晦'
|
46
|
+
day = Utils.last_day_of_month(ERA_BY_NAME[era].year + year - 1, month, match[:is_leap])
|
48
47
|
else
|
49
|
-
day =
|
48
|
+
day = Kansuji.k2i(match[:day])
|
50
49
|
end
|
51
50
|
end
|
52
51
|
|
@@ -75,24 +74,24 @@ module Wareki
|
|
75
74
|
end
|
76
75
|
|
77
76
|
def self.imperial(year, month = 1, day = 1, is_leap_month = false)
|
78
|
-
new(
|
77
|
+
new('皇紀', year, month, day, is_leap_month)
|
79
78
|
end
|
80
79
|
|
81
80
|
def initialize(era_name, era_year, month = 1, day = 1, is_leap_month = false)
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
raise ArgumentError, "Undefined era '#{era_name}'" if
|
82
|
+
era_name.to_s != '' && era_name != '紀元前' && !ERA_BY_NAME[era_name]
|
83
|
+
|
85
84
|
@month = month
|
86
85
|
@day = day
|
87
86
|
@is_leap_month = is_leap_month
|
88
87
|
@era_name = era_name
|
89
88
|
@era_year = era_year
|
90
|
-
if era_name.to_s ==
|
89
|
+
if era_name.to_s == '' || era_name == '西暦'
|
91
90
|
@year = @era_year
|
92
|
-
elsif era_name ==
|
93
|
-
@year = era_year + IMPERIAL_START_YEAR
|
94
|
-
elsif era_name.to_s == "紀元前"
|
91
|
+
elsif era_name.to_s == '紀元前'
|
95
92
|
@year = -@era_year
|
93
|
+
elsif %w(皇紀 神武天皇即位紀元).include? era_name
|
94
|
+
@year = era_year + IMPERIAL_START_YEAR
|
96
95
|
else
|
97
96
|
@year = ERA_BY_NAME[era_name].year + era_year - 1
|
98
97
|
end
|
@@ -119,30 +118,27 @@ module Wareki
|
|
119
118
|
end
|
120
119
|
|
121
120
|
def month_index
|
122
|
-
|
123
|
-
|
124
|
-
end
|
121
|
+
return month - 1 if
|
122
|
+
['', '西暦', '紀元前'].include?(@era_name) || @year >= GREGORIAN_START_YEAR
|
125
123
|
|
126
124
|
yobj = YEAR_BY_NUM[@year] or
|
127
|
-
raise UnsupportedDateRange, "Cannot get year info of #{
|
125
|
+
raise UnsupportedDateRange, "Cannot get year info of #{inspect}"
|
128
126
|
idx = month - 1
|
129
|
-
if leap_month? || yobj.leap_month && month > yobj.leap_month
|
130
|
-
idx += 1
|
131
|
-
end
|
127
|
+
idx += 1 if leap_month? || yobj.leap_month && month > yobj.leap_month
|
132
128
|
idx
|
133
129
|
end
|
134
130
|
|
135
131
|
def jd
|
136
132
|
@jd and return @jd
|
137
133
|
|
138
|
-
|
134
|
+
['', '西暦', '紀元前'].include?(@era_name) and
|
139
135
|
return @jd = ::Date.new(@year, month, day, ::Date::ITALY).jd
|
140
|
-
|
136
|
+
|
137
|
+
@year >= GREGORIAN_START_YEAR and
|
141
138
|
return @jd = ::Date.new(@year, month, day, ::Date::GREGORIAN).jd
|
142
|
-
end
|
143
139
|
|
144
140
|
yobj = YEAR_BY_NUM[@year] or
|
145
|
-
raise UnsupportedDateRange, "Cannot convert to jd #{
|
141
|
+
raise UnsupportedDateRange, "Cannot convert to jd #{inspect}"
|
146
142
|
@jd = yobj.month_starts[month_index] + day - 1
|
147
143
|
end
|
148
144
|
|
@@ -154,83 +150,81 @@ module Wareki
|
|
154
150
|
to_date.to_time
|
155
151
|
end
|
156
152
|
|
157
|
-
def strftime(format_str =
|
153
|
+
def strftime(format_str = '%JF')
|
158
154
|
ret = format_str.to_str.gsub(/%J([fFyYegGoOiImMsSlLdD][kK]?)/) { format($1) || $& }
|
159
|
-
ret.index(
|
155
|
+
ret.index('%') or return ret
|
160
156
|
d = to_date
|
161
157
|
d.respond_to?(:_wareki_strftime_orig) ? d._wareki_strftime_orig(ret) : d.strftime(ret)
|
162
158
|
end
|
163
159
|
|
164
160
|
def format(key)
|
165
161
|
case key.to_sym
|
166
|
-
when :e
|
167
|
-
when :g
|
168
|
-
when :G
|
169
|
-
when :Gk
|
162
|
+
when :e then era_name
|
163
|
+
when :g then era_name.to_s == '' ? '' : era_year
|
164
|
+
when :G then era_name.to_s == '' ? '' : Kansuji.i2z(era_year)
|
165
|
+
when :Gk then era_name.to_s == '' ? '' : Kansuji.i2k(era_year)
|
170
166
|
when :GK
|
171
|
-
if era_name.to_s ==
|
167
|
+
if era_name.to_s == ''
|
172
168
|
''
|
173
169
|
elsif era_year == 1
|
174
|
-
|
170
|
+
'元'
|
175
171
|
else
|
176
|
-
|
172
|
+
Kansuji.i2k(era_year)
|
177
173
|
end
|
178
|
-
when :o
|
179
|
-
when :O
|
180
|
-
when :Ok
|
181
|
-
when :i
|
182
|
-
when :I
|
183
|
-
when :Ik
|
184
|
-
when :s
|
185
|
-
when :S
|
186
|
-
when :Sk
|
187
|
-
when :SK
|
188
|
-
when :l
|
189
|
-
when :L
|
190
|
-
when :Lk
|
191
|
-
when :d
|
192
|
-
when :D
|
193
|
-
when :Dk
|
174
|
+
when :o then year
|
175
|
+
when :O then Kansuji.i2z(year)
|
176
|
+
when :Ok then Kansuji.i2k(year)
|
177
|
+
when :i then imperial_year
|
178
|
+
when :I then Kansuji.i2z(imperial_year)
|
179
|
+
when :Ik then Kansuji.i2k(imperial_year)
|
180
|
+
when :s then month
|
181
|
+
when :S then Kansuji.i2z(month)
|
182
|
+
when :Sk then Kansuji.i2k(month)
|
183
|
+
when :SK then Utils.alt_month_name(month)
|
184
|
+
when :l then leap_month? ? "'" : ''
|
185
|
+
when :L then leap_month? ? '’' : ''
|
186
|
+
when :Lk then leap_month? ? '閏' : ''
|
187
|
+
when :d then day
|
188
|
+
when :D then Kansuji.i2z(day)
|
189
|
+
when :Dk then Kansuji.i2k(day)
|
194
190
|
when :DK
|
195
191
|
if month == 1 && !leap_month? && day == 1
|
196
|
-
|
192
|
+
'元'
|
197
193
|
elsif day == 1
|
198
|
-
|
194
|
+
'朔'
|
199
195
|
elsif day == Utils.last_day_of_month(year, month, leap_month?)
|
200
|
-
|
196
|
+
'晦'
|
201
197
|
else
|
202
|
-
|
198
|
+
Kansuji.i2k(day)
|
203
199
|
end
|
204
|
-
when :m
|
205
|
-
when :M
|
206
|
-
when :Mk
|
207
|
-
when :y
|
208
|
-
when :Y
|
209
|
-
when :Yk
|
210
|
-
when :YK
|
211
|
-
when :f
|
212
|
-
when :F
|
213
|
-
else
|
214
|
-
nil
|
200
|
+
when :m then "#{format(:s)}#{format(:l)}"
|
201
|
+
when :M then "#{format(:Lk)}#{format(:S)}"
|
202
|
+
when :Mk then "#{format(:Lk)}#{format(:Sk)}"
|
203
|
+
when :y then "#{format(:e)}#{format(:g)}"
|
204
|
+
when :Y then "#{format(:e)}#{format(:G)}"
|
205
|
+
when :Yk then "#{format(:e)}#{format(:Gk)}"
|
206
|
+
when :YK then "#{format(:e)}#{format(:GK)}"
|
207
|
+
when :f then "#{format(:e)}#{format(:g)}年#{format(:s)}#{format(:l)}月#{format(:d)}日"
|
208
|
+
when :F then "#{format(:e)}#{format(:GK)}年#{format(:Lk)}#{format(:Sk)}月#{format(:Dk)}日"
|
215
209
|
end
|
216
210
|
end
|
217
211
|
|
218
212
|
def eql?(other)
|
219
213
|
begin
|
220
|
-
[
|
214
|
+
%i[year month day era_year era_name leap_month?].each do |attr|
|
221
215
|
other.public_send(attr) == public_send(attr) or return false
|
222
216
|
end
|
223
|
-
rescue
|
217
|
+
rescue NoMethodError, NotImplementedError
|
224
218
|
return false
|
225
219
|
end
|
226
220
|
true
|
227
221
|
end
|
228
|
-
|
222
|
+
alias == eql?
|
229
223
|
|
230
224
|
def ===(other)
|
231
225
|
begin
|
232
226
|
other.jd == jd or return false
|
233
|
-
rescue
|
227
|
+
rescue NoMethodError, NotImplementedError
|
234
228
|
return false
|
235
229
|
end
|
236
230
|
true
|
@@ -245,8 +239,8 @@ module Wareki
|
|
245
239
|
end
|
246
240
|
|
247
241
|
def _to_jd_for_calc(other)
|
248
|
-
other.class.to_s ==
|
249
|
-
raise NotImplementedError,
|
242
|
+
other.class.to_s == 'ActiveSupport::Duration' and
|
243
|
+
raise NotImplementedError, 'Date calcration with ActiveSupport::Duration currently is not supported. Please use numeric.'
|
250
244
|
other.respond_to?(:to_date) and other = other.to_date
|
251
245
|
other.respond_to?(:jd) and other = other.jd
|
252
246
|
other
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Wareki
|
2
|
+
# Utilities of kansuji/integer converter.
|
3
|
+
module Kansuji
|
4
|
+
UNIT_SUFFIX1 = {
|
5
|
+
'千' => 1000,
|
6
|
+
'百' => 100,
|
7
|
+
'十' => 10,
|
8
|
+
'' => 1,
|
9
|
+
}.freeze
|
10
|
+
UNIT_SUFFIX2 = {
|
11
|
+
'京' => 10_000_000_000_000_000,
|
12
|
+
'兆' => 1_000_000_000_000,
|
13
|
+
'億' => 100_000_000,
|
14
|
+
'万' => 10_000,
|
15
|
+
'' => 1,
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
module_function
|
19
|
+
|
20
|
+
def kan_to_i(str)
|
21
|
+
ret3 = 0
|
22
|
+
ret4 = 0
|
23
|
+
curnum = nil
|
24
|
+
str == '零' and return 0
|
25
|
+
str.to_s.each_char do |c|
|
26
|
+
case c
|
27
|
+
when '正', '元', '朔',
|
28
|
+
'一', '二', '三', '四', '五', '六', '七', '八', '九', '肆',
|
29
|
+
'1', '2', '3', '4', '5', '6', '7', '8', '9',
|
30
|
+
'1', '2', '3', '4', '5', '6', '7', '8', '9'
|
31
|
+
if curnum
|
32
|
+
curnum *= 10
|
33
|
+
else
|
34
|
+
curnum = 0
|
35
|
+
end
|
36
|
+
curnum += c.tr('一二三四五六七八九123456789肆元朔正', '1234567891234567894111').to_i
|
37
|
+
when '〇', '0', '0'
|
38
|
+
curnum and curnum *= 10
|
39
|
+
when '卄', '廿'
|
40
|
+
ret3 += 20
|
41
|
+
curnum = nil
|
42
|
+
when '卅', '丗'
|
43
|
+
ret3 += 30
|
44
|
+
curnum = nil
|
45
|
+
when '卌'
|
46
|
+
ret3 += 40
|
47
|
+
curnum = nil
|
48
|
+
when '皕'
|
49
|
+
ret3 += 200
|
50
|
+
curnum = nil
|
51
|
+
when '万', '億', '兆', '京', '垓'
|
52
|
+
if curnum
|
53
|
+
ret3 += curnum
|
54
|
+
curnum = nil
|
55
|
+
end
|
56
|
+
ret3 = 1 if ret3.zero?
|
57
|
+
ret4 += ret3 * 10**((%w[万 億 兆 京 垓].index(c) + 1) * 4)
|
58
|
+
ret3 = 0
|
59
|
+
when '十', '百', '千'
|
60
|
+
curnum ||= 1
|
61
|
+
ret3 += curnum * 10**(%w[十 百 千].index(c) + 1)
|
62
|
+
curnum = nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
if curnum
|
66
|
+
ret3 += curnum
|
67
|
+
curnum = nil
|
68
|
+
end
|
69
|
+
ret4 + ret3
|
70
|
+
end
|
71
|
+
|
72
|
+
def i_to_kan(num)
|
73
|
+
ret = ''
|
74
|
+
UNIT_SUFFIX2.each do |unit4, rank4|
|
75
|
+
i4 = (num / rank4).to_i % 10_000
|
76
|
+
next if i4.zero?
|
77
|
+
|
78
|
+
if i4 == 1
|
79
|
+
ret += "一#{unit4}"
|
80
|
+
next
|
81
|
+
end
|
82
|
+
|
83
|
+
UNIT_SUFFIX1.each do |unit1, rank1|
|
84
|
+
i1 = (i4 / rank1).to_i % 10
|
85
|
+
next if i1.zero?
|
86
|
+
|
87
|
+
if i1 == 1 && unit1 != ''
|
88
|
+
ret += unit1
|
89
|
+
else
|
90
|
+
ret += i1.to_s.tr('123456789', '一二三四五六七八九') + unit1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
ret += unit4
|
94
|
+
end
|
95
|
+
ret
|
96
|
+
end
|
97
|
+
|
98
|
+
def i_to_zen(num)
|
99
|
+
num.to_s.tr('0123456789', '0123456789')
|
100
|
+
end
|
101
|
+
|
102
|
+
class << self
|
103
|
+
alias i2k i_to_kan
|
104
|
+
alias k2i kan_to_i
|
105
|
+
alias i2z i_to_zen
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
data/lib/wareki/std_ext.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'wareki/date'
|
3
3
|
module Wareki
|
4
|
+
# :nodoc:
|
4
5
|
module StdExt
|
5
6
|
end
|
6
7
|
end
|
8
|
+
# :nodoc:
|
7
9
|
class Date
|
8
10
|
JAPAN = Wareki::GREGORIAN_START
|
9
11
|
|
10
12
|
def to_wareki_date
|
11
|
-
Wareki::Date.jd(
|
13
|
+
Wareki::Date.jd(jd)
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
def strftime(format =
|
16
|
-
if format.index(
|
16
|
+
alias _wareki_strftime_orig strftime
|
17
|
+
def strftime(format = '%F')
|
18
|
+
if format.index('%J')
|
17
19
|
to_wareki_date.strftime(format)
|
18
20
|
else
|
19
21
|
_wareki_strftime_orig(format)
|
@@ -21,13 +23,11 @@ class Date
|
|
21
23
|
end
|
22
24
|
|
23
25
|
class << self
|
24
|
-
|
26
|
+
alias _wareki_parse_orig parse
|
25
27
|
def parse(str, comp = true, start = ::Date::ITALY)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
::Date._wareki_parse_orig(str, comp, start)
|
30
|
-
end
|
28
|
+
Wareki::Date.parse(str).to_date(start)
|
29
|
+
rescue ArgumentError, Wareki::UnsupportedDateRange
|
30
|
+
::Date._wareki_parse_orig(str, comp, start)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
data/lib/wareki/utils.rb
CHANGED
@@ -1,107 +1,17 @@
|
|
1
|
-
# coding: utf-8
|
2
1
|
module Wareki
|
2
|
+
# Static utility methods.
|
3
3
|
module Utils
|
4
|
-
UNIT_SUFFIX1 = {
|
5
|
-
'千' => 1000,
|
6
|
-
'百' => 100,
|
7
|
-
'十' => 10,
|
8
|
-
'' => 1,
|
9
|
-
}
|
10
|
-
UNIT_SUFFIX2 = {
|
11
|
-
'京' => 10000000000000000,
|
12
|
-
'兆' => 1000000000000,
|
13
|
-
'億' => 100000000,
|
14
|
-
'万' => 10000,
|
15
|
-
'' => 1,
|
16
|
-
}
|
17
4
|
module_function
|
18
|
-
def kan_to_i(str)
|
19
|
-
ret3 = 0
|
20
|
-
ret4 = 0
|
21
|
-
curnum = nil
|
22
|
-
str == "零" and return 0
|
23
|
-
str.to_s.each_char do |c|
|
24
|
-
case c
|
25
|
-
when *%w(正 元 朔 一 二 三 四 五 六 七 八 九 肆 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9)
|
26
|
-
if curnum
|
27
|
-
curnum *= 10
|
28
|
-
else
|
29
|
-
curnum = 0
|
30
|
-
end
|
31
|
-
curnum += c.tr("一二三四五六七八九123456789肆元朔正", "1234567891234567894111").to_i
|
32
|
-
when "〇", "0", "0"
|
33
|
-
curnum and curnum *= 10
|
34
|
-
when "卄", "廿"
|
35
|
-
ret3 += 20
|
36
|
-
curnum = nil
|
37
|
-
when "卅", "丗"
|
38
|
-
ret3 += 30
|
39
|
-
curnum = nil
|
40
|
-
when "卌"
|
41
|
-
ret3 += 40
|
42
|
-
curnum = nil
|
43
|
-
when "皕"
|
44
|
-
ret3 += 200
|
45
|
-
curnum = nil
|
46
|
-
when "万", "億", "兆", "京", "垓"
|
47
|
-
if curnum
|
48
|
-
ret3 += curnum
|
49
|
-
curnum = nil
|
50
|
-
end
|
51
|
-
ret3 = 1 if ret3 == 0
|
52
|
-
ret4 += ret3 * 10 ** ((["万", "億", "兆", "京", "垓"].index(c)+1)*4)
|
53
|
-
ret3 = 0
|
54
|
-
when "十", "百", "千"
|
55
|
-
curnum ||= 1
|
56
|
-
ret3 += curnum * 10 ** (["十", "百", "千"].index(c)+1)
|
57
|
-
curnum = nil
|
58
|
-
end
|
59
|
-
end
|
60
|
-
if curnum
|
61
|
-
ret3 += curnum
|
62
|
-
curnum = nil
|
63
|
-
end
|
64
|
-
ret4 + ret3
|
65
|
-
end
|
66
|
-
|
67
|
-
def i_to_kan(num, opts = {})
|
68
|
-
ret = ''
|
69
|
-
UNIT_SUFFIX2.each do |unit4, rank4|
|
70
|
-
i4 = (num / rank4).to_i % 10000
|
71
|
-
if i4 == 0
|
72
|
-
next
|
73
|
-
elsif i4 == 1
|
74
|
-
ret += "一#{unit4}"
|
75
|
-
next
|
76
|
-
end
|
77
|
-
UNIT_SUFFIX1.each do |unit1, rank1|
|
78
|
-
i1 = (i4 / rank1).to_i % 10
|
79
|
-
if i1 == 0
|
80
|
-
next
|
81
|
-
elsif i1 == 1 && unit1 != ""
|
82
|
-
ret += unit1
|
83
|
-
else
|
84
|
-
ret += i1.to_s.tr('123456789', '一二三四五六七八九') + unit1
|
85
|
-
end
|
86
|
-
end
|
87
|
-
ret += unit4
|
88
|
-
end
|
89
|
-
ret
|
90
|
-
end
|
91
|
-
|
92
|
-
def i_to_zen(num)
|
93
|
-
num.to_s.tr('0123456789', '0123456789')
|
94
|
-
end
|
95
5
|
|
96
6
|
def last_day_of_month(year, month, is_leap)
|
97
7
|
if year >= GREGORIAN_START_YEAR
|
98
|
-
_last_day_of_month_gregorian(year, month
|
8
|
+
_last_day_of_month_gregorian(year, month)
|
99
9
|
else
|
100
10
|
_last_day_of_month_from_defs(year, month, is_leap)
|
101
11
|
end
|
102
12
|
end
|
103
13
|
|
104
|
-
def _last_day_of_month_gregorian(year, month
|
14
|
+
def _last_day_of_month_gregorian(year, month)
|
105
15
|
tmp_y = year
|
106
16
|
tmp_m = month
|
107
17
|
if month == 12
|
@@ -110,16 +20,14 @@ module Wareki
|
|
110
20
|
else
|
111
21
|
tmp_m += 1
|
112
22
|
end
|
113
|
-
(::Date.new(tmp_y, tmp_m, 1, ::Date::GREGORIAN)-1).day
|
23
|
+
(::Date.new(tmp_y, tmp_m, 1, ::Date::GREGORIAN) - 1).day
|
114
24
|
end
|
115
25
|
|
116
26
|
def _last_day_of_month_from_defs(year, month, is_leap)
|
117
27
|
yobj = YEAR_BY_NUM[year] or
|
118
|
-
raise UnsupportedDateRange, "Cannot find year #{
|
28
|
+
raise UnsupportedDateRange, "Cannot find year #{inspect}"
|
119
29
|
month_idx = month - 1
|
120
|
-
if is_leap || yobj.leap_month && yobj.leap_month < month
|
121
|
-
month_idx += 1
|
122
|
-
end
|
30
|
+
month_idx += 1 if is_leap || yobj.leap_month && yobj.leap_month < month
|
123
31
|
yobj.month_days[month_idx]
|
124
32
|
end
|
125
33
|
|
@@ -133,9 +41,9 @@ module Wareki
|
|
133
41
|
end
|
134
42
|
|
135
43
|
def _to_date(d)
|
136
|
-
if d.
|
44
|
+
if d.is_a? ::Date
|
137
45
|
d # nothing to do
|
138
|
-
elsif d.
|
46
|
+
elsif d.is_a?(Time)
|
139
47
|
d.to_date
|
140
48
|
else
|
141
49
|
::Date.jd(d.to_i)
|
@@ -143,9 +51,9 @@ module Wareki
|
|
143
51
|
end
|
144
52
|
|
145
53
|
def _to_jd(d)
|
146
|
-
if d.
|
54
|
+
if d.is_a? ::Date
|
147
55
|
d.jd
|
148
|
-
elsif d.
|
56
|
+
elsif d.is_a?(Time)
|
149
57
|
d.to_date.jd
|
150
58
|
else
|
151
59
|
d.to_i
|
@@ -159,32 +67,31 @@ module Wareki
|
|
159
67
|
|
160
68
|
yobj = find_year(d) or raise UnsupportedDateRange, "Unsupported date: #{d.inspect}"
|
161
69
|
month = 0
|
162
|
-
is_leap = false
|
163
70
|
if yobj.month_starts.last <= d.jd
|
164
71
|
month = yobj.month_starts.count
|
165
72
|
else
|
166
|
-
month = yobj.month_starts.find_index {|m| d.jd <= (m - 1) }
|
73
|
+
month = yobj.month_starts.find_index { |m| d.jd <= (m - 1) }
|
167
74
|
end
|
168
|
-
month_start = yobj.month_starts[month-1]
|
75
|
+
month_start = yobj.month_starts[month - 1]
|
169
76
|
is_leap = (yobj.leap_month == (month - 1))
|
170
77
|
yobj.leap_month && yobj.leap_month < month and
|
171
78
|
month -= 1
|
172
|
-
[yobj.year, month, d.jd - month_start +1, is_leap]
|
79
|
+
[yobj.year, month, d.jd - month_start + 1, is_leap]
|
173
80
|
end
|
174
81
|
|
175
82
|
def find_year(d)
|
176
83
|
jd = _to_jd(d)
|
177
|
-
YEAR_DEFS.bsearch{|y| y.end >= jd }
|
84
|
+
YEAR_DEFS.bsearch { |y| y.end >= jd }
|
178
85
|
end
|
179
86
|
|
180
87
|
def find_era(d)
|
181
88
|
jd = _to_jd(d)
|
182
|
-
ERA_DEFS.reverse_each
|
89
|
+
ERA_DEFS.reverse_each do |e|
|
183
90
|
e.start > jd and next
|
184
91
|
e.end < jd and next
|
185
92
|
return e
|
186
|
-
|
187
|
-
|
93
|
+
end
|
94
|
+
nil
|
188
95
|
end
|
189
96
|
end
|
190
97
|
end
|
data/lib/wareki/version.rb
CHANGED
metadata
CHANGED
@@ -1,59 +1,60 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wareki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tatsuki Sugiura
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
|
-
- - "
|
16
|
+
- - ">="
|
18
17
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
-
|
18
|
+
version: '0'
|
19
|
+
name: bundler
|
21
20
|
prerelease: false
|
21
|
+
type: :development
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
30
|
- - "~>"
|
32
31
|
- !ruby/object:Gem::Version
|
33
32
|
version: '10.0'
|
34
|
-
|
33
|
+
name: rake
|
35
34
|
prerelease: false
|
35
|
+
type: :development
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
44
|
- - ">="
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: '0'
|
48
|
-
|
47
|
+
name: rspec
|
49
48
|
prerelease: false
|
49
|
+
type: :development
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description:
|
56
|
-
|
55
|
+
description: |
|
56
|
+
Pure ruby library of Wareki (Japanese calendar date) that supports string parsing,
|
57
|
+
formatting, and bi-directional convertion with standard Date class.
|
57
58
|
email:
|
58
59
|
- sugi@nemui.org
|
59
60
|
executables: []
|
@@ -68,6 +69,7 @@ files:
|
|
68
69
|
- lib/wareki/common.rb
|
69
70
|
- lib/wareki/date.rb
|
70
71
|
- lib/wareki/era_def.rb
|
72
|
+
- lib/wareki/kansuji.rb
|
71
73
|
- lib/wareki/std_ext.rb
|
72
74
|
- lib/wareki/utils.rb
|
73
75
|
- lib/wareki/version.rb
|
@@ -75,7 +77,7 @@ homepage: https://github.com/sugi/wareki
|
|
75
77
|
licenses:
|
76
78
|
- BSD
|
77
79
|
metadata: {}
|
78
|
-
post_install_message:
|
80
|
+
post_install_message:
|
79
81
|
rdoc_options: []
|
80
82
|
require_paths:
|
81
83
|
- lib
|
@@ -90,9 +92,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
92
|
- !ruby/object:Gem::Version
|
91
93
|
version: '0'
|
92
94
|
requirements: []
|
93
|
-
rubyforge_project:
|
94
|
-
rubygems_version: 2.
|
95
|
-
signing_key:
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.7.6
|
97
|
+
signing_key:
|
96
98
|
specification_version: 4
|
97
99
|
summary: Pure ruby library of Wareki (Japanese calendar date)
|
98
100
|
test_files: []
|