wareki 1.1.0 → 2.1.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/lib/wareki/utils.rb CHANGED
@@ -5,6 +5,10 @@ require 'ya_kansuji'
5
5
  module Wareki
6
6
  # Static utility methods.
7
7
  module Utils
8
+ TIME_FORMAT_DIRECTIVE_REGEX = /%J(-|[_0]{0,2}[0-9]*|)(T(?:[fF]|[HMS]k?))/.freeze
9
+ TIME_FORMAT_EXPANSION_REGEX = /(?<!%)(?:%%)*\K#{TIME_FORMAT_DIRECTIVE_REGEX}/.freeze
10
+ SIMPLE_KANSUJI_CACHE = (0..99).map { |num| YaKansuji.to_kan(num, :simple).freeze }.freeze
11
+
8
12
  module_function
9
13
 
10
14
  def last_day_of_month(year, month, is_leap)
@@ -16,23 +20,42 @@ module Wareki
16
20
  end
17
21
 
18
22
  def _last_day_of_month_gregorian(year, month)
19
- tmp_y = year
20
- tmp_m = month
21
- if month == 12
22
- tmp_y += 1
23
- tmp_m = 1
24
- else
25
- tmp_m += 1
26
- end
27
- (::Date.new(tmp_y, tmp_m, 1, ::Date::GREGORIAN) - 1).day
23
+ ::Date.new(year, month, -1, ::Date::GREGORIAN).day
28
24
  end
29
25
 
30
26
  def _last_day_of_month_from_defs(year, month, is_leap)
31
- yobj = YEAR_BY_NUM[year] or
32
- raise UnsupportedDateRange, "Cannot find year #{inspect}"
33
- month_idx = month - 1
34
- month_idx += 1 if is_leap || yobj.leap_month && yobj.leap_month < month
35
- yobj.month_days[month_idx]
27
+ Calendar.last_day_of_month(year, month, is_leap) or
28
+ raise UnsupportedDateRange, "Cannot find year #{year}"
29
+ end
30
+
31
+ def era_year_to_civil(era_name, era_year)
32
+ era_name = era_name.to_s
33
+ return era_year if ['', '西暦'].include?(era_name)
34
+ return -era_year if era_name == '紀元前'
35
+ return era_year + IMPERIAL_START_YEAR if IMPERIAL_ERA_NAMES.include?(era_name)
36
+
37
+ era = ERA_BY_NAME[era_name] or
38
+ raise ArgumentError, "Undefined era '#{era_name}'"
39
+ era.year + era_year - 1
40
+ end
41
+
42
+ def civil_to_era_year(era_name, year)
43
+ era_name = era_name.to_s
44
+ return year if ['', '西暦'].include?(era_name)
45
+ return -year if era_name == '紀元前'
46
+ return year - IMPERIAL_START_YEAR if IMPERIAL_ERA_NAMES.include?(era_name)
47
+
48
+ era = ERA_BY_NAME[era_name] or
49
+ raise ArgumentError, "Undefined era '#{era_name}'"
50
+ year - era.year + 1
51
+ end
52
+
53
+ def last_day_of_era_month(era_name, civil_year, month, is_leap)
54
+ if WESTERN_ERA_NAMES.include?(era_name.to_s)
55
+ ::Date.new(civil_year, month, -1, ::Date::ITALY).day
56
+ else
57
+ last_day_of_month(civil_year, month, is_leap)
58
+ end
36
59
  end
37
60
 
38
61
  def alt_month_name_to_i(name)
@@ -69,23 +92,8 @@ module Wareki
69
92
  d.jd >= GREGORIAN_START and
70
93
  return [d.year, d.month, d.day, false]
71
94
 
72
- yobj = find_year(d) or raise UnsupportedDateRange, "Unsupported date: #{d.inspect}"
73
- month = 0
74
- if yobj.month_starts.last <= d.jd
75
- month = yobj.month_starts.count
76
- else
77
- month = yobj.month_starts.find_index { |m| d.jd <= (m - 1) }
78
- end
79
- month_start = yobj.month_starts[month - 1]
80
- is_leap = (yobj.leap_month == (month - 1))
81
- yobj.leap_month && yobj.leap_month < month and
82
- month -= 1
83
- [yobj.year, month, d.jd - month_start + 1, is_leap]
84
- end
85
-
86
- def find_year(d)
87
- jd = _to_jd(d)
88
- YEAR_DEFS.bsearch { |y| y.end >= jd }
95
+ Calendar.find_date_ary(d.jd) or
96
+ raise UnsupportedDateRange, "Unsupported date: #{d.inspect}"
89
97
  end
90
98
 
91
99
  def find_era(d)
@@ -111,6 +119,65 @@ module Wareki
111
119
  end
112
120
  end
113
121
 
