when_exe 0.4.0 → 0.4.1
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 +4 -4
- data/README.md +333 -212
- data/bin/make_ttl.rb +37 -0
- data/bin/make_ttl.rb.config +9 -0
- data/lib/when_exe.rb +923 -925
- data/lib/when_exe/calendarnote.rb +9 -5
- data/lib/when_exe/coordinates.rb +2437 -2446
- data/lib/when_exe/inspect.rb +1480 -1408
- data/lib/when_exe/linkeddata.rb +574 -0
- data/lib/when_exe/locales/akt.rb +177 -176
- data/lib/when_exe/locales/locale.rb +751 -751
- data/lib/when_exe/mini_application.rb +307 -307
- data/lib/when_exe/parts/resource.rb +1115 -1103
- data/lib/when_exe/region/chinese/epochs.rb +6 -5
- data/lib/when_exe/region/christian.rb +831 -829
- data/lib/when_exe/region/japanese.rb +93 -93
- data/lib/when_exe/region/japanese/notes.rb +1510 -1495
- data/lib/when_exe/region/japanese/residues.rb +13 -13
- data/lib/when_exe/tmposition.rb +2307 -2273
- data/lib/when_exe/tmreference.rb +1744 -1734
- data/lib/when_exe/version.rb +2 -2
- data/link_to_online_documents +1 -1
- data/test/scripts/3.ext.rb +6 -6
- data/test/scripts/3.rb +6 -6
- data/test/test.rb +76 -75
- data/test/test/icalendar.rb +883 -879
- data/test/test/linkeddata.rb +224 -0
- data/test/test/region/m17n.rb +193 -193
- data/when_exe.gemspec +3 -2
- metadata +13 -6
@@ -1,307 +1,307 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
=begin
|
3
|
-
Copyright (C) 2013-
|
4
|
-
|
5
|
-
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
-
=end
|
7
|
-
|
8
|
-
require 'socket'
|
9
|
-
|
10
|
-
#
|
11
|
-
# Time for v1.8.x compatibility
|
12
|
-
#
|
13
|
-
class Time
|
14
|
-
if Time.now.respond_to?(:strftime) && Time.now.strftime('%FT%X.%L').length > 0
|
15
|
-
alias :_log_ :strftime
|
16
|
-
else
|
17
|
-
def _log_(format)
|
18
|
-
"%04d-%02d-%02dT%02d:%02d:%02d.%03d" % [year, month, day, hour, min, sec, usec / 1000]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
#
|
24
|
-
# Micro Client / Server
|
25
|
-
#
|
26
|
-
module When
|
27
|
-
class << self
|
28
|
-
|
29
|
-
#
|
30
|
-
# 設定ファイルを読み込む
|
31
|
-
# @private
|
32
|
-
def config(path=File.expand_path($0) + '.config')
|
33
|
-
config = {}
|
34
|
-
open(path, 'r') do |file|
|
35
|
-
while (line=file.gets)
|
36
|
-
next if line =~ /\A\s*#/
|
37
|
-
key, *value = line.chomp.split(':')
|
38
|
-
value = value[0] if value.size <= 1
|
39
|
-
config[key] = value
|
40
|
-
end
|
41
|
-
end
|
42
|
-
config
|
43
|
-
rescue
|
44
|
-
{}
|
45
|
-
end
|
46
|
-
|
47
|
-
#
|
48
|
-
# マイクロ・サーバーを起動する
|
49
|
-
#
|
50
|
-
# @param [#to_i] port 待ち受けるポート番号
|
51
|
-
#
|
52
|
-
# @return [void]
|
53
|
-
#
|
54
|
-
# @note mini_application
|
55
|
-
#
|
56
|
-
def server(port)
|
57
|
-
config = When.config
|
58
|
-
TCPServer.open(port.to_i) do |socket|
|
59
|
-
puts Time.now._log_('%FT%X.%L') + ': Start'
|
60
|
-
loop do
|
61
|
-
Thread.start(socket.accept) do |client|
|
62
|
-
query = client.gets.chomp.force_encoding("UTF-8")
|
63
|
-
start = Time.now
|
64
|
-
puts start._log_('%FT%X.%L') + ': Query - ' + When::Locale.translate(query, config['!'])
|
65
|
-
begin
|
66
|
-
result = free_conv(*query.split(/\s+/))
|
67
|
-
result = When::Locale.translate(result, config['!'])
|
68
|
-
client.puts JSON.generate(Array(_to_string(result))).to_s
|
69
|
-
stop = Time.now
|
70
|
-
puts stop._log_('%FT%X.%L') + ": Respond (%7.0f ms)" % (1000 * (stop.to_f - start.to_f))
|
71
|
-
rescue => err
|
72
|
-
puts Time.now._log_('%FT%X.%L') + ': error - ' + err.to_s
|
73
|
-
client.puts JSON.generate({:error=>query}).to_s
|
74
|
-
end
|
75
|
-
client.close
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
rescue Exception => e
|
80
|
-
puts Time.now._log_('%FT%X.%L') + ': Exception - ' + e.to_s
|
81
|
-
ensure
|
82
|
-
puts Time.now._log_('%FT%X.%L') + ': Done.'
|
83
|
-
end
|
84
|
-
|
85
|
-
#
|
86
|
-
# マイクロ・クライアントを実行する
|
87
|
-
#
|
88
|
-
# @param [String] server マイクロ・サーバのアドレス
|
89
|
-
# @param [#to_i] port つなぐポート番号
|
90
|
-
# @param [String] query 問い合わせ文字列
|
91
|
-
#
|
92
|
-
# @return [JSON] 応答
|
93
|
-
#
|
94
|
-
# @note mini_application
|
95
|
-
#
|
96
|
-
def client(server, port, query)
|
97
|
-
TCPSocket.open(server, port.to_i) do |socket|
|
98
|
-
socket.puts(query)
|
99
|
-
results = JSON.parse(socket.gets.force_encoding("UTF-8"))
|
100
|
-
results = Hash[*results.flatten(1)] if results[0].kind_of?(Array)
|
101
|
-
_to_symbol(results)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# 日付の自由変換
|
106
|
-
#
|
107
|
-
# @param [Array<String, When::TM::TemporalPosition, When::TM::CalendarEra or When::TM::Calendar>] args コマンドライン入力
|
108
|
-
# @param [Block] block ブロック
|
109
|
-
#
|
110
|
-
# @return [Array<Hash>] 変換結果
|
111
|
-
# @return [Array<Array<Numeric>>] 最良近似分数列
|
112
|
-
#
|
113
|
-
# @note 暦法のIRI, When.exe Standard Expression, 最良近似分数列の分母分子などを文字列で指定
|
114
|
-
# @note mini_application
|
115
|
-
#
|
116
|
-
def free_conv(*args, &block)
|
117
|
-
calendars, dates, numbers, methods, output, options = _parse_command(args)
|
118
|
-
|
119
|
-
if numbers.size >= 2 && calendars.size == 0
|
120
|
-
result = []
|
121
|
-
When::Coordinates::Residue.new(numbers[0], numbers[1]).each { |v| result << v }
|
122
|
-
return result
|
123
|
-
end
|
124
|
-
|
125
|
-
block ||=
|
126
|
-
if methods.size == 0
|
127
|
-
lambda {|date| date.send(*output)}
|
128
|
-
else
|
129
|
-
lambda {|date, type| column(date, type)}
|
130
|
-
end
|
131
|
-
_free_conv(calendars, dates, methods, output, options, &block)
|
132
|
-
end
|
133
|
-
|
134
|
-
# 七曜表の一日分
|
135
|
-
#
|
136
|
-
# @param [When::TM::TemporalPosition] date 処理する一日
|
137
|
-
# @param [Integer, nil] type 当該日の種類
|
138
|
-
#
|
139
|
-
# @return [Object>] 処理結果
|
140
|
-
#
|
141
|
-
def column(date, type)
|
142
|
-
case type
|
143
|
-
when When::YEAR ; date.strftime("%Y")
|
144
|
-
when When::MONTH ; date.strftime("%B %Y")
|
145
|
-
when When::WEEK ; nil
|
146
|
-
when When::DAY ; date[0]
|
147
|
-
else ; '-'
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
private
|
152
|
-
|
153
|
-
# to_h メソッドのオプション設定
|
154
|
-
HashMethod = {:iri => [:to_h, {:method=>:iri , :prefix=>true}],
|
155
|
-
:to_m17n => [:to_h, {:method=>:to_m17n, :prefix=>true}]}
|
156
|
-
|
157
|
-
# 引数読み込み
|
158
|
-
#
|
159
|
-
# args [String] コマンドライン入力
|
160
|
-
#
|
161
|
-
# @return [Array] ( calendars, dates, numbers, methods )
|
162
|
-
# [ calendars [Array<When::TM::Calendar or When::TM::CalendarEra>]]
|
163
|
-
# [ dates [Array<When::TM::CalData or When::TM::DateAndTime>] ]
|
164
|
-
# [ numbers [Array<Numeric>]]
|
165
|
-
# [ methods [Array<String>] メソッド名('week', 'month', 'year') ]
|
166
|
-
# [ output [Array<Symbol, String>] 出力処理に使うメソッドのシンボルと引数 ]
|
167
|
-
# [ options [Hash{ :extent=>Boolean, :go_back=><:All || :Before(nil) || :After> }]
|
168
|
-
#
|
169
|
-
def _parse_command(args)
|
170
|
-
calendars = []
|
171
|
-
dates = []
|
172
|
-
numbers = []
|
173
|
-
methods = []
|
174
|
-
options = {}
|
175
|
-
output = [:to_s]
|
176
|
-
|
177
|
-
config = When.config
|
178
|
-
args.flatten.each do |arg|
|
179
|
-
case arg
|
180
|
-
when Numeric ; dates << arg ; numbers << arg
|
181
|
-
when Hash ; options.update(arg)
|
182
|
-
when Range ; arg.each {|d| dates << d}
|
183
|
-
when Symbol ; output = [arg]
|
184
|
-
when When::TM::CalendarEra,
|
185
|
-
When::TM::Calendar ; calendars << arg
|
186
|
-
when String
|
187
|
-
arg = When::EncodingConversion.to_internal_encoding(arg)
|
188
|
-
case arg
|
189
|
-
when /\A:(.+?)(?:\[(..)\])?\z/ ; output = [$1.to_sym, $2].compact
|
190
|
-
when /\A(year|month|week)(?:\[(..)\])?\z/i ; methods << [$1.downcase + '_included', $2||'SU']
|
191
|
-
when /\A[-+\d]\d*\z/ ; dates << arg.to_i ; numbers << arg.to_i
|
192
|
-
when /\A[-+.\d][.\d]*\z/ ; dates << arg.to_f ; numbers << arg.to_f
|
193
|
-
when /\Anow\z/i ; dates << When.now
|
194
|
-
when /\Atoday\z/i ; dates << When.today
|
195
|
-
when /(^[-+\d])|\^/ ; dates << arg
|
196
|
-
when /\A\//
|
197
|
-
arg[1..-1].scan(/./) do |c|
|
198
|
-
c = c.upcase
|
199
|
-
if config.key?(c)
|
200
|
-
calendar = config[c]
|
201
|
-
calendar = calendar.join(':') if calendar.kind_of?(Array)
|
202
|
-
calendars << When.Calendar(calendar)
|
203
|
-
elsif c == 'D'
|
204
|
-
calendars << When::TM::JulianDate
|
205
|
-
end
|
206
|
-
end
|
207
|
-
else
|
208
|
-
begin
|
209
|
-
calendars << ((arg == 'JulianDate') ? When::TM::JulianDate : When.Calendar(arg))
|
210
|
-
rescue NameError, OpenURI::HTTPError
|
211
|
-
dates << arg
|
212
|
-
end
|
213
|
-
end
|
214
|
-
else
|
215
|
-
dates << arg
|
216
|
-
end
|
217
|
-
end
|
218
|
-
[calendars, dates, numbers, methods, HashMethod[output[0]] || output, options]
|
219
|
-
end
|
220
|
-
|
221
|
-
# 変換処理(実行部)
|
222
|
-
#
|
223
|
-
# @param [When::TM::Calendar, When::TM::CalendarEra] calendars
|
224
|
-
# @param [When::TM::CalData, When::TM::DateAndTime] dates
|
225
|
-
# @param [String] methods メソッド名('week', 'month', 'year')
|
226
|
-
# @param [Hash] options {:extent=>Boolean, :go_back=><:All||:Before(nil)||:After>}
|
227
|
-
#
|
228
|
-
# @return [Array] 変換結果
|
229
|
-
#
|
230
|
-
def _free_conv(calendars, dates, methods, output, options, &block)
|
231
|
-
dates[0] ||= When.now
|
232
|
-
calendars[0] ||= When::Gregorian
|
233
|
-
result = dates.map {|date|
|
234
|
-
date = When.when?(date)
|
235
|
-
opts = {}
|
236
|
-
opts[:location] = date.location if date.location
|
237
|
-
opts[:clock ] = date.clock if date.respond_to?(:clock) && date.clock
|
238
|
-
list = calendars.dup
|
239
|
-
(0...calendars.size).to_a.reverse.each do |i|
|
240
|
-
case list[i]
|
241
|
-
when When::TM::Calendar ; list.slice!(i) if options[:extent] && !list[i].domain[''].include?(date)
|
242
|
-
when Class ;
|
243
|
-
else
|
244
|
-
eras = (date ^ list[i]).delete_if {|e| !e.leaf?}
|
245
|
-
unless options[:go_back] == :All
|
246
|
-
if options[:go_back] == :After
|
247
|
-
eras = [eras[(eras.index {|e| e.
|
248
|
-
else
|
249
|
-
eras.delete_if {|e| e.
|
250
|
-
end
|
251
|
-
end
|
252
|
-
list[i,1] = eras.map {|e| e.calendar_era}
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
if methods.size == 0
|
257
|
-
list.map {|calendar|
|
258
|
-
calendar.kind_of?(Class) ?
|
259
|
-
yield(calendar.new(date, opts.dup)) :
|
260
|
-
yield(calendar.^(calendar.rate_of_clock == date.time_standard.rate_of_clock ? date.to_i : date, opts))
|
261
|
-
}
|
262
|
-
else
|
263
|
-
list.map {|calendar|
|
264
|
-
date_for_calendar = calendar.^(calendar.rate_of_clock == date.time_standard.rate_of_clock ? date.to_i : date, opts)
|
265
|
-
methods.map {|method|
|
266
|
-
date_for_calendar.send(method[0].to_sym, method[1], &block)
|
267
|
-
}
|
268
|
-
}
|
269
|
-
end
|
270
|
-
}
|
271
|
-
result = result[0] while result.kind_of?(Array) && result.size == 1
|
272
|
-
return result
|
273
|
-
end
|
274
|
-
|
275
|
-
# JSONで通信するために Symbol を String に変換する
|
276
|
-
def _to_string(source)
|
277
|
-
case source
|
278
|
-
when Array
|
279
|
-
source.map {|e| _to_string(e)}
|
280
|
-
when Hash
|
281
|
-
result = {}
|
282
|
-
source.each_pair {|k,v|
|
283
|
-
result[k.kind_of?(Symbol) ? '_sym_' + k.to_s : k] = _to_string(v)
|
284
|
-
}
|
285
|
-
result
|
286
|
-
else
|
287
|
-
source
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
# JSONで通信するために String を Symbol に変換する
|
292
|
-
def _to_symbol(source)
|
293
|
-
case source
|
294
|
-
when Array
|
295
|
-
source.map {|e| _to_symbol(e)}
|
296
|
-
when Hash
|
297
|
-
result = {}
|
298
|
-
source.each_pair {|k,v|
|
299
|
-
result[k =~ /\A_sym_(.+)\z/ ? $1.to_sym : k] = _to_symbol(v)
|
300
|
-
}
|
301
|
-
result
|
302
|
-
else
|
303
|
-
source
|
304
|
-
end
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
Copyright (C) 2013-2015 Takashi SUGA
|
4
|
+
|
5
|
+
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
6
|
+
=end
|
7
|
+
|
8
|
+
require 'socket'
|
9
|
+
|
10
|
+
#
|
11
|
+
# Time for v1.8.x compatibility
|
12
|
+
#
|
13
|
+
class Time
|
14
|
+
if Time.now.respond_to?(:strftime) && Time.now.strftime('%FT%X.%L').length > 0
|
15
|
+
alias :_log_ :strftime
|
16
|
+
else
|
17
|
+
def _log_(format)
|
18
|
+
"%04d-%02d-%02dT%02d:%02d:%02d.%03d" % [year, month, day, hour, min, sec, usec / 1000]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Micro Client / Server
|
25
|
+
#
|
26
|
+
module When
|
27
|
+
class << self
|
28
|
+
|
29
|
+
#
|
30
|
+
# 設定ファイルを読み込む
|
31
|
+
# @private
|
32
|
+
def config(path=File.expand_path($0) + '.config')
|
33
|
+
config = {}
|
34
|
+
open(path, 'r') do |file|
|
35
|
+
while (line=file.gets)
|
36
|
+
next if line =~ /\A\s*#/
|
37
|
+
key, *value = line.chomp.split(':')
|
38
|
+
value = value[0] if value.size <= 1
|
39
|
+
config[key] = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
config
|
43
|
+
rescue
|
44
|
+
{}
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# マイクロ・サーバーを起動する
|
49
|
+
#
|
50
|
+
# @param [#to_i] port 待ち受けるポート番号
|
51
|
+
#
|
52
|
+
# @return [void]
|
53
|
+
#
|
54
|
+
# @note mini_application
|
55
|
+
#
|
56
|
+
def server(port)
|
57
|
+
config = When.config
|
58
|
+
TCPServer.open(port.to_i) do |socket|
|
59
|
+
puts Time.now._log_('%FT%X.%L') + ': Start'
|
60
|
+
loop do
|
61
|
+
Thread.start(socket.accept) do |client|
|
62
|
+
query = client.gets.chomp.force_encoding("UTF-8")
|
63
|
+
start = Time.now
|
64
|
+
puts start._log_('%FT%X.%L') + ': Query - ' + When::Locale.translate(query, config['!'])
|
65
|
+
begin
|
66
|
+
result = free_conv(*query.split(/\s+/))
|
67
|
+
result = When::Locale.translate(result, config['!'])
|
68
|
+
client.puts JSON.generate(Array(_to_string(result))).to_s
|
69
|
+
stop = Time.now
|
70
|
+
puts stop._log_('%FT%X.%L') + ": Respond (%7.0f ms)" % (1000 * (stop.to_f - start.to_f))
|
71
|
+
rescue => err
|
72
|
+
puts Time.now._log_('%FT%X.%L') + ': error - ' + err.to_s
|
73
|
+
client.puts JSON.generate({:error=>query}).to_s
|
74
|
+
end
|
75
|
+
client.close
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
rescue Exception => e
|
80
|
+
puts Time.now._log_('%FT%X.%L') + ': Exception - ' + e.to_s
|
81
|
+
ensure
|
82
|
+
puts Time.now._log_('%FT%X.%L') + ': Done.'
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# マイクロ・クライアントを実行する
|
87
|
+
#
|
88
|
+
# @param [String] server マイクロ・サーバのアドレス
|
89
|
+
# @param [#to_i] port つなぐポート番号
|
90
|
+
# @param [String] query 問い合わせ文字列
|
91
|
+
#
|
92
|
+
# @return [JSON] 応答
|
93
|
+
#
|
94
|
+
# @note mini_application
|
95
|
+
#
|
96
|
+
def client(server, port, query)
|
97
|
+
TCPSocket.open(server, port.to_i) do |socket|
|
98
|
+
socket.puts(query)
|
99
|
+
results = JSON.parse(socket.gets.force_encoding("UTF-8"))
|
100
|
+
results = Hash[*results.flatten(1)] if results[0].kind_of?(Array)
|
101
|
+
_to_symbol(results)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# 日付の自由変換
|
106
|
+
#
|
107
|
+
# @param [Array<String, When::TM::TemporalPosition, When::TM::CalendarEra or When::TM::Calendar>] args コマンドライン入力
|
108
|
+
# @param [Block] block ブロック
|
109
|
+
#
|
110
|
+
# @return [Array<Hash>] 変換結果
|
111
|
+
# @return [Array<Array<Numeric>>] 最良近似分数列
|
112
|
+
#
|
113
|
+
# @note 暦法のIRI, When.exe Standard Expression, 最良近似分数列の分母分子などを文字列で指定
|
114
|
+
# @note mini_application
|
115
|
+
#
|
116
|
+
def free_conv(*args, &block)
|
117
|
+
calendars, dates, numbers, methods, output, options = _parse_command(args)
|
118
|
+
|
119
|
+
if numbers.size >= 2 && calendars.size == 0
|
120
|
+
result = []
|
121
|
+
When::Coordinates::Residue.new(numbers[0], numbers[1]).each { |v| result << v }
|
122
|
+
return result
|
123
|
+
end
|
124
|
+
|
125
|
+
block ||=
|
126
|
+
if methods.size == 0
|
127
|
+
lambda {|date| date.send(*output)}
|
128
|
+
else
|
129
|
+
lambda {|date, type| column(date, type)}
|
130
|
+
end
|
131
|
+
_free_conv(calendars, dates, methods, output, options, &block)
|
132
|
+
end
|
133
|
+
|
134
|
+
# 七曜表の一日分
|
135
|
+
#
|
136
|
+
# @param [When::TM::TemporalPosition] date 処理する一日
|
137
|
+
# @param [Integer, nil] type 当該日の種類
|
138
|
+
#
|
139
|
+
# @return [Object>] 処理結果
|
140
|
+
#
|
141
|
+
def column(date, type)
|
142
|
+
case type
|
143
|
+
when When::YEAR ; date.strftime("%Y")
|
144
|
+
when When::MONTH ; date.strftime("%B %Y")
|
145
|
+
when When::WEEK ; nil
|
146
|
+
when When::DAY ; date[0]
|
147
|
+
else ; '-'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
# to_h メソッドのオプション設定
|
154
|
+
HashMethod = {:iri => [:to_h, {:method=>:iri , :prefix=>true}],
|
155
|
+
:to_m17n => [:to_h, {:method=>:to_m17n, :prefix=>true}]}
|
156
|
+
|
157
|
+
# 引数読み込み
|
158
|
+
#
|
159
|
+
# args [String] コマンドライン入力
|
160
|
+
#
|
161
|
+
# @return [Array] ( calendars, dates, numbers, methods )
|
162
|
+
# [ calendars [Array<When::TM::Calendar or When::TM::CalendarEra>]]
|
163
|
+
# [ dates [Array<When::TM::CalData or When::TM::DateAndTime>] ]
|
164
|
+
# [ numbers [Array<Numeric>]]
|
165
|
+
# [ methods [Array<String>] メソッド名('week', 'month', 'year') ]
|
166
|
+
# [ output [Array<Symbol, String>] 出力処理に使うメソッドのシンボルと引数 ]
|
167
|
+
# [ options [Hash{ :extent=>Boolean, :go_back=><:All || :Before(nil) || :After> }]
|
168
|
+
#
|
169
|
+
def _parse_command(args)
|
170
|
+
calendars = []
|
171
|
+
dates = []
|
172
|
+
numbers = []
|
173
|
+
methods = []
|
174
|
+
options = {}
|
175
|
+
output = [:to_s]
|
176
|
+
|
177
|
+
config = When.config
|
178
|
+
args.flatten.each do |arg|
|
179
|
+
case arg
|
180
|
+
when Numeric ; dates << arg ; numbers << arg
|
181
|
+
when Hash ; options.update(arg)
|
182
|
+
when Range ; arg.each {|d| dates << d}
|
183
|
+
when Symbol ; output = [arg]
|
184
|
+
when When::TM::CalendarEra,
|
185
|
+
When::TM::Calendar ; calendars << arg
|
186
|
+
when String
|
187
|
+
arg = When::EncodingConversion.to_internal_encoding(arg)
|
188
|
+
case arg
|
189
|
+
when /\A:(.+?)(?:\[(..)\])?\z/ ; output = [$1.to_sym, $2].compact
|
190
|
+
when /\A(year|month|week)(?:\[(..)\])?\z/i ; methods << [$1.downcase + '_included', $2||'SU']
|
191
|
+
when /\A[-+\d]\d*\z/ ; dates << arg.to_i ; numbers << arg.to_i
|
192
|
+
when /\A[-+.\d][.\d]*\z/ ; dates << arg.to_f ; numbers << arg.to_f
|
193
|
+
when /\Anow\z/i ; dates << When.now
|
194
|
+
when /\Atoday\z/i ; dates << When.today
|
195
|
+
when /(^[-+\d])|\^/ ; dates << arg
|
196
|
+
when /\A\//
|
197
|
+
arg[1..-1].scan(/./) do |c|
|
198
|
+
c = c.upcase
|
199
|
+
if config.key?(c)
|
200
|
+
calendar = config[c]
|
201
|
+
calendar = calendar.join(':') if calendar.kind_of?(Array)
|
202
|
+
calendars << When.Calendar(calendar)
|
203
|
+
elsif c == 'D'
|
204
|
+
calendars << When::TM::JulianDate
|
205
|
+
end
|
206
|
+
end
|
207
|
+
else
|
208
|
+
begin
|
209
|
+
calendars << ((arg == 'JulianDate') ? When::TM::JulianDate : When.Calendar(arg))
|
210
|
+
rescue NameError, OpenURI::HTTPError
|
211
|
+
dates << arg
|
212
|
+
end
|
213
|
+
end
|
214
|
+
else
|
215
|
+
dates << arg
|
216
|
+
end
|
217
|
+
end
|
218
|
+
[calendars, dates, numbers, methods, HashMethod[output[0]] || output, options]
|
219
|
+
end
|
220
|
+
|
221
|
+
# 変換処理(実行部)
|
222
|
+
#
|
223
|
+
# @param [When::TM::Calendar, When::TM::CalendarEra] calendars
|
224
|
+
# @param [When::TM::CalData, When::TM::DateAndTime] dates
|
225
|
+
# @param [String] methods メソッド名('week', 'month', 'year')
|
226
|
+
# @param [Hash] options {:extent=>Boolean, :go_back=><:All||:Before(nil)||:After>}
|
227
|
+
#
|
228
|
+
# @return [Array] 変換結果
|
229
|
+
#
|
230
|
+
def _free_conv(calendars, dates, methods, output, options, &block)
|
231
|
+
dates[0] ||= When.now
|
232
|
+
calendars[0] ||= When::Gregorian
|
233
|
+
result = dates.map {|date|
|
234
|
+
date = When.when?(date)
|
235
|
+
opts = {}
|
236
|
+
opts[:location] = date.location if date.location
|
237
|
+
opts[:clock ] = date.clock if date.respond_to?(:clock) && date.clock
|
238
|
+
list = calendars.dup
|
239
|
+
(0...calendars.size).to_a.reverse.each do |i|
|
240
|
+
case list[i]
|
241
|
+
when When::TM::Calendar ; list.slice!(i) if options[:extent] && !list[i].domain[''].include?(date)
|
242
|
+
when Class ;
|
243
|
+
else
|
244
|
+
eras = (date ^ list[i]).delete_if {|e| !e.leaf?}
|
245
|
+
unless options[:go_back] == :All
|
246
|
+
if options[:go_back] == :After
|
247
|
+
eras = [eras[(eras.index {|e| e.calendar_era_go_back}) || -1]]
|
248
|
+
else
|
249
|
+
eras.delete_if {|e| e.calendar_era_go_back}
|
250
|
+
end
|
251
|
+
end
|
252
|
+
list[i,1] = eras.map {|e| e.calendar_era}
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
if methods.size == 0
|
257
|
+
list.map {|calendar|
|
258
|
+
calendar.kind_of?(Class) ?
|
259
|
+
yield(calendar.new(date, opts.dup)) :
|
260
|
+
yield(calendar.^(calendar.rate_of_clock == date.time_standard.rate_of_clock ? date.to_i : date, opts))
|
261
|
+
}
|
262
|
+
else
|
263
|
+
list.map {|calendar|
|
264
|
+
date_for_calendar = calendar.^(calendar.rate_of_clock == date.time_standard.rate_of_clock ? date.to_i : date, opts)
|
265
|
+
methods.map {|method|
|
266
|
+
date_for_calendar.send(method[0].to_sym, method[1], &block)
|
267
|
+
}
|
268
|
+
}
|
269
|
+
end
|
270
|
+
}
|
271
|
+
result = result[0] while result.kind_of?(Array) && result.size == 1
|
272
|
+
return result
|
273
|
+
end
|
274
|
+
|
275
|
+
# JSONで通信するために Symbol を String に変換する
|
276
|
+
def _to_string(source)
|
277
|
+
case source
|
278
|
+
when Array
|
279
|
+
source.map {|e| _to_string(e)}
|
280
|
+
when Hash
|
281
|
+
result = {}
|
282
|
+
source.each_pair {|k,v|
|
283
|
+
result[k.kind_of?(Symbol) ? '_sym_' + k.to_s : k] = _to_string(v)
|
284
|
+
}
|
285
|
+
result
|
286
|
+
else
|
287
|
+
source
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
# JSONで通信するために String を Symbol に変換する
|
292
|
+
def _to_symbol(source)
|
293
|
+
case source
|
294
|
+
when Array
|
295
|
+
source.map {|e| _to_symbol(e)}
|
296
|
+
when Hash
|
297
|
+
result = {}
|
298
|
+
source.each_pair {|k,v|
|
299
|
+
result[k =~ /\A_sym_(.+)\z/ ? $1.to_sym : k] = _to_symbol(v)
|
300
|
+
}
|
301
|
+
result
|
302
|
+
else
|
303
|
+
source
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|