when_exe 0.3.2 → 0.3.3
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/LICENSE.ja.txt +25 -25
- data/LICENSE.txt +31 -31
- data/bin/locales.rb +2 -1
- data/bin/when.rb.config +1 -1
- data/lib/when_exe.rb +70 -48
- data/lib/when_exe/basictypes.rb +99 -65
- data/lib/when_exe/calendartypes.rb +40 -178
- data/lib/when_exe/coordinates.rb +156 -62
- data/lib/when_exe/core/compatibility.rb +10 -0
- data/lib/when_exe/core/extension.rb +40 -0
- data/lib/when_exe/ephemeris.rb +112 -50
- data/lib/when_exe/icalendar.rb +125 -91
- data/lib/when_exe/inspect.rb +100 -48
- data/lib/when_exe/locales/ar.rb +48 -48
- data/lib/when_exe/locales/bg.rb +1 -1
- data/lib/when_exe/locales/bs.rb +4 -2
- data/lib/when_exe/locales/ca.rb +1 -1
- data/lib/when_exe/locales/en_CA.rb +3 -4
- data/lib/when_exe/locales/en_IE.rb +88 -0
- data/lib/when_exe/locales/en_US.rb +87 -0
- data/lib/when_exe/locales/es_CR.rb +84 -0
- data/lib/when_exe/locales/es_EC.rb +85 -0
- data/lib/when_exe/locales/es_PA.rb +85 -0
- data/lib/when_exe/locales/fr.rb +39 -39
- data/lib/when_exe/locales/hu.rb +15 -14
- data/lib/when_exe/locales/it.rb +1 -1
- data/lib/when_exe/locales/ja.rb +2 -2
- data/lib/when_exe/locales/locales.rb +7 -0
- data/lib/when_exe/locales/lt.rb +21 -19
- data/lib/when_exe/locales/ms.rb +84 -0
- data/lib/when_exe/locales/nl.rb +2 -2
- data/lib/when_exe/locales/ru.rb +1 -1
- data/lib/when_exe/locales/uk.rb +1 -1
- data/lib/when_exe/locales/ur.rb +84 -0
- data/lib/when_exe/mini_application.rb +44 -43
- data/lib/when_exe/parts/enumerator.rb +3 -3
- data/lib/when_exe/parts/geometric_complex.rb +6 -1
- data/lib/when_exe/parts/locale.rb +49 -18
- data/lib/when_exe/parts/method_cash.rb +61 -0
- data/lib/when_exe/parts/resource.rb +221 -106
- data/lib/when_exe/parts/timezone.rb +70 -33
- data/lib/when_exe/region/bahai.rb +2 -2
- data/lib/when_exe/region/balinese.rb +40 -43
- data/lib/when_exe/region/chinese.rb +93 -33
- data/lib/when_exe/region/chinese_calendar.rb +117 -1
- data/lib/when_exe/region/chinese_epoch.rb +65 -10
- data/lib/when_exe/region/christian.rb +97 -2
- data/lib/when_exe/region/ephemeric_notes.rb +353 -0
- data/lib/when_exe/region/french.rb +1 -1
- data/lib/when_exe/region/geologicalage.rb +171 -171
- data/lib/when_exe/region/indian.rb +18 -14
- data/lib/when_exe/region/iranian.rb +1 -1
- data/lib/when_exe/region/japanese.rb +49 -12
- data/lib/when_exe/region/japanese_notes.rb +838 -507
- data/lib/when_exe/region/japanese_residues.rb +724 -662
- data/lib/when_exe/region/javanese.rb +7 -7
- data/lib/when_exe/region/mayan.rb +19 -17
- data/lib/when_exe/region/nihon_shoki.rb +3 -3
- data/lib/when_exe/region/residue.rb +29 -28
- data/lib/when_exe/region/shire.rb +2 -2
- data/lib/when_exe/region/tibetan.rb +87 -5
- data/lib/when_exe/region/world.rb +1 -1
- data/lib/when_exe/timestandard.rb +85 -7
- data/lib/when_exe/tmobjects.rb +32 -4
- data/lib/when_exe/tmposition.rb +104 -55
- data/lib/when_exe/tmreference.rb +157 -60
- data/lib/when_exe/version.rb +2 -2
- data/test/examples/JapanHolidays.ics +3 -3
- data/test/examples/JapanHolidaysRFC6350.ics +499 -0
- data/test/examples/Residue.m17n +3 -2
- data/test/examples/Spatial.m17n +3 -3
- data/test/examples/USA-DST.ics +27 -27
- data/test/examples/today.rb +1 -1
- data/test/test.rb +4 -2
- data/test/test/basictypes.rb +40 -15
- data/test/test/coordinates.rb +9 -4
- data/test/test/icalendar.rb +24 -14
- data/test/test/inspect.rb +5 -3
- data/test/test/parts.rb +11 -2
- data/test/test/region/chinese.rb +4 -4
- data/test/test/region/civil.rb +124 -0
- data/test/test/region/geologicalage.rb +5 -2
- data/test/test/region/indian.rb +2 -0
- data/test/test/region/japanese.rb +156 -1
- data/test/test/region/jewish.rb +3 -3
- data/test/test/region/m17n.rb +9 -9
- data/test/test/region/mayan.rb +122 -5
- data/test/test/region/residue.rb +1 -1
- data/test/test/tmobjects.rb +27 -64
- data/test/test/tmposition.rb +48 -1
- data/test/test/tmreference.rb +66 -4
- data/when_exe.gemspec +1 -1
- metadata +15 -6
data/lib/when_exe/icalendar.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
=begin
|
|
3
|
-
Copyright (C) 2011-
|
|
3
|
+
Copyright (C) 2011-2014 Takashi SUGA
|
|
4
4
|
|
|
5
5
|
You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
|
|
6
6
|
=end
|
|
@@ -86,7 +86,7 @@ module When::V
|
|
|
86
86
|
|
|
87
87
|
#
|
|
88
88
|
# iCalendar クラス群の属性
|
|
89
|
-
# @return [Hash] { String => When::Parts::Resource::
|
|
89
|
+
# @return [Hash] { String => When::Parts::Resource::ContentLine }
|
|
90
90
|
#
|
|
91
91
|
attr_reader :property
|
|
92
92
|
|
|
@@ -128,9 +128,27 @@ module When::V
|
|
|
128
128
|
raise ArgumentError, "No enumerator exists" if (enumerators.length==0)
|
|
129
129
|
|
|
130
130
|
# Enumerator の生成
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
enumerator =
|
|
132
|
+
if (enumerators.length==1 && exdate.node.size==0)
|
|
133
|
+
enumerators[0]
|
|
134
|
+
else
|
|
135
|
+
options[:exdate] = exdate
|
|
136
|
+
When::Parts::Enumerator::Integrated.new(self, enumerators, *args)
|
|
137
|
+
end
|
|
138
|
+
if ::Object.const_defined?(:Date) && (args[0].kind_of?(Range) ? args[0].first : args[0]).kind_of?(::Date)
|
|
139
|
+
enumerator.instance_eval %Q{
|
|
140
|
+
alias :_succ_of_super :succ
|
|
141
|
+
def succ
|
|
142
|
+
result = _succ_of_super
|
|
143
|
+
case result
|
|
144
|
+
when When::TM::DateAndTime ; result.to_date_time
|
|
145
|
+
when When::TM::CalDate ; result.to_date
|
|
146
|
+
else ; result
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
}
|
|
150
|
+
end
|
|
151
|
+
enumerator
|
|
134
152
|
end
|
|
135
153
|
alias :to_enum :_enumerator
|
|
136
154
|
alias :enum_for :_enumerator
|
|
@@ -147,7 +165,14 @@ module When::V
|
|
|
147
165
|
@_pool['..'] = options['..']
|
|
148
166
|
|
|
149
167
|
# parsed 部の属性化
|
|
150
|
-
|
|
168
|
+
@property = {}
|
|
169
|
+
@namespace = @_pool['..'].respond_to?(:namespace) ? @_pool['..'].namespace : {}
|
|
170
|
+
if options['.']
|
|
171
|
+
_parse_from_file(options)
|
|
172
|
+
else
|
|
173
|
+
_parse_from_code(options)
|
|
174
|
+
end
|
|
175
|
+
_set_variables
|
|
151
176
|
|
|
152
177
|
# 属性の存在チェック & 設定
|
|
153
178
|
_initialize_attributes(_attribute_appearance(self.class::Properties)) # .const_get(:Properties)))
|
|
@@ -156,29 +181,47 @@ module When::V
|
|
|
156
181
|
_child(options, self.class::Classes) #.const_get(:Classes))
|
|
157
182
|
end
|
|
158
183
|
|
|
159
|
-
#
|
|
160
|
-
def
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
184
|
+
# ファイルからの属性読み込み
|
|
185
|
+
def _parse_from_file(options)
|
|
186
|
+
options['.'].each do |v|
|
|
187
|
+
v = When::Parts::Resource._parse(v)
|
|
188
|
+
_parse_altid(@property, v) if v.kind_of?(ContentLine)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
keys = @property.keys
|
|
192
|
+
if keys.delete('namespace')
|
|
193
|
+
content = @property['namespace'][0]
|
|
194
|
+
@property['namespace'] = content if @property['namespace'].size == 1
|
|
195
|
+
if content.attribute['prefix']
|
|
196
|
+
begin
|
|
197
|
+
@namespace[content.attribute['prefix'].object] = content.object
|
|
198
|
+
end while (content = content.same_altid)
|
|
199
|
+
else
|
|
200
|
+
@namespace.update(When::Parts::Locale._namespace(content.object))
|
|
172
201
|
end
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
keys.each do |key|
|
|
205
|
+
@property[key].each do |content|
|
|
206
|
+
content.object = When::BasicTypes::M17n.new(content, @namespace, []) if content.same_altid
|
|
176
207
|
end
|
|
177
|
-
@property[
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
208
|
+
@property[key] = @property[key][0] if @property[key].size == 1
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# コードからの属性読み込み
|
|
213
|
+
def _parse_from_code(options)
|
|
214
|
+
options.each_pair do |key, value|
|
|
215
|
+
@property[key] = ContentLine.new(key, value) if key.kind_of?(String)
|
|
181
216
|
end
|
|
217
|
+
@property['dtstamp'] ||= ContentLine.new('dtstamp',
|
|
218
|
+
When.now.to_s.gsub(/[-:]/,'')) if self.class::Properties[0].index('dtstamp')
|
|
219
|
+
@property['uid'] ||= ContentLine.new('uid',
|
|
220
|
+
@property['dtstamp'].object + '-auto') if self.class::Properties[0].index('uid')
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# @propertyの個別属性化
|
|
224
|
+
def _set_variables
|
|
182
225
|
@property.each_key do |key|
|
|
183
226
|
next if respond_to?(key)
|
|
184
227
|
instance_eval %Q{
|
|
@@ -220,7 +263,7 @@ module When::V
|
|
|
220
263
|
|
|
221
264
|
# REQUIRED but MUST NOT occur more than once
|
|
222
265
|
require_unique.each do |key|
|
|
223
|
-
unless @property[key].kind_of?(When::Parts::Resource::
|
|
266
|
+
unless @property[key].kind_of?(When::Parts::Resource::ContentLine)
|
|
224
267
|
raise ArgumentError, "The #{key.upcase.gsub(/_/,'-')} is REQUIRED but MUST NOT occur more than once"
|
|
225
268
|
end
|
|
226
269
|
end
|
|
@@ -230,7 +273,7 @@ module When::V
|
|
|
230
273
|
unless @property[key]
|
|
231
274
|
raise ArgumentError, "The #{key.upcase.gsub(/_/,'-')} is REQUIRED and MAY occur more than once"
|
|
232
275
|
end
|
|
233
|
-
@property[key] = [@property[key]] if (@property[key].kind_of?(When::Parts::Resource::
|
|
276
|
+
@property[key] = [@property[key]] if (@property[key].kind_of?(When::Parts::Resource::ContentLine))
|
|
234
277
|
end
|
|
235
278
|
|
|
236
279
|
# OPTIONAL but MUST NOT occur more than once
|
|
@@ -249,7 +292,7 @@ module When::V
|
|
|
249
292
|
|
|
250
293
|
# OPTIONAL and MAY occur more than once
|
|
251
294
|
(optional + DefaultOptional).each do |key|
|
|
252
|
-
@property[key] = [@property[key]] if (@property[key].kind_of?(When::Parts::Resource::
|
|
295
|
+
@property[key] = [@property[key]] if (@property[key].kind_of?(When::Parts::Resource::ContentLine))
|
|
253
296
|
end
|
|
254
297
|
|
|
255
298
|
# Other Properties
|
|
@@ -269,10 +312,6 @@ module When::V
|
|
|
269
312
|
@calscale = @property['calscale'].object if @property['calscale']
|
|
270
313
|
@calscale = When.Resource((@calscale||'GREGORIAN').capitalize, '_c:') unless (@calscale.kind_of?(When::TM::Calendar))
|
|
271
314
|
|
|
272
|
-
# namespace の登録
|
|
273
|
-
@namespace = @_pool['..'].respond_to?(:namespace) ? @_pool['..'].namespace : {}
|
|
274
|
-
@namespace.update(When::Parts::Locale._namespace(@property['namespace'].object)) if @property['namespace']
|
|
275
|
-
|
|
276
315
|
# locale の登録
|
|
277
316
|
@locale = @_pool['..'].respond_to?(:locale) ? @_pool['..'].locale : []
|
|
278
317
|
@locale = When::Parts::Locale._locale(@property['locale'].object) if @property['locale']
|
|
@@ -367,7 +406,7 @@ module When::V
|
|
|
367
406
|
@exdate = When::Parts::GeometricComplex.new()
|
|
368
407
|
if (@property['rdate'])
|
|
369
408
|
@rdate = @property['rdate'].inject([]) do |sum, v|
|
|
370
|
-
if When::Parts::Resource::
|
|
409
|
+
if v.kind_of?(When::Parts::Resource::ContentLine)
|
|
371
410
|
if new_zone == ''
|
|
372
411
|
sum += When.when?(v.attribute['.'].split(/,/), date_options)
|
|
373
412
|
else
|
|
@@ -388,7 +427,7 @@ module When::V
|
|
|
388
427
|
# exdate の登録
|
|
389
428
|
if @property['exdate']
|
|
390
429
|
dates = @property['exdate'].inject([]) do |sum, v|
|
|
391
|
-
if When::Parts::Resource::
|
|
430
|
+
if v.kind_of?(When::Parts::Resource::ContentLine)
|
|
392
431
|
sum += When.when?(v.attribute['.'].split(/,/), date_options)
|
|
393
432
|
else
|
|
394
433
|
sum << v
|
|
@@ -416,7 +455,7 @@ module When::V
|
|
|
416
455
|
@freebusy = []
|
|
417
456
|
if (@property['freebusy'])
|
|
418
457
|
@freebusy = @property['freebusy'].inject([]) do |sum, v|
|
|
419
|
-
if When::Parts::Resource::
|
|
458
|
+
if v.kind_of?(When::Parts::Resource::ContentLine)
|
|
420
459
|
sum += When.when?((v.attribute['.']||v.object).split(/,/), date_options)
|
|
421
460
|
else
|
|
422
461
|
sum << v
|
|
@@ -454,8 +493,10 @@ module When::V
|
|
|
454
493
|
copy.child = @child.select {|ev|
|
|
455
494
|
if ev.kind_of?(Event)
|
|
456
495
|
keys.each_pair do |key, value|
|
|
457
|
-
|
|
458
|
-
break unless
|
|
496
|
+
case value
|
|
497
|
+
when String ; break unless ev.property[key].object.index(value)
|
|
498
|
+
when Regexp ; break unless (ev.property[key].object =~ value)
|
|
499
|
+
end
|
|
459
500
|
end
|
|
460
501
|
else
|
|
461
502
|
true
|
|
@@ -467,7 +508,7 @@ module When::V
|
|
|
467
508
|
# @private
|
|
468
509
|
def _enumerator_list(args)
|
|
469
510
|
(@child.reject {|el| !el.kind_of?(Event)}).inject([]) { |sum, ev|
|
|
470
|
-
|
|
511
|
+
sum += ev._enumerator_list(args)
|
|
471
512
|
}
|
|
472
513
|
end
|
|
473
514
|
end
|
|
@@ -517,6 +558,12 @@ module When::V
|
|
|
517
558
|
end
|
|
518
559
|
end
|
|
519
560
|
|
|
561
|
+
# SUMMARY Property
|
|
562
|
+
#
|
|
563
|
+
# @return [String, When::BasicTypes::M17n]
|
|
564
|
+
#
|
|
565
|
+
attr_reader :summary
|
|
566
|
+
|
|
520
567
|
# RRULE Property
|
|
521
568
|
#
|
|
522
569
|
# @return [Hash]
|
|
@@ -587,7 +634,7 @@ module When::V
|
|
|
587
634
|
# @return [String]
|
|
588
635
|
#
|
|
589
636
|
def label
|
|
590
|
-
@property['uid'].object
|
|
637
|
+
@label ||= @property['uid'].object
|
|
591
638
|
end
|
|
592
639
|
|
|
593
640
|
# 最後のイベント
|
|
@@ -679,7 +726,7 @@ module When::V
|
|
|
679
726
|
# ユニーク識別名 - ACTION Property をユニーク識別名とする。
|
|
680
727
|
# @return [String]
|
|
681
728
|
def label
|
|
682
|
-
@property['action'].object # TODO
|
|
729
|
+
@label ||= @property['action'].object # TODO
|
|
683
730
|
end
|
|
684
731
|
|
|
685
732
|
# @private
|
|
@@ -692,7 +739,7 @@ module When::V
|
|
|
692
739
|
_parsed(options)
|
|
693
740
|
|
|
694
741
|
# 属性の存在チェック
|
|
695
|
-
case (@property['action'].kind_of?(When::Parts::Resource::
|
|
742
|
+
case (@property['action'].kind_of?(When::Parts::Resource::ContentLine) && @property['action'].object)
|
|
696
743
|
when 'AUDIO'
|
|
697
744
|
aware = _attribute_appearance([
|
|
698
745
|
['action', 'trigger'], [],
|
|
@@ -808,7 +855,7 @@ module When::V
|
|
|
808
855
|
# ユニーク識別名 - DTSTART Property をユニーク識別名とする
|
|
809
856
|
# @return [String]
|
|
810
857
|
def label
|
|
811
|
-
@property['dtstart'].attribute['.']
|
|
858
|
+
@label ||= @property['dtstart'].attribute['.']
|
|
812
859
|
end
|
|
813
860
|
end
|
|
814
861
|
|
|
@@ -838,22 +885,12 @@ module When::V
|
|
|
838
885
|
|
|
839
886
|
class << self; include When::Parts::Resource::Pool; end
|
|
840
887
|
|
|
841
|
-
|
|
842
|
-
# @return [When::TM::Clock]
|
|
843
|
-
attr_reader :standard
|
|
844
|
-
|
|
845
|
-
# 夏時間帯の時計
|
|
846
|
-
# @return [When::TM::Clock]
|
|
847
|
-
attr_reader :daylight
|
|
848
|
-
|
|
849
|
-
# 夏時間帯と標準時間帯の時間差
|
|
850
|
-
# @return [When::TM:IntervalLength]
|
|
851
|
-
attr_reader :difference
|
|
888
|
+
include When::Parts::Timezone::Base
|
|
852
889
|
|
|
853
890
|
# ユニーク識別名 - TZID Property をユニーク識別名とする
|
|
854
891
|
# @return [String]
|
|
855
892
|
def label
|
|
856
|
-
@property['tzid'].object
|
|
893
|
+
@label ||= @property['tzid'].object
|
|
857
894
|
end
|
|
858
895
|
|
|
859
896
|
# 同一の時間帯を用いた期間
|
|
@@ -866,24 +903,21 @@ module When::V
|
|
|
866
903
|
#
|
|
867
904
|
def current_period(current_date=Time.now)
|
|
868
905
|
current_date = When.when?(current_date) unless current_date.kind_of?(When::TM::TemporalPosition)
|
|
869
|
-
period = _tz_period(current_date)
|
|
906
|
+
period = _tz_period(current_date.universal_time)
|
|
870
907
|
range = period[1]
|
|
871
908
|
return range if range.kind_of?(Range)
|
|
872
909
|
GeometricComplex.new([period], !range)
|
|
873
910
|
end
|
|
874
911
|
|
|
875
912
|
# @private
|
|
876
|
-
def _daylight(
|
|
913
|
+
def _daylight(time)
|
|
877
914
|
raise ArgumentError, "Needless daylight saving time evaluation" unless _need_validate
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
deltad = zdate.universal_time - ndate.universal_time
|
|
885
|
-
return nprop.tzoffsetto if (deltad >= 0)
|
|
886
|
-
return nprop.tzoffsetfrom
|
|
915
|
+
frame, cal_date, clk_time = time
|
|
916
|
+
time = frame.to_universal_time(cal_date, clk_time, @standard) if clk_time
|
|
917
|
+
ndate = _neighbor_event_date(time)
|
|
918
|
+
nprop = ndate.clock.tz_prop
|
|
919
|
+
time = frame.to_universal_time(cal_date, clk_time, nprop.tzoffsetfrom) if clk_time && !@standard.equal?(nprop.tzoffsetfrom)
|
|
920
|
+
(time >= ndate.universal_time) ? nprop.tzoffsetto : nprop.tzoffsetfrom
|
|
887
921
|
end
|
|
888
922
|
|
|
889
923
|
# @private
|
|
@@ -922,43 +956,42 @@ module When::V
|
|
|
922
956
|
|
|
923
957
|
# 指定の日時に最も近い、時間帯変更イベントの日時
|
|
924
958
|
#
|
|
925
|
-
# @param [
|
|
959
|
+
# @param [Numeric] current_time 捜索の基点の日時の universal time
|
|
926
960
|
#
|
|
927
961
|
# @return [When::TM::TemporalPosition] 捜索の基点の日時に最も近い、時間帯変更イベントの日時
|
|
928
962
|
#
|
|
929
|
-
def _neighbor_event_date(
|
|
930
|
-
_tz_period(
|
|
963
|
+
def _neighbor_event_date(current_time)
|
|
964
|
+
_tz_period(current_time)[0]
|
|
931
965
|
end
|
|
932
966
|
|
|
933
|
-
def _tz_period(
|
|
934
|
-
|
|
935
|
-
return [@dtstart, false] if (universal_time <= @dtstart.universal_time)
|
|
967
|
+
def _tz_period(current_time)
|
|
968
|
+
return [@dtstart, false] if (current_time <= @dtstart.universal_time)
|
|
936
969
|
return [@dtstop, true ] if (@dtstop.kind_of?(When::TimeValue) &&
|
|
937
|
-
|
|
970
|
+
current_time >= @dtstop.universal_time)
|
|
938
971
|
|
|
939
972
|
# Thread 要注意 - @range は生成後に更新
|
|
940
973
|
synchronize do
|
|
941
974
|
@range.each do |range|
|
|
942
|
-
from =
|
|
943
|
-
to = range.last.universal_time -
|
|
975
|
+
from = current_time - range.first.universal_time
|
|
976
|
+
to = range.last.universal_time - current_time
|
|
944
977
|
return [(from < to) ? range.first : range.last, range] if (from >= 0 && to > 0)
|
|
945
978
|
end
|
|
946
|
-
early = _neighbor(
|
|
947
|
-
late = _neighbor(
|
|
948
|
-
from =
|
|
949
|
-
to = late.universal_time -
|
|
979
|
+
early = _neighbor(current_time, :reverse)
|
|
980
|
+
late = _neighbor(current_time, :forward)
|
|
981
|
+
from = current_time - early.universal_time
|
|
982
|
+
to = late.universal_time - current_time
|
|
950
983
|
@range << (early...late)
|
|
951
984
|
return [(from < to) ? early : late, @range[-1]]
|
|
952
985
|
end
|
|
953
986
|
end
|
|
954
987
|
|
|
955
|
-
def _neighbor(
|
|
988
|
+
def _neighbor(current_time, direction)
|
|
956
989
|
event = nil
|
|
957
990
|
minimum = nil
|
|
958
991
|
@child.each do |prop|
|
|
959
|
-
date = prop.enum_for(
|
|
992
|
+
date = prop.enum_for(current_time, direction, 1).succ
|
|
960
993
|
if (date)
|
|
961
|
-
diff = (date -
|
|
994
|
+
diff = (date.universal_time - current_time).abs
|
|
962
995
|
if (minimum == nil || minimum > diff)
|
|
963
996
|
event = date
|
|
964
997
|
minimum = diff
|
|
@@ -1020,14 +1053,14 @@ module When::V
|
|
|
1020
1053
|
|
|
1021
1054
|
# オブジェクトの生成
|
|
1022
1055
|
def initialize(*args)
|
|
1023
|
-
@options
|
|
1024
|
-
@exdate
|
|
1025
|
-
@exevent
|
|
1056
|
+
@options = When::Parts::Enumerator._options(args)
|
|
1057
|
+
@exdate = @options.delete(:exdate)
|
|
1058
|
+
@exevent = @options.delete(:exevent)
|
|
1026
1059
|
@parent, @rule, @dtstart, @duration, *args = args
|
|
1027
|
-
@dtstart
|
|
1028
|
-
@rule
|
|
1029
|
-
@logics
|
|
1030
|
-
@tz_prop
|
|
1060
|
+
@dtstart = When.when?(@dtstart)
|
|
1061
|
+
@rule = self.class._decode_rule(@rule, @dtstart) if (@rule.kind_of?(String))
|
|
1062
|
+
@logics = @rule[:logics]
|
|
1063
|
+
@tz_prop = nil
|
|
1031
1064
|
if (@dtstart.kind_of?(When::TM::DateAndTime))
|
|
1032
1065
|
clock = @dtstart.clock
|
|
1033
1066
|
if (clock.kind_of?(When::TM::Clock) &&
|
|
@@ -1054,10 +1087,11 @@ module When::V
|
|
|
1054
1087
|
else
|
|
1055
1088
|
@interval = When::TM::PeriodDuration.new(@rule['INTERVAL'], FreqIndex[@rule['FREQ']])
|
|
1056
1089
|
end
|
|
1057
|
-
return dtstart if (
|
|
1090
|
+
return dtstart if (dtstart == target)
|
|
1058
1091
|
interval_time = (dtstart + @interval) - dtstart
|
|
1059
1092
|
return dtstart if (interval_time == 0)
|
|
1060
|
-
|
|
1093
|
+
duration = target.kind_of?(Numeric) ? target - dtstart.universal_time : (target - dtstart).duration
|
|
1094
|
+
div, mod = duration.divmod(interval_time.duration)
|
|
1061
1095
|
seed = dtstart + (@interval * div)
|
|
1062
1096
|
case @direction
|
|
1063
1097
|
when :reverse ; seed += @interval while (seed <= target)
|
data/lib/when_exe/inspect.rb
CHANGED
|
@@ -11,29 +11,30 @@ module When
|
|
|
11
11
|
#
|
|
12
12
|
# オブジェクトの内容を Hash 化
|
|
13
13
|
#
|
|
14
|
-
# @param [String, Integer] options {When::TM::TemporalPosition#
|
|
14
|
+
# @param [String, Integer] options {When::TM::TemporalPosition#_to_h}に渡す
|
|
15
15
|
# @param [Hash] options 下記のとおり
|
|
16
|
+
# @option options [Numeric] :precision 指定があれば「イベント名(イベント時刻)」出力の時刻を指定の精度に丸める
|
|
16
17
|
# @option options [Boolean] :camel true ならシンボルを camel case にする
|
|
17
18
|
# @option options [String] :locale 文字列化の locale(指定なしは M17nオブジェクトに変換)
|
|
18
19
|
# @option options [Boolean] :simple true ならIRI の先頭部分を簡約表現にする
|
|
19
20
|
# @option options [Boolean] :residue true なら Residue をそのまま出力
|
|
20
|
-
# @option options [Object] :その他 各クラス#
|
|
21
|
+
# @option options [Object] :その他 各クラス#_to_h を参照
|
|
21
22
|
#
|
|
22
23
|
# @return [Hash] (Whenモジュール内のクラスは文字列 or M17n化)
|
|
23
24
|
#
|
|
24
|
-
def
|
|
25
|
-
_m17n_form(
|
|
25
|
+
def to_h(options={})
|
|
26
|
+
_m17n_form(_to_h(options), options.kind_of?(Hash) ? options : {})
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
#
|
|
29
30
|
# オブジェクトの内容を JSON 化
|
|
30
31
|
#
|
|
31
|
-
# @param [Object] options #
|
|
32
|
+
# @param [Object] options #to_h を参照
|
|
32
33
|
#
|
|
33
|
-
# @return [String]
|
|
34
|
+
# @return [String] to_h 結果を JSON文字列化したもの
|
|
34
35
|
#
|
|
35
36
|
def _to_json(options={})
|
|
36
|
-
JSON.dump(
|
|
37
|
+
JSON.dump(to_h(options))
|
|
37
38
|
end
|
|
38
39
|
|
|
39
40
|
#
|
|
@@ -47,14 +48,14 @@ module When
|
|
|
47
48
|
#
|
|
48
49
|
# 時間位置オブジェクトの内容を Hash 化
|
|
49
50
|
#
|
|
50
|
-
# @param [Object] options #
|
|
51
|
+
# @param [Object] options #to_h を参照
|
|
51
52
|
#
|
|
52
53
|
# @return [Hash]
|
|
53
54
|
# 各クラスの HashProperty に列挙した属性のうち値が false/nil でないものを
|
|
54
55
|
# 属性 => 値
|
|
55
56
|
# とする Hash
|
|
56
57
|
#
|
|
57
|
-
def
|
|
58
|
+
def _to_h(options={})
|
|
58
59
|
hash = {}
|
|
59
60
|
self.class::HashProperty.each do |property|
|
|
60
61
|
method, skip = property
|
|
@@ -69,19 +70,20 @@ module When
|
|
|
69
70
|
#
|
|
70
71
|
# @param [Object] element 変換元
|
|
71
72
|
# @param [Hash] options 下記の通り
|
|
72
|
-
# @option options [
|
|
73
|
-
# @option options [
|
|
74
|
-
# @option options [
|
|
75
|
-
# @option options [Boolean] :
|
|
73
|
+
# @option options [Numeric] :precision 指定があれば「イベント名(イベント時刻)」出力の時刻を指定の精度に丸める
|
|
74
|
+
# @option options [Boolean] :camel true ならシンボルを camel case にする
|
|
75
|
+
# @option options [String] :locale 文字列化の locale(指定なしは M17nオブジェクトに変換)
|
|
76
|
+
# @option options [Boolean] :simple true ならIRI の先頭部分を簡約表現にする
|
|
77
|
+
# @option options [Boolean] :residue true なら Residue をそのまま出力
|
|
76
78
|
#
|
|
77
79
|
# @return [Hash, Array] 変換結果
|
|
78
80
|
#
|
|
79
81
|
# @note element.events のある日付は _event_form で変換する
|
|
80
82
|
#
|
|
81
83
|
def _m17n_form(element, options={})
|
|
82
|
-
result = element.respond_to?(:_event_form) ? element._event_form(self)
|
|
83
|
-
element.respond_to?(:_to_hash_value) ? element._to_hash_value(options)
|
|
84
|
-
element.respond_to?(:label) && element.label ? element.label
|
|
84
|
+
result = element.respond_to?(:_event_form) ? element._event_form(self, options[:precision]) :
|
|
85
|
+
element.respond_to?(:_to_hash_value) ? element._to_hash_value(options) :
|
|
86
|
+
element.respond_to?(:label) && element.label ? element.label :
|
|
85
87
|
case element
|
|
86
88
|
when Hash ; Hash[*(element.keys.inject([]) { |s, k|
|
|
87
89
|
s + [_m17n_form(k, options), _m17n_form(element[k], options)]
|
|
@@ -121,7 +123,7 @@ module When
|
|
|
121
123
|
end
|
|
122
124
|
|
|
123
125
|
#
|
|
124
|
-
#
|
|
126
|
+
# to_h のための要素生成
|
|
125
127
|
# @private
|
|
126
128
|
def _to_hash_value(options={})
|
|
127
129
|
options[:residue] ? self : to_m17n
|
|
@@ -130,7 +132,7 @@ module When
|
|
|
130
132
|
|
|
131
133
|
class Pair
|
|
132
134
|
#
|
|
133
|
-
#
|
|
135
|
+
# to_h のための要素生成
|
|
134
136
|
# @private
|
|
135
137
|
def _to_hash_value(options={})
|
|
136
138
|
to_s
|
|
@@ -319,6 +321,7 @@ module When
|
|
|
319
321
|
begin
|
|
320
322
|
date = it.next
|
|
321
323
|
end while date.to_i == dates[-1].to_i
|
|
324
|
+
date = date.to_cal_date unless date.instance_of?(TM::CalDate)
|
|
322
325
|
dates << date
|
|
323
326
|
end
|
|
324
327
|
end
|
|
@@ -326,6 +329,11 @@ module When
|
|
|
326
329
|
else
|
|
327
330
|
begun = self.floor(MONTH,DAY) + When::TM::PeriodDuration.new([0, first, 0])
|
|
328
331
|
ended = begun + When::TM::PeriodDuration.new([0, length, 0])
|
|
332
|
+
loop do
|
|
333
|
+
last = ended.prev
|
|
334
|
+
break unless last.cal_date[MONTH-1] == ended.cal_date[MONTH-1]
|
|
335
|
+
ended = last
|
|
336
|
+
end
|
|
329
337
|
if block_given?
|
|
330
338
|
(begun...ended).map do |date|
|
|
331
339
|
yield(date)
|
|
@@ -535,7 +543,7 @@ module When
|
|
|
535
543
|
# - :dynamical dynamical_time / 秒
|
|
536
544
|
# - :universal universal_time / 秒
|
|
537
545
|
#
|
|
538
|
-
def
|
|
546
|
+
def _to_h(options={})
|
|
539
547
|
hash = super.update({
|
|
540
548
|
:sdn => to_i,
|
|
541
549
|
:calendar => calendar_name,
|
|
@@ -596,9 +604,7 @@ module When
|
|
|
596
604
|
|
|
597
605
|
def _to_uri(date)
|
|
598
606
|
uri = date.gsub(/\./, '-').gsub(/%/, '@')
|
|
599
|
-
unless @calendar_era_name || @frame == When.Calendar('Gregorian')
|
|
600
|
-
uri += '^^' + @frame.iri.gsub(/\?/, '%3F').gsub('.', '@').split(/\//)[-1]
|
|
601
|
-
end
|
|
607
|
+
uri += '^^' + @frame.iri.split(/\//)[-1] unless @calendar_era_name || @frame == When.Calendar('Gregorian')
|
|
602
608
|
uri
|
|
603
609
|
end
|
|
604
610
|
private :_to_uri
|
|
@@ -772,7 +778,9 @@ module When
|
|
|
772
778
|
#
|
|
773
779
|
def to_m17n(precision=@precision)
|
|
774
780
|
time = m17n('T' + _time_to_s(precision))
|
|
775
|
-
|
|
781
|
+
if @frame
|
|
782
|
+
time += @frame.zone unless Clock.is_local_time_set? && @frame.equal?(Clock.local_time)
|
|
783
|
+
end
|
|
776
784
|
return time
|
|
777
785
|
end
|
|
778
786
|
|
|
@@ -784,7 +792,9 @@ module When
|
|
|
784
792
|
#
|
|
785
793
|
def to_s(precision=@precision)
|
|
786
794
|
time = 'T' + _time_to_s(precision)
|
|
787
|
-
|
|
795
|
+
if @frame
|
|
796
|
+
time += @frame.zone unless Clock.is_local_time_set? && @frame.equal?(Clock.local_time)
|
|
797
|
+
end
|
|
788
798
|
return time
|
|
789
799
|
end
|
|
790
800
|
|
|
@@ -846,9 +856,12 @@ module When
|
|
|
846
856
|
|
|
847
857
|
# 秒
|
|
848
858
|
digits = [precision - @clk_time.length + 1, STRING-SECOND].min
|
|
849
|
-
if digits
|
|
850
|
-
|
|
851
|
-
|
|
859
|
+
if digits == 0
|
|
860
|
+
format += "%02d"
|
|
861
|
+
elsif digits > 0
|
|
862
|
+
factor = 10**digits
|
|
863
|
+
terms[-1] = ((@clk_time[-1] + 1E-6) * factor).floor.to_f / factor # 切り捨て(10で割る丸めガードあり)
|
|
864
|
+
format += "%02.#{digits}f"
|
|
852
865
|
end
|
|
853
866
|
|
|
854
867
|
# 結果
|
|
@@ -857,7 +870,7 @@ module When
|
|
|
857
870
|
end
|
|
858
871
|
|
|
859
872
|
#
|
|
860
|
-
#
|
|
873
|
+
# to_h のための要素生成
|
|
861
874
|
# @private
|
|
862
875
|
def _to_hash_value(options={})
|
|
863
876
|
clk_time.map {|e| _m17n_form(e, options) }
|
|
@@ -923,7 +936,7 @@ module When
|
|
|
923
936
|
# - :clk_time to_clock_time の結果 ( 日, 時, 分, 秒 )
|
|
924
937
|
# - :notes Hash (の Array (の Array)) - _notes(options)
|
|
925
938
|
#
|
|
926
|
-
def
|
|
939
|
+
def _to_h(options={})
|
|
927
940
|
super.update({:cal_date=>@cal_date})
|
|
928
941
|
end
|
|
929
942
|
|
|
@@ -1090,32 +1103,37 @@ module When
|
|
|
1090
1103
|
# 多言語対応文字列化 - When.exe Standard Representation により多言語対応文字列化する
|
|
1091
1104
|
#
|
|
1092
1105
|
# @param [Integer] precision どの桁まで多言語対応文字列化するか、分解能で指定する
|
|
1106
|
+
# @param [false] round 常に切り捨てる(DateAndTimeとの互換性のためのダミーの引数)
|
|
1093
1107
|
#
|
|
1094
1108
|
# @return [When::BasicTypes::M17n]
|
|
1095
1109
|
#
|
|
1096
|
-
def to_m17n(precision=@precision)
|
|
1097
|
-
|
|
1098
|
-
date
|
|
1099
|
-
return m17n(
|
|
1100
|
-
|
|
1110
|
+
def to_m17n(precision=@precision, round=false)
|
|
1111
|
+
date = m17n(_date_to_s(precision))
|
|
1112
|
+
return date unless @calendar_era
|
|
1113
|
+
return _parent_labels.inject(m17n(@calendar_era_name[0])) {|era_name, parent|
|
|
1114
|
+
era_name.prefix(m17n(parent) + '::')
|
|
1115
|
+
} + date
|
|
1101
1116
|
end
|
|
1102
1117
|
|
|
1103
1118
|
# 文字列化 - When.exe Standard Representation により文字列化する
|
|
1104
1119
|
#
|
|
1105
1120
|
# @param [Integer] precision どの桁まで多言語対応文字列化するか、分解能で指定する
|
|
1121
|
+
# @param [false] round 常に切り捨てる(DateAndTimeとの互換性のためのダミーの引数)
|
|
1106
1122
|
#
|
|
1107
1123
|
# @return [String]
|
|
1108
1124
|
#
|
|
1109
|
-
def to_s(precision=@precision)
|
|
1110
|
-
era, = @calendar_era_name
|
|
1125
|
+
def to_s(precision=@precision, round=false)
|
|
1111
1126
|
date = _date_to_s(precision)
|
|
1112
|
-
return date unless
|
|
1113
|
-
return
|
|
1127
|
+
return date unless @calendar_era
|
|
1128
|
+
return _parent_labels.inject(@calendar_era_name[0].to_s) {|era_name, parent|
|
|
1129
|
+
parent.to_s + '::' + era_name
|
|
1130
|
+
} + date
|
|
1114
1131
|
end
|
|
1115
1132
|
|
|
1116
1133
|
# event を 文字列化 - 日時で与えられた event を文字列化する
|
|
1117
1134
|
#
|
|
1118
1135
|
# @param [When::TM::TemporalPosition] other 時系の歩度を比較する基準(nilは比較しない)
|
|
1136
|
+
# @param [Numeric] round_precision イベント名(イベント)出力の場合の時刻の丸め位置(nilなら丸めない)
|
|
1119
1137
|
#
|
|
1120
1138
|
# @return [String]
|
|
1121
1139
|
#
|
|
@@ -1124,15 +1142,36 @@ module When
|
|
|
1124
1142
|
# 日時の精度が日より細かい - イベント名(イベント時刻)
|
|
1125
1143
|
# 日時の精度が日 - イベント名(当日までの経過日数)
|
|
1126
1144
|
#
|
|
1127
|
-
def _event_form(other=nil)
|
|
1145
|
+
def _event_form(other=nil, round_precision=nil)
|
|
1128
1146
|
return to_m17n unless events
|
|
1129
|
-
return events[0] + '(' +
|
|
1147
|
+
return events[0] + '(' + _clk_time_for_inspect(round_precision).to_s(round_precision || precision)[/[:*=0-9]+/] + ')' if precision > When::DAY
|
|
1130
1148
|
return events[0] unless other
|
|
1131
1149
|
other = JulianDate.dynamical_time(other.dynamical_time,
|
|
1132
1150
|
{:time_standard=>time_standard}) unless time_standard.rate_of_clock == other.time_standard.rate_of_clock
|
|
1133
1151
|
events[0] + '(' + (other.to_i - to_i).to_s + ')'
|
|
1134
1152
|
end
|
|
1135
1153
|
|
|
1154
|
+
private
|
|
1155
|
+
|
|
1156
|
+
# 日付の年号に曖昧性がある場合の親年号の label の Array
|
|
1157
|
+
#
|
|
1158
|
+
# @return [Array<String>]
|
|
1159
|
+
#
|
|
1160
|
+
def _parent_labels
|
|
1161
|
+
return [] unless (area = When::TM::CalendarEra[nil]) &&
|
|
1162
|
+
(period = area[nil])
|
|
1163
|
+
list = []
|
|
1164
|
+
era = @calendar_era
|
|
1165
|
+
while (labels = period[era.label.to_s]) &&
|
|
1166
|
+
(epoch = labels[era.epoch_year]) &&
|
|
1167
|
+
(epoch.size > 1) &&
|
|
1168
|
+
(parent = era.parent).respond_to?(:epoch_year)
|
|
1169
|
+
list << parent.label
|
|
1170
|
+
era = parent
|
|
1171
|
+
end
|
|
1172
|
+
list
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1136
1175
|
# 日付の年号以外の部分を文字列化する
|
|
1137
1176
|
#
|
|
1138
1177
|
# @param [Integer] precision どの桁まで多言語対応文字列化するか、分解能で指定する
|
|
@@ -1144,23 +1183,23 @@ module When
|
|
|
1144
1183
|
precision = [precision, 1 - @cal_date.length].max
|
|
1145
1184
|
precision = [precision, DAY].min
|
|
1146
1185
|
terms = []
|
|
1147
|
-
|
|
1186
|
+
ext_dg = [(@extra_year_digits||1).to_i, 0].max
|
|
1148
1187
|
|
|
1149
1188
|
# 年
|
|
1150
1189
|
year_by_epoch = @cal_date[0]
|
|
1151
|
-
if
|
|
1190
|
+
if @calendar_era_name
|
|
1152
1191
|
era, epoch, reverse = @calendar_era_name
|
|
1153
1192
|
year_in_term = reverse ? -year_by_epoch : year_by_epoch
|
|
1154
1193
|
year_by_calendar = epoch + year_by_epoch if epoch
|
|
1155
1194
|
terms << year_in_term
|
|
1156
|
-
format
|
|
1195
|
+
format = (0..99) === (year_in_term * 1) ? "%02d." : "%04d."
|
|
1157
1196
|
if year_by_calendar && year_by_calendar != year_in_term
|
|
1158
1197
|
terms << (year_by_calendar * 1)
|
|
1159
1198
|
format += "(%04d)"
|
|
1160
1199
|
end
|
|
1161
1200
|
else
|
|
1162
1201
|
terms << year_by_epoch
|
|
1163
|
-
format
|
|
1202
|
+
format = (0..9999) === (year_by_epoch * 1) ? "%04d." : "%+0#{5+ext_dg}d."
|
|
1164
1203
|
end
|
|
1165
1204
|
|
|
1166
1205
|
# 月日
|
|
@@ -1196,22 +1235,35 @@ module When
|
|
|
1196
1235
|
# 多言語対応文字列化 - When.exe Standard Representation により多言語対応文字列化する
|
|
1197
1236
|
#
|
|
1198
1237
|
# @param [Integer] precision どの桁まで多言語対応文字列化するか、分解能で指定する
|
|
1238
|
+
# @param [true, false] round 指定の桁までで丸める(true)か, 切り捨てる(false)か
|
|
1239
|
+
# @note 丸めるのは precision が When::DAY よりも高精度の場合のみである
|
|
1199
1240
|
#
|
|
1200
1241
|
# @return [When::BasicTypes::M17n]
|
|
1201
1242
|
#
|
|
1202
|
-
def to_m17n(precision=@precision)
|
|
1203
|
-
super +
|
|
1243
|
+
def to_m17n(precision=@precision, round=false)
|
|
1244
|
+
super + _clk_time_for_inspect(round ? precision : nil).to_m17n(precision)
|
|
1204
1245
|
end
|
|
1205
1246
|
|
|
1206
1247
|
# 文字列化 -When.exe Standard Representation により文字列化する
|
|
1207
1248
|
#
|
|
1208
1249
|
# @param [Integer] precision どの桁まで多言語対応文字列化するか、分解能で指定する
|
|
1250
|
+
# @param [true, false] round 指定の桁までで丸める(true)か, 切り捨てる(false)か
|
|
1251
|
+
# @note 丸めるのは precision が When::DAY よりも高精度の場合のみである
|
|
1209
1252
|
#
|
|
1210
1253
|
# @return [String]
|
|
1211
1254
|
#
|
|
1212
|
-
def to_s(precision=@precision)
|
|
1213
|
-
super +
|
|
1255
|
+
def to_s(precision=@precision, round=false)
|
|
1256
|
+
super + _clk_time_for_inspect(round ? precision : nil).to_s(precision)
|
|
1257
|
+
end
|
|
1258
|
+
|
|
1259
|
+
# 出力に使用する clk_time の作成
|
|
1260
|
+
def _clk_time_for_inspect(precision)
|
|
1261
|
+
return @clk_time unless precision && precision > When::DAY
|
|
1262
|
+
base = self + When::TM::Duration.new(@clk_time.frame._round_value(precision))
|
|
1263
|
+
base.clk_time.clk_time[When::HOUR] = @clk_time.clk_time[When::HOUR] + 1 unless self.to_i == base.to_i
|
|
1264
|
+
return base.clk_time
|
|
1214
1265
|
end
|
|
1266
|
+
private :_clk_time_for_inspect
|
|
1215
1267
|
|
|
1216
1268
|
# 時
|
|
1217
1269
|
#
|