122
+ def to_simple_kan(num)
123
+ return SIMPLE_KANSUJI_CACHE[num].dup if
124
+ num.is_a?(Integer) && num >= 0 && num < SIMPLE_KANSUJI_CACHE.length
125
+
126
+ YaKansuji.to_kan(num, :simple)
127
+ end
128
+
129
+ # 日本語の時刻表記 (漢数字・全角数字の時分秒、午前/午後、半、正午) を
130
+ # 等価な "HH:MM(:SS)" 表記へ置換する。値の範囲チェックは行わず、
131
+ # 妥当性判断は Ruby 標準パーサに委ねる (二十五時 -> "25:00")。
132
+ def normalize_time(str)
133
+ str.to_s =~ TIME_PARSE_QUICK_FILTER or return str
134
+ str.to_s.sub(TIME_REGEX) { _time_match_to_s(Regexp.last_match) }
135
+ end
136
+
137
+ def _time_match_to_s(match)
138
+ return '12:00' if match[:noon]
139
+
140
+ hour = k2i(match[:hour])
141
+ hour += 12 if match[:ampm] == '午後' && hour < 12
142
+ min = 0
143
+ min = 30 if match[:half]
144
+ min = k2i(match[:min]) if match[:min]
145
+ return Kernel.format('%<hour>02d:%<min>02d', hour: hour, min: min) unless match[:sec]
146
+
147
+ Kernel.format('%<hour>02d:%<min>02d:%<sec>02d', hour: hour, min: min, sec: k2i(match[:sec]))
148
+ end
149
+
150
+ def number_format(opt)
151
+ case opt
152
+ when '', '0', '_0' then '%02d'
153
+ when '-' then '%d'
154
+ when /_\Z/ then '%2d'
155
+ when /0?_/ then "%#{opt.sub(/0?_/, '')}d"
156
+ when /_?0/ then "%#{opt.sub(/_?0/, '0')}d"
157
+ else "%0#{opt}d"
158
+ end
159
+ end
160
+
161
+ def expand_time_format(format_str, time)
162
+ format_str.to_str.gsub(TIME_FORMAT_EXPANSION_REGEX) { _format_time_directive($2, $1, time) || $& }
163
+ end
164
+
165
+ def _format_time_directive(key, opt, time)
166
+ case key.to_sym
167
+ when :Tf
168
+ nf = number_format(opt)
169
+ Kernel.format("#{nf}時#{nf}分#{nf}秒", time.hour, time.min, time.sec)
170
+ when :TF
171
+ "#{to_simple_kan(time.hour)}時#{to_simple_kan(time.min)}分#{to_simple_kan(time.sec)}秒"
172
+ when :TH then i2z(time.hour)
173
+ when :THk then to_simple_kan(time.hour)
174
+ when :TM then i2z(time.min)
175
+ when :TMk then to_simple_kan(time.min)
176
+ when :TS then i2z(time.sec)
177
+ when :TSk then to_simple_kan(time.sec)
178
+ end
179
+ end
180
+
114
181
  # DEPRECATED
115
182
  def kan_to_i(*args)
116
183
  warn '[DEPRECATED] Wareki::Utils.kan_to_i: Please use ya_kansuji gem to handle kansuji'
@@ -120,7 +187,7 @@ module Wareki
120
187
  # DEPRECATED
121
188
  def i_to_kan(*args)
122
189
  warn '[DEPRECATED] Wareki::Utils.i_to_kan: Please use ya_kansuji gem to handle kansuji'
123
- i2k(*args)
190
+ YaKansuji.to_kan(*args)
124
191
  end
125
192
  end
126
193
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wareki
4
- VERSION = '1.1.0'
4
+ VERSION = '2.1.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wareki
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.1.0
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: 2019-12-23 00:00:00.000000000 Z
11
+ date: 2026-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ya_kansuji
@@ -30,48 +30,6 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 2.0.0
33
- - !ruby/object:Gem::Dependency
34
- name: bundler
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '1.9'
40
- type: :development
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: '1.9'
47
- - !ruby/object:Gem::Dependency
48
- name: rake
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '10.0'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- version: '10.0'
61
- - !ruby/object:Gem::Dependency
62
- name: rspec
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: '0'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: '0'
75
33
  description: |
76
34
  Pure ruby library of Wareki (Japanese calendar date) that supports string parsing,
77
35
  formatting, and bi-directional convertion with standard Date class.
@@ -85,6 +43,7 @@ files:
85
43
  - LICENSE
86
44
  - README.md
87
45
  - lib/wareki.rb
46
+ - lib/wareki/calendar.rb
88
47
  - lib/wareki/calendar_def.rb
89
48
  - lib/wareki/common.rb
90
49
  - lib/wareki/date.rb
@@ -95,9 +54,10 @@ files:
95
54
  - lib/wareki/version.rb
96
55
  homepage: https://github.com/sugi/wareki
97
56
  licenses:
98
- - BSD
99
- metadata: {}
100
- post_install_message:
57
+ - BSD-2-Clause
58
+ metadata:
59
+ rubygems_mfa_required: 'true'
60
+ post_install_message:
101
61
  rdoc_options: []
102
62
  require_paths:
103
63
  - lib
@@ -105,16 +65,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
65
  requirements:
106
66
  - - ">="
107
67
  - !ruby/object:Gem::Version
108
- version: 2.0.0
68
+ version: 2.3.0
109
69
  required_rubygems_version: !ruby/object:Gem::Requirement
110
70
  requirements:
111
71
  - - ">="
112
72
  - !ruby/object:Gem::Version
113
73
  version: '0'
114
74
  requirements: []
115
- rubyforge_project:
116
- rubygems_version: 2.7.6.2
117
- signing_key:
75
+ rubygems_version: 3.1.6
76
+ signing_key:
118
77
  specification_version: 4
119
78
  summary: Pure ruby library of Wareki (Japanese calendar date)
120
79
  test_files: []