when_exe 0.4.4 → 0.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/lib/when_exe.rb +89 -3
  3. data/lib/when_exe/basictypes.rb +37 -7
  4. data/lib/when_exe/calendarnote.rb +18 -13
  5. data/lib/when_exe/calendartypes.rb +3 -9
  6. data/lib/when_exe/coordinates.rb +23 -373
  7. data/lib/when_exe/ephemeris.rb +7 -7
  8. data/lib/when_exe/ephemeris/notes.rb +0 -14
  9. data/lib/when_exe/events.rb +1851 -0
  10. data/lib/when_exe/icalendar.rb +121 -4
  11. data/lib/when_exe/linkeddata.rb +29 -18
  12. data/lib/when_exe/locales/akt.rb +63 -0
  13. data/lib/when_exe/locales/locale.rb +60 -11
  14. data/lib/when_exe/mini_application.rb +14 -8
  15. data/lib/when_exe/namespace.rb +42 -0
  16. data/lib/when_exe/parts/enumerator.rb +13 -2
  17. data/lib/when_exe/parts/geometric_complex.rb +51 -1
  18. data/lib/when_exe/parts/method_cash.rb +15 -10
  19. data/lib/when_exe/parts/resource.rb +47 -29
  20. data/lib/when_exe/region/chinese.rb +4 -3
  21. data/lib/when_exe/region/chinese/calendars.rb +4 -4
  22. data/lib/when_exe/region/chinese/epochs.rb +6 -6
  23. data/lib/when_exe/region/chinese/notes.rb +3 -3
  24. data/lib/when_exe/region/chinese/twins.rb +6 -6
  25. data/lib/when_exe/region/islamic.rb +1 -1
  26. data/lib/when_exe/region/japanese.rb +4 -4
  27. data/lib/when_exe/region/japanese/eclipses.rb +2 -2
  28. data/lib/when_exe/region/japanese/location.rb +93 -0
  29. data/lib/when_exe/region/japanese/notes.rb +29 -11
  30. data/lib/when_exe/region/japanese/residues.rb +1 -1
  31. data/lib/when_exe/region/japanese/twins.rb +18 -6
  32. data/lib/when_exe/region/location.rb +40 -0
  33. data/lib/when_exe/region/martian.rb +1 -1
  34. data/lib/when_exe/region/ryukyu.rb +1 -1
  35. data/lib/when_exe/spatial.rb +611 -0
  36. data/lib/when_exe/timestandard.rb +3 -3
  37. data/lib/when_exe/tmobjects.rb +32 -0
  38. data/lib/when_exe/tmposition.rb +211 -1318
  39. data/lib/when_exe/tmptypes.rb +1265 -0
  40. data/lib/when_exe/tmreference.rb +35 -0
  41. data/lib/when_exe/version.rb +3 -3
  42. data/test/events/example-datasets +7 -0
  43. data/test/events/history-dataset.csv +22 -0
  44. data/test/events/japanese-holiday-index.csv +28 -0
  45. data/test/events/japanese-holiday.csv +77 -0
  46. data/test/events/japanese-holiday.ttl +778 -0
  47. data/test/events/make_events_ttl.rb +18 -0
  48. data/test/events/mori_wikichoshi.csv +14 -0
  49. data/test/events/ndl_koyomi.csv +220 -0
  50. data/test/events/ndl_koyomi_index.csv +44 -0
  51. data/test/events/primeminister-dataset.csv +19 -0
  52. data/test/events/shogun-dataset.csv +22 -0
  53. data/test/events/test-history-dataset-edge-sparql.csv +26 -0
  54. data/test/events/test-history-dataset-edge.csv +27 -0
  55. data/test/events/test-history-dataset-sparql.csv +22 -0
  56. data/test/events/test-history-dataset.csv +23 -0
  57. data/test/events/test-history-events-edge.ttl +89 -0
  58. data/test/events/test-history-events.csv +6 -0
  59. data/test/examples/Terms.m17n +1 -1
  60. data/test/test.rb +6 -0
  61. data/test/test/coordinates.rb +2 -2
  62. data/test/test/events.rb +32 -0
  63. data/test/test/region/japanese.rb +20 -0
  64. data/test/test/region/m17n.rb +2 -2
  65. data/test/test/region/mayan.rb +6 -6
  66. data/test/test/tmposition.rb +63 -1
  67. metadata +26 -2
@@ -0,0 +1,1265 @@
1
+ # -*- coding: utf-8 -*-
2
+ =begin
3
+ Copyright (C) 2011-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
+ module When::TM
9
+
10
+ #
11
+ # 時間座標 - 単一の時間間隔によって定義する連続な間隔尺度を基礎とする
12
+ #
13
+ # see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#TimeCoordinateType gml schema}
14
+ #
15
+ class Coordinate < TemporalPosition
16
+
17
+ class << self
18
+ # 内部時間によるオブジェクトの生成
19
+ alias :universal_time :new
20
+
21
+ # 外部時間によるオブジェクトの生成
22
+ #
23
+ # @param [Numeric] dynamical_time 外部時間による時間座標値
24
+ #
25
+ # @param [Hash] options 下記の通り
26
+ # @option options [When::TimeStandard] :time_standard
27
+ #
28
+ # @return [When::TM::Coordinate]
29
+ #
30
+ def dynamical_time(dynamical_time, options={})
31
+ universal_time(When.Resource(options[:time_standard] || 'UniversalTime', '_t:').from_dynamical_time(dynamical_time), options)
32
+ end
33
+
34
+ # 他種の時間位置によるオブジェクトの生成
35
+ #
36
+ # @param [Numeric, When::TM::ClockTime, ::Time, ::Date, ::DateTime] time 他種の時間位置によるオブジェクト
37
+ #
38
+ # @param [Hash] options 下記の通り
39
+ # @option options [When::TM::Clock] :clock
40
+ # @option options [When::Parts::Timezone] :tz
41
+ #
42
+ # @return [When::TM::Coordinate]
43
+ #
44
+ def new(time, options={})
45
+ options = options.dup
46
+ options[:frame] = Clock.get_clock_option(options)
47
+ case time
48
+ when Numeric
49
+ options[:frame] ||= When::UTC unless time.kind_of?(Integer)
50
+ universal_time = (2*time - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
51
+ when ClockTime
52
+ options[:frame] ||= time.clock
53
+ universal_time = time.clk_time[0] + time.universal_time
54
+ when ::Time
55
+ options[:frame] ||= When.Clock(time.gmtoff)
56
+ universal_time = options[:frame].time_standard.from_time_object(time)
57
+ when TimeValue
58
+ options[:frame] ||= time.clock
59
+ universal_time = time.universal_time
60
+ else
61
+ if ::Object.const_defined?(:Date) && ::Date.method_defined?(:+) && time.respond_to?(:ajd)
62
+ case time
63
+ when ::DateTime
64
+ options[:frame] ||= When.Clock((time.offset * 86400).to_i)
65
+ universal_time = (2*time.ajd - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
66
+ when ::Date
67
+ universal_time = JulianDate._d_to_t(time.jd)
68
+ if options[:frame] && options[:frame].rate_of_clock != 1.0
69
+ universal_time = options[:frame].time_standard.from_dynamical_time(
70
+ When::TimeStandard.to_dynamical_time(universal_time))
71
+ end
72
+ end
73
+ end
74
+ end
75
+ raise TypeError, "Can't create #{self} from #{time.class}" unless universal_time
76
+ universal_time(universal_time, options)
77
+ end
78
+ end
79
+
80
+ # この時間位置と関連付けられた時間参照系 (relation - Reference)
81
+ #
82
+ # The time reference system associated with the temporal position being described
83
+ #
84
+ # @return [When::TM::ReferenceSystem]
85
+ #
86
+ alias :clock :frame
87
+
88
+ # 内部時間による時間座標値
89
+ #
90
+ # @return [Numeric]
91
+ #
92
+ attr_accessor :universal_time
93
+ alias :coordinateValue :universal_time
94
+ protected :universal_time=
95
+
96
+ # 内部時間(ローカル)
97
+ #
98
+ # @return [Numeric]
99
+ #
100
+ # 1970-01-01T00:00:00(ローカル) からの Universal Coordinated Time の経過時間 / 128秒
101
+ #
102
+ def local_time
103
+ @universal_time
104
+ end
105
+
106
+ # CoordinateSystem による時間座標値
107
+ #
108
+ # @return [Numeric]
109
+ #
110
+ def coordinateValue
111
+ (universal_time - frame.origin.universal_time) / frame.interval.to_f
112
+ end
113
+
114
+ # 加算
115
+ #
116
+ # @param [Numeric, When::TM::IntervalLength] other
117
+ #
118
+ # @return [When::TM::TemporalPosition]
119
+ #
120
+ def +(other)
121
+ other = other.to_interval_length if other.kind_of?(PeriodDuration)
122
+ super(other)
123
+ end
124
+
125
+ # 減算
126
+ #
127
+ # @param [When::TM::TemporalPosition, Numeric, When::TM::IntervalLength] other
128
+ #
129
+ # @return [When::TM::TemporalPosition] if other is a Numeric or When::TM::IntervalLength
130
+ # @return [When::TM::IntervalLength] if other is a When::TM::TemporalPosition
131
+ #
132
+ def -(other)
133
+ other = other.to_interval_length if other.kind_of?(PeriodDuration)
134
+ super(other)
135
+ end
136
+
137
+ # 前の時刻
138
+ #
139
+ # @return [When::TM::TemporalPosition]
140
+ #
141
+ # 分解能に対応する Duration だけ,日時を戻す
142
+ #
143
+ def prev
144
+ self - period
145
+ end
146
+
147
+ # 次の時刻
148
+ #
149
+ # @return [When::TM::TemporalPosition]
150
+ #
151
+ # 分解能に対応する Duration だけ,日時を進める
152
+ #
153
+ def succ
154
+ self + period
155
+ end
156
+ alias :next :succ
157
+
158
+ # オブジェクトの生成
159
+ #
160
+ # @param [Numeric] universal_time 内部時間による時間座標値
161
+ #
162
+ # @param [Hash] options 下記の通り
163
+ # @option options [When::TM::CoordinateSystem] :frame
164
+ #
165
+ def initialize(universal_time, options={})
166
+ super(options)
167
+ @universal_time = universal_time
168
+ end
169
+ end
170
+
171
+ #
172
+ # ユリウス日
173
+ #
174
+ # see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#JulianDateType CALENdeRsign}
175
+ #
176
+ class JulianDate < Coordinate
177
+
178
+ # Julian Day Number
179
+ # 19700101T120000Z
180
+ JD19700101 = 2440588
181
+
182
+ # Modified Julian Date
183
+ #
184
+ # see {https://en.wikipedia.org/wiki/Julian_day#Variants MJD}
185
+ JDN_of_MJD = 2400000.5
186
+
187
+ # Countdown to Equinoctial Planetconjunction
188
+ #
189
+ # see {http://www.calendersign.com/en/cs_cep-pec.php CEP}
190
+ JDN_of_CEP = 2698162
191
+
192
+ class << self
193
+
194
+ JD19700100_5 = JD19700101 - 0.5
195
+
196
+ #
197
+ # 日時の内部表現をユリウス日に変換
198
+ #
199
+ # @param [Numeric] t
200
+ #
201
+ # @return [Numeric]
202
+ #
203
+ def _t_to_d(t)
204
+ t / Duration::DAY + JD19700100_5
205
+ end
206
+
207
+ #
208
+ # ユリウス日をに日時の内部表現変換
209
+ #
210
+ # @param [Numeric] d
211
+ #
212
+ # @return [Numeric]
213
+ #
214
+ def _d_to_t(d)
215
+ (d - JD19700100_5) * Duration::DAY
216
+ end
217
+
218
+ # Generation of Temporal Objetct
219
+ #
220
+ # @param [String] specification ユリウス通日を表す文字列
221
+ # @param [Hash] options 暦法や時法などの指定 (see {When::TM::TemporalPosition._instance})
222
+ #
223
+ # @return [When::TM::TemporalPosition, When::TM::Duration, When::Parts::GeometricComplex or Array<them>]
224
+ #
225
+ def parse(specification, options={})
226
+ num, *calendars = specification.split(/\^{1,2}/)
227
+ jdn = num.sub!(/[.@]/, '.') ? num.to_f : num.to_i
228
+ case num
229
+ when /MJD/i ; jdn += JDN_of_MJD
230
+ when /CEP/i ; jdn += JDN_of_CEP
231
+ when /DTB/i ; jdn = When.Resource('_t:UniversalTime').from_dynamical_date(jdn)
232
+ end
233
+ frame = calendars.shift || options[:frame]
234
+ return self.new(jdn, options) unless frame
235
+ calendars.unshift(frame).inject(jdn) {|date, calendar| When.Calendar(calendar).jul_trans(date, options)}
236
+ end
237
+ end
238
+
239
+ # 加算
240
+ #
241
+ # @param [Numeric, When::TM::IntervalLength] other
242
+ #
243
+ # @return [When::TM::TemporalPosition]
244
+ #
245
+ def +(other)
246
+ new_date = super
247
+ new_date.frame = new_date.frame._daylight(new_date.universal_time) if new_date.frame && new_date.frame._need_validate
248
+ return new_date
249
+ end
250
+
251
+ # 減算
252
+ #
253
+ # @param [When::TM::TemporalPosition, Numeric, When::TM::IntervalLength] other
254
+ #
255
+ # @return [When::TM::TemporalPosition]
256
+ #
257
+ def -(other)
258
+ new_date = super
259
+ new_date.frame = new_date.frame._daylight(new_date.universal_time) if new_date.kind_of?(TimeValue) && new_date.frame && new_date.frame._need_validate
260
+ return new_date
261
+ end
262
+
263
+ # ユリウス日が指定の剰余となる日
264
+ #
265
+ # @param [When::Coordinates::Residue] other
266
+ #
267
+ # @return [When::TM::TemporalPosition]
268
+ #
269
+ def &(other)
270
+ raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
271
+ raise ArgumentError,"The right operand should have a unit 'day'" unless other.event == 'day'
272
+ jdn = to_i
273
+ new_date = self.dup
274
+ new_date.universal_time += ((other & jdn) - jdn) * Duration::DAY
275
+ return new_date
276
+ end
277
+
278
+ # ユリウス日の剰余
279
+ #
280
+ # @param [When::Coordinates::Residue] other
281
+ #
282
+ # @return [Numeric]
283
+ #
284
+ def %(other)
285
+ raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
286
+ raise ArgumentError,"The right operand should have a unit 'day'" unless other.event == 'day'
287
+ other % to_i
288
+ end
289
+
290
+ private
291
+
292
+ # オブジェクトの生成
293
+ #
294
+ # @param [Numeric] universal_time 内部時間による時間座標値
295
+ #
296
+ # @param [Hash] options 以下の通り
297
+ # @option options [When::TM::Clock] :frame
298
+ # @option options [Integer] :precision
299
+ #
300
+ def initialize(universal_time, options={})
301
+ @frame = options.delete(:frame)
302
+ @frame = When.Clock(@frame) if @frame.kind_of?(String)
303
+ @frame = @frame._daylight(universal_time) if @frame && @frame._need_validate
304
+ precision = options.delete(:precision)
305
+ precision ||= DAY unless @frame.kind_of?(Clock)
306
+ @precision = Index.precision(precision)
307
+ super
308
+ end
309
+ end
310
+
311
+ #
312
+ # 順序時間参照系で参照する位置
313
+ #
314
+ # see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#TimeOrdinalPositionType gml schema}
315
+ #
316
+ class OrdinalPosition < TemporalPosition
317
+
318
+ # この順序位置と関連付けられた順序年代 (relation - Reference)
319
+ #
320
+ # The ordinal era associated with the ordinal position being described
321
+ #
322
+ # @return [When::TM::OrdinalEra]
323
+ #
324
+ attr_reader :ordinal_position
325
+ alias :ordinalPosition :ordinal_position
326
+
327
+ # オブジェクトの生成
328
+ #
329
+ # @param [When::TM::OrdinalEra] ordinal_position この順序位置と関連付けられた順序年代
330
+ # @param [Hash] options see {When::TM::TemporalPosition._instance}
331
+ #
332
+ def initialize(ordinal_position, options={})
333
+ super(options)
334
+ @ordinal_position = ordinal_position
335
+ end
336
+ end
337
+
338
+ #
339
+ # 時刻
340
+ #
341
+ # see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#ClockTimeType gml schema}
342
+ #
343
+ class ClockTime < TemporalPosition
344
+
345
+ # 時刻要素
346
+ #
347
+ # @return [Array<Numeric>]
348
+ #
349
+ # @note ISO19108 では sequence<Integer> だが、閏時・閏秒などが表現可能なよう Numeric としている。
350
+ #
351
+ attr_reader :clk_time
352
+ alias :clkTime :clk_time
353
+
354
+ # この時間位置と関連付けられた時間参照系 (relation - Reference)
355
+ #
356
+ # The time reference system associated with the temporal position being described
357
+ #
358
+ # @return [When::TM::ReferenceSystem]
359
+ #
360
+ alias :clock :frame
361
+
362
+ # 内部時間
363
+ #
364
+ # @param [Integer] sdn 参照事象の通し番号
365
+ #
366
+ # @return [Numeric]
367
+ #
368
+ # T00:00:00Z からの Universal Coordinated Time の経過時間 / 128秒
369
+ #
370
+ # 時法によっては、異なる意味を持つことがある
371
+ #
372
+ def universal_time(sdn=nil)
373
+ raise NameError, "Temporal Reference System is not defined" unless @frame
374
+ @universal_time ||= @frame.to_universal_time(@clk_time, sdn)
375
+ end
376
+
377
+ # 内部時間(ローカル)
378
+ #
379
+ # @param [Integer] sdn 参照事象の通し番号
380
+ #
381
+ # @return [Numeric]
382
+ #
383
+ # T00:00:00(ローカル) からの Universal Coordinated Time の経過時間 / 128秒
384
+ #
385
+ # 時法によっては、異なる意味を持つことがある
386
+ #
387
+ def local_time(sdn=nil)
388
+ raise NameError, "Temporal Reference System is not defined" unless @frame
389
+ @local_time ||= @frame.to_local_time(@clk_time, sdn)
390
+ end
391
+
392
+ # 繰り上がり
393
+ #
394
+ # @return [Numeric]
395
+ #
396
+ # 日付の境界が午前0時でない場合、clk_time の最上位桁に 0 以外が入ることがある
397
+ #
398
+ def carry
399
+ return @clk_time[0]
400
+ end
401
+
402
+ # 要素の参照
403
+ #
404
+ # @param [Integer, String] index 参照する要素の指定
405
+ #
406
+ # @return [Numeric]
407
+ #
408
+ def value(index)
409
+ @clk_time[_digit(index) {|digit| digit >= DAY}]
410
+ end
411
+
412
+ #protected
413
+ # 属性のコピー
414
+ # @private
415
+ def _copy(options={})
416
+ @clk_time = options[:time] if options.key?(:time)
417
+ if options.key?(:clock)
418
+ options.delete(:frame)
419
+ @frame = options[:clock]
420
+ end
421
+ if options.key?(:tz_prop)
422
+ @frame = @frame.dup
423
+ @frame.tz_prop = options[:tz_prop]
424
+ end
425
+ return super
426
+ end
427
+
428
+ # オブジェクトの生成
429
+ #
430
+ # @param [String] time ISO8601形式の時刻表現
431
+ # @param [Array<Numeric>] time (日, 時, 分, 秒)
432
+ #
433
+ #
434
+ # @param [Hash] options 以下の通り
435
+ # @option options [When::TM::Clock] :frame
436
+ # @option options [Integer] :precision
437
+ #
438
+ def initialize(time, options={})
439
+ # 参照系の取得
440
+ @frame = options[:frame] || Clock.local_time
441
+ @frame = When.Clock(@frame) if (@frame.kind_of?(String))
442
+ options.delete(:frame)
443
+
444
+ # 時刻表現の解読 ( Time Zone の解釈 )
445
+ if (time.kind_of?(String))
446
+ case time
447
+ when /\A([-+])?(\d{2,}?):?(\d{2})?:?(\d{2}(\.\d+)?)?\z/
448
+ sign, hh, mm, ss = $~[1..4]
449
+ time = @frame._validate([0,0,0,0],
450
+ [0,
451
+ -(sign.to_s + "0" + hh.to_s).to_i,
452
+ -(sign.to_s + "0" + mm.to_s).to_i,
453
+ Pair._en_number(-(sign.to_s + "0" + ss.to_s).to_f)])
454
+ time[0] = Pair.new(0, time[0].to_i) if (time[0] != 0)
455
+ when /\AZ\z/
456
+ time = [0,0,0,0]
457
+ else
458
+ raise ArgumentError, "Invalid Time Format"
459
+ end
460
+ end
461
+ @clk_time = time
462
+
463
+ # 分解能
464
+ @precision = @frame._precision(time, options.delete(:precision))
465
+
466
+ super(options)
467
+ end
468
+
469
+ private
470
+
471
+ # オブジェクトの正規化
472
+ def _normalize(options={})
473
+ # strftime で使用する locale
474
+ @keys |= @frame.keys
475
+
476
+ # 時刻の正規化
477
+ @clk_time = @frame._validate(@clk_time) unless options[:validate]
478
+ end
479
+
480
+ # 加減算共通処理
481
+ def _plus(period)
482
+ self.dup._copy({:time=>@frame._validate(@clk_time, @frame._arrange_length(period.time)),
483
+ :events=>nil, :query=>nil, :validate=>:done})
484
+ end
485
+ end
486
+
487
+ #
488
+ # 暦日
489
+ #
490
+ # see {gml schema}[link:http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#CalDateType]
491
+ #
492
+ class CalDate < TemporalPosition
493
+
494
+ # 検索オプション
495
+ # @private
496
+ SearchOption = {After=>[0, -2, Before], Before=>[-2, 0, After]}
497
+
498
+ # 日付要素
499
+ #
500
+ # @return [Array<Numeric>]
501
+ #
502
+ # @note ISO19108 では sequence<Integer> だが、閏月などが表現可能なよう Numeric としている。
503
+ #
504
+ attr_reader :cal_date
505
+ alias :calDate :cal_date
506
+
507
+ # この時間位置と関連付けられた時間参照系 (relation - Reference)
508
+ #
509
+ # The time reference system associated with the temporal position being described
510
+ #
511
+ # @return [When::TM::ReferenceSystem]
512
+ #
513
+ alias :calendar :frame
514
+
515
+ # 暦年代
516
+ #
517
+ # @return [When::TM::CalendarEra]
518
+ #
519
+ attr_accessor :calendar_era
520
+ private :calendar_era=
521
+ alias :calendarEra :calendar_era
522
+
523
+ # 暦年代属性
524
+ #
525
+ # @return [Array] ( name, epoch, reverse, go back )
526
+ # - name [String] 暦年代名
527
+ # - epoch [Integer] 使用する When::TM::Calendar で暦元に対応する年
528
+ # - reverse [Boolean] 年数が昇順(false,nil)か降順(true)か
529
+ # - go back [Boolean] 参照イベントより前の暦日か(true)、否か(false,nil)
530
+ #
531
+ attr_accessor :calendar_era_props
532
+ private :calendar_era_props=
533
+
534
+ # 暦年代名
535
+ #
536
+ # @return [String] 暦年代名
537
+ #
538
+ def calendar_era_name
539
+ @calendar_era_props ? @calendar_era_props[0] : nil
540
+ end
541
+ alias :calendarEraName :calendar_era_name
542
+
543
+ # 暦年代元期
544
+ #
545
+ # @return [Integer] 使用する When::TM::Calendar で暦元に対応する年
546
+ #
547
+ def calendar_era_epoch
548
+ @calendar_era_props ? @calendar_era_props[1] : 0
549
+ end
550
+
551
+ # 暦年代正逆
552
+ #
553
+ # @return [Boolean] 年数が昇順(false,nil)か降順(true)か
554
+ #
555
+ def calendar_era_reverse
556
+ @calendar_era_props ? @calendar_era_props[2] : false
557
+ end
558
+
559
+ # 暦年代遡及
560
+ #
561
+ # @return [Boolean] 参照イベントより前の暦日か(true)、否か(false,nil)
562
+ #
563
+ def calendar_era_go_back
564
+ @calendar_era_props ? @calendar_era_props[3] : false
565
+ end
566
+
567
+ # 時法の取得 - ダミー
568
+ def clock
569
+ nil
570
+ end
571
+
572
+ # 内部時間
573
+ #
574
+ # @return [Numeric]
575
+ #
576
+ # 当日正午の 1970-01-01T00:00:00Z からの Universal Coordinated Time の経過時間 / 128秒
577
+ #
578
+ def universal_time
579
+ return super if [Now, Max, Min].include?(@indeterminated_position)
580
+ @universal_time ||= JulianDate._d_to_t(to_i)
581
+ end
582
+ alias :local_time :universal_time
583
+
584
+ # ユリウス日
585
+ #
586
+ # @return [Integer]
587
+ #
588
+ # -4712-01-01からの経過日数に対応する通番
589
+ #
590
+ def to_i
591
+ @sdn ||= _to_i
592
+ end
593
+
594
+ #
595
+ # 暦法上の通日
596
+ #
597
+ def _to_i
598
+ void, epoch = @calendar_era_props
599
+ if epoch
600
+ date = @cal_date.dup
601
+ date[0] += epoch
602
+ else
603
+ date = @cal_date
604
+ end
605
+ @frame.to_julian_date(date)
606
+ end
607
+ private :_to_i
608
+
609
+ # 前の日時
610
+ #
611
+ # @return [When::TM::TemporalPosition]
612
+ #
613
+ # 分解能に対応する Duration だけ,日時を戻す
614
+ #
615
+ def prev
616
+ @precision==When::DAY ? _force_euqal_day(-1) : self-period
617
+ rescue RangeError
618
+ (When::Gregorian ^ self) - period
619
+ end
620
+
621
+ # 次の日時
622
+ #
623
+ # @return [When::TM::TemporalPosition]
624
+ #
625
+ # 分解能に対応する Duration だけ,日時を進める
626
+ #
627
+ def succ
628
+ @precision==When::DAY ? _force_euqal_day(+1) : self+period
629
+ rescue RangeError
630
+ (When::Gregorian ^ self) + period
631
+ end
632
+ alias :next :succ
633
+
634
+ # 剰余類化
635
+ #
636
+ # @param [Numeric] remainder 剰余
637
+ # @param [Integer] divisor 法(>0)
638
+ #
639
+ # @return [When::Coordinates::Residue] 当日、当年を基準とする剰余類
640
+ #
641
+ def to_residue(remainder, divisor)
642
+ When::Coordinates::Residue.new(remainder, divisor, {'day' => least_significant_coordinate,
643
+ 'year' => most_significant_coordinate})
644
+ end
645
+
646
+ # 暦年代の削除
647
+ #
648
+ # @return [When::TM::CalDate] 暦年代を削除した When::TM::CalDate
649
+ #
650
+ def without_era
651
+ target = dup
652
+ return target unless calendar_era
653
+ options = _attr
654
+ options[:era] = nil
655
+ options[:era_name] = nil
656
+ options[:date] = cal_date.dup
657
+ options[:date][0] += calendar_era_epoch
658
+ target._copy(options)
659
+ end
660
+
661
+ # 要素の参照
662
+ #
663
+ # @param [Integer, String] index 参照する要素の指定
664
+ #
665
+ # @return [Numeric]
666
+ #
667
+ def value(index)
668
+ @cal_date[(_digit(index) {|digit| digit <= DAY})-1]
669
+ end
670
+
671
+ #
672
+ # 最上位の要素
673
+ #
674
+ # @return [Numeric] 暦年代の epoch に関わらず暦法に従った年の通し番号を返す
675
+ #
676
+ def most_significant_coordinate
677
+ coordinate = @cal_date[0]
678
+ coordinate += calendar_era_epoch if @calendar_era_props
679
+ @frame.index_of_MSC.times do |i|
680
+ coordinate = +coordinate * @frame.indices[i].unit + @cal_date[i+1] - @frame.indices[i].base
681
+ end
682
+ coordinate
683
+ end
684
+
685
+ #
686
+ # 最下位の要素
687
+ #
688
+ # @return [Numeric] 剰余類の演算に用いる日の通し番号を返す
689
+ #
690
+ def least_significant_coordinate
691
+ return to_i + @frame.indices[-1].shift
692
+ end
693
+
694
+ # ユリウス日または通年が指定の剰余となる日
695
+ #
696
+ # @param [When::Coordinates::Residue] other
697
+ #
698
+ # @return [When::TM::CalDate]
699
+ #
700
+ def &(other)
701
+ raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
702
+ case other.event
703
+ when 'day'
704
+ # 指定の剰余となる日
705
+ sdn = other & to_i
706
+ options = {:date=>_date_with_era(@frame.to_cal_date(sdn)), :events=>nil, :query=>@query, :validate=>:done}
707
+ options[:precision] = When::DAY if precision < When::DAY
708
+ result = self.dup._copy(options)
709
+ result.send(:_force_euqal_day, sdn-result.to_i)
710
+
711
+ when 'year'
712
+ # 指定の剰余となる年
713
+ date = @frame.send(:_decode, _date_without_era)
714
+ date[0] = (other & (date[0] + @frame.diff_to_CE)) - @frame.diff_to_CE
715
+ options = {:date=>_date_with_era(@frame.send(:_encode, date)), :events=>nil, :query=>@query}
716
+ options[:precision] = When::YEAR if precision < When::YEAR
717
+ return self.dup._copy(options)
718
+
719
+ else
720
+ raise ArgumentError,"The right operand should have a unit 'day' or 'year'"
721
+ end
722
+ end
723
+
724
+ # ユリウス日または通年の剰余
725
+ #
726
+ # @param [When::Coordinates::Residue] other
727
+ #
728
+ # @return [Numeric]
729
+ #
730
+ def %(other)
731
+ raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
732
+ if precision <= When::YEAR && other.units['year'] && other.event != 'year'
733
+ other.to('year') % (most_significant_coordinate + @frame.epoch_in_CE)
734
+ else
735
+ case other.event
736
+ when 'day' ; other % least_significant_coordinate
737
+ when 'year' ; other % (most_significant_coordinate + @frame.epoch_in_CE)
738
+ else ; raise ArgumentError,"The right operand should have a unit 'day' or 'year'"
739
+ end
740
+ end
741
+ end
742
+
743
+ # 下位桁の切り捨て
744
+ #
745
+ # @param [Integer] digit 切り捨てずに残す、最下位の桁
746
+ #
747
+ # @param [Integer] precision 切り捨て結果の分解能
748
+ #
749
+ # @return [When::TM::CalDate]
750
+ #
751
+ def floor(digit=DAY, precision=digit)
752
+ options = {:date=>@cal_date[0..(digit-1)], :events=>nil, :query=>nil}
753
+ options[:precision] = precision if precision
754
+ self.dup._copy(options)
755
+ end
756
+
757
+ # 下位桁の切り上げ
758
+ #
759
+ # @param [Integer] digit 切り上げずに残す、最下位の桁
760
+ #
761
+ # @param [Integer] precision 切り上げ結果の分解能
762
+ #
763
+ # @return [When::TM::CalDate]
764
+ #
765
+ def ceil(digit=DAY, precision=digit)
766
+ (self + PeriodDuration.new(1, digit, (-@frame.indices.length)..0)).floor(digit, precision)
767
+ end
768
+
769
+ # 要素数 ― 上位要素に含まれる下位要素の数
770
+ #
771
+ # @param [Integer] upper 上位要素のインデックス
772
+ # @param [Integer] lower 下位要素のインデックス(DAY または MONTH)
773
+ #
774
+ # @return [Integer]
775
+ #
776
+ def length(upper, lower=DAY)
777
+ range = [floor(upper).to_i, ceil(upper).to_i]
778
+ range = range.map {|d| (Residue.mod(d) {|m| frame._new_month(m)})[0]} if lower == MONTH
779
+ range[1] - range[0]
780
+ end
781
+
782
+ # 時刻情報のない When::TM::CalDate を返す
783
+ #
784
+ # @return [When::TM::CalDate]
785
+ #
786
+ alias :to_cal_date :dup
787
+ alias :to_CalDate :to_cal_date
788
+
789
+ # 暦年代が末端の参照であるか?
790
+ #
791
+ # @return [Boolean]
792
+ #
793
+ def leaf?
794
+ ! @calendar_era.respond_to?(:_pool) || @calendar_era.leaf?
795
+ end
796
+
797
+ # 属性の Hash
798
+ # @private
799
+ def _attr
800
+ super.merge({:era_name=>@calendar_era_props, :era=>@calendar_era})
801
+ end
802
+ protected
803
+
804
+ # 属性のコピー
805
+ # @private
806
+ def _copy(options={})
807
+ @cal_date = options[:date] if options.key?(:date)
808
+ @calendar_era = options[:era] if options.key?(:era)
809
+ @calendar_era_props = options[:era_name] if options.key?(:era_name)
810
+ return super
811
+ end
812
+
813
+ # オブジェクトの生成
814
+ #
815
+ # @param [Array<Numeric>] date 日付表現
816
+ #
817
+ # @param [Hash] options 下記の通り (see also {When::TM::TemporalPosition._instance})
818
+ # @option options [When::TM::Calendar] :frame
819
+ # @option options [When::TM::CalendarEra, When::BasicTypes::M17n, Array<When::BasicTypes::M17n, Integer>] :era_name
820
+ # (Integer は 当該年号の 0 年に相当する通年)
821
+ # @option options [Integer] :precision
822
+ #
823
+ def initialize(date, options={})
824
+ # 年号 & 日付
825
+ @calendar_era_props = options[:era_name]
826
+ @calendar_era = options[:era]
827
+ @cal_date = date
828
+
829
+ super(options)
830
+ end
831
+
832
+ private
833
+
834
+ # オブジェクトの正規化
835
+ def _normalize(options={})
836
+
837
+ # 日付配列の長さ
838
+ cal_date_index = @cal_date.compact.length
839
+
840
+ # 日付の正規化
841
+ if @calendar_era_props
842
+ # Calendar Era がある場合
843
+ trans_options = @trans || {} # TODO? 消す
844
+ count = trans_options[:count] || 1
845
+ query_options = (@query || {}).dup
846
+ query_options[:label] = @calendar_era_props
847
+ query_options[:count] = count
848
+ era = date = nil
849
+ if @calendar_era
850
+ era, date = _search_era(@calendar_era, trans_options)
851
+ else
852
+ eras = CalendarEra._instance(query_options)
853
+ raise ArgumentError, "CalendarEraName doesn't exist: #{query_options[:label]}" if eras.empty?
854
+ eras.each do |e|
855
+ era, date = _search_era(e, trans_options)
856
+ next unless era
857
+ count -= 1
858
+ break unless count > 0
859
+ end
860
+ end
861
+ raise RangeError, "Out of CalendarEra Range" unless era
862
+ @calendar_era_props = date.calendar_era_props
863
+ @calendar_era = era
864
+ @cal_date = date.cal_date
865
+ @frame = date.frame
866
+ @query = (@query||{}).merge(date.query)
867
+ @trans = (@trans||{}).merge(date.trans)
868
+ @keys |= calendar_era_name.keys | @frame.keys
869
+ else
870
+ # Calendar Era がない場合
871
+ @frame = When.Resource(options[:frame] || @frame || 'Gregorian', '_c:')
872
+ @cal_date = @frame._validate(@cal_date) unless options[:validate] == :done
873
+ @keys |= @frame.keys
874
+ end
875
+
876
+ # 分解能
877
+ precision = options.delete(:precision) || @precision
878
+ cal_date_index =
879
+ case options.delete(:_format)
880
+ when :century ; CENTURY
881
+ when :week, :day ; DAY
882
+ else ; cal_date_index - (@frame.indices.length + 1)
883
+ end
884
+ precision ||= cal_date_index if cal_date_index < DAY
885
+ precision ||= @clk_time.precision if @clk_time
886
+ @precision = Index.precision(precision || DAY)
887
+ end
888
+
889
+ # 暦年代を探す
890
+ def _search_era(era, trans_options)
891
+ cal_date = @cal_date.dup
892
+ cal_date[0] = -cal_date[0] if era.reverse?
893
+ cal_date[0] += era.epoch_year
894
+ date = era.trans(cal_date, trans_options)
895
+ loop do
896
+ case date
897
+ when Before, After
898
+ i0, i1, reverse = SearchOption[date]
899
+ new_era = (date == Before) ? era.prev : era.succ
900
+ break unless new_era
901
+ date = new_era.trans(cal_date, trans_options)
902
+ if date == reverse
903
+ cal_date = new_era.epoch[i0].frame.to_cal_date(era.epoch[i1].frame.to_julian_date(cal_date))
904
+ date = new_era.trans(cal_date, trans_options)
905
+ break if date == reverse
906
+ end
907
+ era = new_era
908
+ when TimeValue
909
+ return era, date
910
+ else
911
+ break
912
+ end
913
+ end
914
+ return nil
915
+ end
916
+
917
+ # 加減算共通処理
918
+ def _plus(period)
919
+ _frame_adjust(period, self.dup._copy({:date=>_date_with_era(@frame._validate(_date_without_era,
920
+ @frame._arrange_length(period.date))),
921
+ :events=>nil, :query=>nil, :validate=>:done}))
922
+ end
923
+
924
+ # 年号を除外した @frame の暦法に対応する日付
925
+ def _date_without_era
926
+ date = @cal_date.dup
927
+ date[0] += calendar_era_epoch if @calendar_era_props
928
+ date
929
+ end
930
+
931
+ # 年号に続く日付
932
+ def _date_with_era(date)
933
+ date[0] -= calendar_era_epoch if @calendar_era_props
934
+ date
935
+ end
936
+
937
+ # 暦法が変わった場合の補正
938
+ def _frame_adjust(period, date)
939
+ return date if @frame.equal?(date.frame) || (period.to_day||0) == 0
940
+ diff = period.to_day - (date.to_i - to_i)
941
+ return date if diff == 0
942
+ date.send(:_force_euqal_day, diff)
943
+ end
944
+ end
945
+
946
+ #
947
+ # 時刻を伴った日付
948
+ #
949
+ # see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#DateAndTimeType gml schema}
950
+ #
951
+ class DateAndTime < CalDate
952
+
953
+ # 時刻要素
954
+ #
955
+ # @return [When::TM::ClockTime]
956
+ #
957
+ attr_reader :clk_time
958
+ alias :clkTime :clk_time
959
+
960
+ # 時法の取得
961
+ #
962
+ # @return [When::TM::Clock]
963
+ #
964
+ def clock
965
+ @clk_time.frame
966
+ end
967
+
968
+ # 内部時間
969
+ #
970
+ # @return [Numeric]
971
+ #
972
+ # 1970-01-01T00:00:00Z からの Universal Coordinated Time の経過時間 / 128秒
973
+ #
974
+ # 暦法によっては、異なる意味を持つことがある
975
+ #
976
+ def universal_time
977
+ return super if [Now, Max, Min].include?(@indeterminated_position)
978
+ raise NameError, "Temporal Reference System is not defined" unless (@frame && clock)
979
+ @universal_time ||= (to_i - JulianDate::JD19700101) * Duration::DAY + @clk_time.universal_time(to_i)
980
+ end
981
+
982
+ # 内部時間(ローカル)
983
+ #
984
+ # @return [Numeric]
985
+ #
986
+ # 1970-01-01T00:00:00(ローカル) からの Universal Coordinated Time の経過時間 / 128秒
987
+ #
988
+ # 暦法によっては、異なる意味を持つことがある
989
+ #
990
+ def local_time
991
+ return super if [Now, Max, Min].include?(@indeterminated_position)
992
+ raise NameError, "Temporal Reference System is not defined" unless (@frame && clock)
993
+ @local_time ||= (to_i - JulianDate::JD19700101) * Duration::DAY + @clk_time.local_time(to_i)
994
+ end
995
+
996
+ # 要素の参照
997
+ #
998
+ # @param [Integer] index 参照する要素の指定
999
+ #
1000
+ # @return [Numeric]
1001
+ #
1002
+ def value(index)
1003
+ digit = _digit(index)
1004
+ return (digit <= DAY) ? @cal_date[digit-1] : @clk_time.clk_time[digit]
1005
+ end
1006
+
1007
+ # ユリウス日または通年が指定の剰余となる日
1008
+ #
1009
+ # @param [When::Coordinates::Residue] other
1010
+ #
1011
+ # @return [When::TM::DateAndTime]
1012
+ #
1013
+ def &(other)
1014
+ raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
1015
+ case other.event
1016
+ when 'day'
1017
+ # 指定の剰余となる日
1018
+ sdn = other & to_i
1019
+ options = {:date=>_date_with_era(@frame.to_cal_date(sdn)), :time=>@clk_time.clk_time.dup,
1020
+ :events=>nil, :query=>@query, :validate=>:done}
1021
+ options[:precision] = When::DAY if precision < When::DAY
1022
+ result = self.dup._copy(options)
1023
+ result.send(:_force_euqal_day, sdn-result.to_i)
1024
+
1025
+ when 'year'
1026
+ # 指定の剰余となる年
1027
+ date = @frame.send(:_decode, _date_without_era)
1028
+ date[0] = (other & (date[0] + @frame.diff_to_CE)) - @frame.diff_to_CE
1029
+ options = {:date=>_date_with_era(@frame.send(:_encode, date)), :time=>@clk_time.clk_time.dup,
1030
+ :events=>nil, :query=>@query}
1031
+ options[:precision] = When::YEAR if precision < When::YEAR
1032
+ return self.dup._copy(options)
1033
+
1034
+ else
1035
+ raise ArgumentError,"The right operand should have a unit 'day' or 'year'"
1036
+ end
1037
+ end
1038
+
1039
+ # 下位桁の切り捨て
1040
+ #
1041
+ # @param [Integer] digit 切り捨てずに残す、最下位の桁
1042
+ #
1043
+ # @param [Integer] precision 切り捨て結果の分解能
1044
+ #
1045
+ # @return [When::TM::DateAndTime]
1046
+ #
1047
+ def floor(digit=DAY, precision=digit)
1048
+ count = digit - clock.indices.length
1049
+
1050
+ if digit>=DAY
1051
+ date = @cal_date.dup
1052
+ elsif @calendar_era_props
1053
+ date = @cal_date.dup
1054
+ date[0] += calendar_era_epoch
1055
+ date = @frame._validate(date[0..(digit-1)])
1056
+ date[0] -= calendar_era_epoch
1057
+ else
1058
+ date = @frame._validate(@cal_date[0..(digit-1)])
1059
+ end
1060
+
1061
+ time = @clk_time.clk_time[0..((digit<=DAY) ? 0 : ((count>=0) ? -1 : digit))]
1062
+ time[0] += to_i
1063
+ time = clock._validate(time)
1064
+ time[0] -= to_i
1065
+
1066
+ if (count >= 0)
1067
+ factor = 10**count
1068
+ time[-1] = (time[-1] * factor).floor.to_f / factor
1069
+ end
1070
+
1071
+ # オブジェクトの生成
1072
+ options = {:date=>date, :validate=>:done, :events=>nil, :query=>nil,
1073
+ :time=>(digit<=DAY) ? time : @clk_time.dup._copy({:time=>time})}
1074
+ options[:precision] = precision if precision
1075
+ return self.dup._copy(options)
1076
+ end
1077
+
1078
+ # 下位桁の切り上げ
1079
+ #
1080
+ # @param [Integer] digit 切り上げずに残す、最下位の桁
1081
+ #
1082
+ # @param [Integer] precision 切り上げ結果の分解能
1083
+ #
1084
+ # @return [When::TM::DateAndTime]
1085
+ #
1086
+ def ceil(digit=DAY, precision=digit)
1087
+ length = clock.indices.length
1088
+ count = digit - length
1089
+ period = PeriodDuration.new((count<=0) ? 1 : 0.1**count, digit, (-@frame.indices.length)..length)
1090
+ result = floor(digit, precision) + period
1091
+ result += clock.tz_difference if (result.universal_time <= self.universal_time)
1092
+ return result
1093
+ end
1094
+
1095
+ # 位置情報
1096
+ #
1097
+ # @return [When::Coordinates::Spatial]
1098
+ #
1099
+ def location
1100
+ @location ||= @clk_time.frame.location
1101
+ end
1102
+
1103
+ # 時刻情報のない When::TM::CalDate を返す
1104
+ #
1105
+ # @return [When::TM::CalDate]
1106
+ #
1107
+ def to_cal_date
1108
+ options = _attr
1109
+ options.delete(:clock)
1110
+ options[:precision] = [When::DAY, options[:precision]].min
1111
+ CalDate.new(@cal_date, options)
1112
+ end
1113
+ alias :to_CalDate :to_cal_date
1114
+
1115
+ # 標準ライブラリの DateTime オブジェクトへの変換
1116
+ #
1117
+ alias :to_date_or_datetime :to_datetime
1118
+
1119
+ #protected
1120
+
1121
+ # 属性の Hash
1122
+ # @private
1123
+ def _attr
1124
+ super.merge({:clock=>clock})
1125
+ end
1126
+
1127
+ # 属性のコピー
1128
+ # @private
1129
+ def _copy(options={})
1130
+ # 夏時間の調整
1131
+ case options[:time]
1132
+ when Array
1133
+ if clock._need_validate
1134
+ if @calendar_era_props
1135
+ date = options[:date].dup
1136
+ date[0] += calendar_era_epoch
1137
+ else
1138
+ date = options[:date]
1139
+ end
1140
+ new_clock = clock._daylight([@frame, date, options[:time]])
1141
+ options[:time] = options[:time].map {|t| t * 1}
1142
+ else
1143
+ new_clock = clock
1144
+ end
1145
+ options[:time] = @clk_time.dup._copy(options.merge({:clock=>new_clock}))
1146
+ when nil
1147
+ options[:time] = @clk_time.dup._copy(options)
1148
+ end
1149
+
1150
+ return super(options)
1151
+ end
1152
+
1153
+ # オブジェクトの生成
1154
+ #
1155
+ # @param [Array<Numeric>] date 日付表現
1156
+ # @param [Array<Numeric>] time 時刻表現
1157
+ # @param [Hash] options 下記の通り (see also {When::TM::TemporalPosition._instance})
1158
+ # @option options [When::TM::Calendar] :frame
1159
+ # @option options [When::TM::Clock] :clock
1160
+ # @option options [When::TM::CalendarEra, When::BasicTypes::M17n, Array<When::BasicTypes::M17n, Integer>] :era_name
1161
+ # (Integer は 当該年号の 0 年に相当する通年)
1162
+ # @option options [Integer] :precision
1163
+ #
1164
+ def initialize(date, time, options={})
1165
+ options[:time] = time
1166
+ super(date, options)
1167
+ end
1168
+
1169
+ private
1170
+
1171
+ # オブジェクトの正規化
1172
+ def _normalize(options={})
1173
+
1174
+ # Clock
1175
+ unless options[:validate]
1176
+ clock = Clock.get_clock_option(options)
1177
+ clock ||= options[:time].frame if options[:time].kind_of?(ClockTime)
1178
+ clock ||= Clock.local_time
1179
+ end
1180
+ clock = When.Clock(clock) if clock.kind_of?(String)
1181
+ clock_is_timezone = clock && !clock.kind_of?(When::TM::Clock)
1182
+ clock = clock.daylight if clock_is_timezone
1183
+
1184
+ # ClockTime
1185
+ @clk_time =
1186
+ case options[:time]
1187
+ when ClockTime ; options[:time]
1188
+ when Array ; ClockTime.new(options[:time], {:frame=>clock, :precision=>options[:precision], :validate=>:done})
1189
+ else ; clock.to_clk_time(options[:time], {:precision=>options[:precision]})
1190
+ end
1191
+
1192
+ super
1193
+
1194
+ # 日付と時刻の正規化
1195
+ unless options[:validate]
1196
+ time = @clk_time.clk_time
1197
+ precision = @clk_time.precision
1198
+ second = time[clock.base.length-1]
1199
+ second -= clock.base[-1] if second
1200
+ if second && second != 0 && time_standard.has_leap?
1201
+ zero = DateAndTime.new(@cal_date, time[0..-2],
1202
+ {:frame=>@frame, :clock=>clock, :precision=>precision,
1203
+ :era_name=>@calendar_era_props, :era=>options[:era],
1204
+ :time_standard=>time_standard, :location=>@location})
1205
+ end
1206
+
1207
+ # 日付と時刻の関係の調整
1208
+ @cal_date = _date_with_era(@frame._validate(_date_without_era) {|jdn|
1209
+ time[0] += jdn
1210
+ time[0..-1] = clock._validate(time)
1211
+ jdn = time[0] * 1
1212
+ time[0] -= jdn
1213
+ jdn
1214
+ })
1215
+
1216
+ # 夏時間の調整
1217
+ if clock._need_validate
1218
+ if @calendar_era_props
1219
+ cal_date = @cal_date.dup
1220
+ cal_date[0] += calendar_era_epoch
1221
+ else
1222
+ cal_date = @cal_date
1223
+ end
1224
+ clock = clock._daylight([@frame, cal_date, time])
1225
+ end
1226
+ time = [time[0]] + time[1..-1].map {|t| t * 1}
1227
+ @clk_time = ClockTime.new(time, {:frame=>clock, :precision=>precision, :validate=>:done}) if clock_is_timezone
1228
+
1229
+ # 閏秒
1230
+ if zero
1231
+ leap = ((dynamical_time - zero.dynamical_time) * clock.second - second).to_i
1232
+ if leap != 0 && leap.abs < clock.second
1233
+ @cal_date = zero.cal_date
1234
+ @clk_time = zero.clk_time
1235
+ @clk_time.clk_time[-1] += second
1236
+ leap /= clock.second
1237
+ @universal_time = @local_time = When::Coordinates::LeapSeconds.new(@local_time-leap, leap, 1/clock.second)
1238
+ @dynamical_time -= leap
1239
+ end
1240
+ end
1241
+ end
1242
+
1243
+ # 後処理
1244
+ @keys |= @clk_time.keys
1245
+ end
1246
+
1247
+ # 加減算共通処理
1248
+ def _plus(period)
1249
+ # 日時の加算
1250
+ time = @clk_time.clk_time.dup
1251
+ pdate = @frame._arrange_length(period.date)
1252
+ ptime = clock._arrange_length(period.time)
1253
+ date = _date_with_era(@frame._validate(_date_without_era, pdate) {|jdn|
1254
+ time[0] += jdn
1255
+ time = clock._validate(time, ptime)
1256
+ jdn = time[0] * 1
1257
+ time[0] -= jdn
1258
+ jdn
1259
+ })
1260
+
1261
+ # オブジェクトの生成
1262
+ _frame_adjust(period, self.dup._copy({:date=>date, :time=>time, :validate=>:done, :events=>nil, :query=>nil}))
1263
+ end
1264
+ end
1265
+ end