when_exe 0.3.6 → 0.3.7
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 +7 -0
- data/README.md +171 -0
- data/lib/when_exe.rb +78 -47
- data/lib/when_exe/basictypes.rb +752 -747
- data/lib/when_exe/calendarnote.rb +805 -801
- data/lib/when_exe/calendartypes.rb +1583 -1531
- data/lib/when_exe/coordinates.rb +16 -15
- data/lib/when_exe/core/duration.rb +114 -110
- data/lib/when_exe/core/extension.rb +504 -504
- data/lib/when_exe/ephemeris.rb +1917 -1913
- data/lib/when_exe/ephemeris/moon.rb +333 -333
- data/lib/when_exe/ephemeris/notes.rb +389 -387
- data/lib/when_exe/ephemeris/planets.rb +585 -585
- data/lib/when_exe/ephemeris/sun.rb +214 -214
- data/lib/when_exe/googlecalendar.rb +144 -140
- data/lib/when_exe/icalendar.rb +1636 -1636
- data/lib/when_exe/inspect.rb +46 -22
- data/lib/when_exe/locales/akt.rb +176 -176
- data/lib/when_exe/locales/encoding_conversion.rb +134 -126
- data/lib/when_exe/locales/iast.rb +90 -90
- data/lib/when_exe/locales/locale.rb +750 -746
- data/lib/when_exe/locales/transliteration_table.rb +62 -62
- data/lib/when_exe/mini_application.rb +307 -305
- data/lib/when_exe/parts/enumerator.rb +2 -2
- data/lib/when_exe/parts/geometric_complex.rb +397 -397
- data/lib/when_exe/parts/method_cash.rb +224 -224
- data/lib/when_exe/parts/resource.rb +1069 -1071
- data/lib/when_exe/parts/timezone.rb +240 -230
- data/lib/when_exe/region/armenian.rb +56 -56
- data/lib/when_exe/region/babylonian.rb +405 -0
- data/lib/when_exe/region/bahai.rb +146 -146
- data/lib/when_exe/region/balinese.rb +622 -622
- data/lib/when_exe/region/chinese.rb +95 -25
- data/lib/when_exe/region/chinese/calendars.rb +1016 -1016
- data/lib/when_exe/region/chinese/epochs.rb +1 -1
- data/lib/when_exe/region/chinese/twins.rb +803 -795
- data/lib/when_exe/region/christian.rb +824 -824
- data/lib/when_exe/region/coptic.rb +106 -87
- data/lib/when_exe/region/discordian.rb +225 -225
- data/lib/when_exe/region/far_east.rb +188 -188
- data/lib/when_exe/region/french.rb +56 -56
- data/lib/when_exe/region/geologicalage.rb +639 -639
- data/lib/when_exe/region/goddess.rb +58 -58
- data/lib/when_exe/region/indian.rb +1254 -1251
- data/lib/when_exe/region/iranian.rb +8 -8
- data/lib/when_exe/region/islamic.rb +3 -3
- data/lib/when_exe/region/japanese.rb +93 -99
- data/lib/when_exe/region/japanese/calendars.rb +396 -397
- data/lib/when_exe/region/japanese/epochs.rb +26 -26
- data/lib/when_exe/region/japanese/nihon_shoki.rb +71 -71
- data/lib/when_exe/region/japanese/notes.rb +1383 -1386
- data/lib/when_exe/region/japanese/residues.rb +1306 -1306
- data/lib/when_exe/region/japanese/twins.rb +225 -225
- data/lib/when_exe/region/japanese/weeks.rb +112 -0
- data/lib/when_exe/region/javanese.rb +230 -230
- data/lib/when_exe/region/jewish.rb +126 -126
- data/lib/when_exe/region/korean.rb +378 -378
- data/lib/when_exe/region/m17n.rb +114 -113
- data/lib/when_exe/region/martian.rb +258 -255
- data/lib/when_exe/region/mayan.rb +32 -32
- data/lib/when_exe/region/residue.rb +89 -89
- data/lib/when_exe/region/roman.rb +36 -24
- data/lib/when_exe/region/ryukyu.rb +97 -97
- data/lib/when_exe/region/shire.rb +240 -240
- data/lib/when_exe/region/soviet.rb +209 -0
- data/lib/when_exe/region/symmetry.rb +50 -50
- data/lib/when_exe/region/thai.rb +336 -335
- data/lib/when_exe/region/tibetan.rb +316 -315
- data/lib/when_exe/region/vietnamese.rb +440 -439
- data/lib/when_exe/region/weekdate.rb +80 -80
- data/lib/when_exe/region/world.rb +175 -175
- data/lib/when_exe/region/yerm.rb +14 -14
- data/lib/when_exe/region/zoroastrian.rb +203 -203
- data/lib/when_exe/timestandard.rb +707 -681
- data/lib/when_exe/tmduration.rb +338 -330
- data/lib/when_exe/tmobjects.rb +1346 -1325
- data/lib/when_exe/tmposition.rb +2115 -2072
- data/lib/when_exe/tmreference.rb +1693 -1669
- data/lib/when_exe/version.rb +1 -1
- data/link_to_online_documents +1 -1
- data/test/examples/JapanHolidaysRFC6350.ics +1 -1
- data/test/test.rb +67 -61
- data/test/test/basictypes.rb +409 -409
- data/test/test/calendarnote.rb +86 -69
- data/test/test/calendartypes.rb +97 -97
- data/test/test/coordinates.rb +396 -396
- data/test/test/ephemeris.rb +83 -74
- data/test/test/ephemeris/moon.rb +14 -14
- data/test/test/ephemeris/planets.rb +14 -14
- data/test/test/ephemeris/sun.rb +14 -14
- data/test/test/googlecalendar.rb +194 -176
- data/test/test/icalendar.rb +867 -858
- data/test/test/inspect.rb +117 -117
- data/test/test/parts.rb +487 -487
- data/test/test/region/balinese.rb +34 -0
- data/test/test/region/chinese.rb +218 -206
- data/test/test/region/christian.rb +245 -245
- data/test/test/region/coptic.rb +27 -27
- data/test/test/region/french.rb +33 -33
- data/test/test/region/geologicalage.rb +17 -17
- data/test/test/region/indian.rb +57 -57
- data/test/test/region/iran.rb +54 -54
- data/test/test/region/islamic.rb +18 -18
- data/test/test/region/japanese.rb +237 -219
- data/test/test/region/jewish.rb +61 -61
- data/test/test/region/m17n.rb +184 -184
- data/test/test/region/mayan.rb +195 -195
- data/test/test/region/residue.rb +147 -139
- data/test/test/region/thai.rb +116 -116
- data/test/test/region/tibetan.rb +30 -30
- data/test/test/region/vietnamese.rb +102 -102
- data/test/test/region/yerm.rb +146 -146
- data/test/test/timestandard.rb +81 -81
- data/test/test/tmobjects.rb +328 -328
- data/test/test/tmposition.rb +397 -284
- data/test/test/tmreference.rb +157 -157
- metadata +13 -10
data/lib/when_exe/tmobjects.rb
CHANGED
|
@@ -1,1325 +1,1346 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
=begin
|
|
3
|
-
Copyright (C) 2011-2013 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
|
-
# (5.2) Temporal Objects Package
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
# 長さと距離を計算するための操作を規定する
|
|
16
|
-
#
|
|
17
|
-
module Separation
|
|
18
|
-
|
|
19
|
-
# When::TM::GeometricPrimitive 自身の持続時間
|
|
20
|
-
#
|
|
21
|
-
# @return [When::TM::Duration]
|
|
22
|
-
#
|
|
23
|
-
# @abstract
|
|
24
|
-
#
|
|
25
|
-
def length
|
|
26
|
-
raise TypeError, "Absolute Class #{self.class}"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# 他のWhen::TM::GeometricPrimitiveとの時間位置の差の絶対値
|
|
30
|
-
#
|
|
31
|
-
# @param [When::TM::GeometricPrimitive] other
|
|
32
|
-
#
|
|
33
|
-
# @return [When::TM::Duration]
|
|
34
|
-
#
|
|
35
|
-
# @abstract
|
|
36
|
-
#
|
|
37
|
-
def distance(other)
|
|
38
|
-
raise TypeError, "Absolute Class #{self.class}"
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
#
|
|
44
|
-
# 互いの相対位置を判定する操作を規定する
|
|
45
|
-
#
|
|
46
|
-
module Order
|
|
47
|
-
|
|
48
|
-
# 他のWhen::TM::Primitiveとの相対的な時間位置
|
|
49
|
-
#
|
|
50
|
-
# @param [When::TM::Primitive] other
|
|
51
|
-
#
|
|
52
|
-
# @return [When::TM::RelativePosition]
|
|
53
|
-
#
|
|
54
|
-
# @abstract
|
|
55
|
-
#
|
|
56
|
-
def relative_position(other)
|
|
57
|
-
raise TypeError, "Absolute Class #{self.class}"
|
|
58
|
-
end
|
|
59
|
-
alias :relativePosition :relative_position
|
|
60
|
-
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# 相対的な時間位置
|
|
64
|
-
#
|
|
65
|
-
# Allen(1983) が分類した13種類の相対的な時間位置を定義している
|
|
66
|
-
#
|
|
67
|
-
# ISO19108では値は Code クラスだが、本実装では値は Symbol である
|
|
68
|
-
#
|
|
69
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#RelatedTimeType gml schema}
|
|
70
|
-
#
|
|
71
|
-
# see Allen,J.F., Maintaining Knowledge about Temporal Intervals, Communications of the ACM, 1983,vol.26 pp.832-843
|
|
72
|
-
#
|
|
73
|
-
module RelativePosition
|
|
74
|
-
|
|
75
|
-
Before = :Before
|
|
76
|
-
After = :After
|
|
77
|
-
Begins = :Begins
|
|
78
|
-
Ends = :Ends
|
|
79
|
-
During = :During
|
|
80
|
-
Equals = :Equals
|
|
81
|
-
Contains = :Contains
|
|
82
|
-
Overlaps = :Overlaps
|
|
83
|
-
Meets = :Meets
|
|
84
|
-
OverlappedBy = :OverlappedBy
|
|
85
|
-
MetBy = :MetBy
|
|
86
|
-
BegunBy = :BegunBy
|
|
87
|
-
EndedBy = :EndedBy
|
|
88
|
-
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# 時間のオブジェクト
|
|
92
|
-
#
|
|
93
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimeObjectType gml schema}
|
|
94
|
-
#
|
|
95
|
-
class Object < When::BasicTypes::Object
|
|
96
|
-
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# 複数の時間プリミティブの集成
|
|
100
|
-
#
|
|
101
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimeComplexType gml schema}
|
|
102
|
-
#
|
|
103
|
-
class Complex < Object
|
|
104
|
-
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
# 位相複体 - 連結した位相プリミティブの集合
|
|
108
|
-
#
|
|
109
|
-
# A temporal topology complex.
|
|
110
|
-
#
|
|
111
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#TimeTopologyComplexType gml schema}
|
|
112
|
-
#
|
|
113
|
-
class TopologicalComplex < Complex
|
|
114
|
-
|
|
115
|
-
# 対応するプリミティブ (relation - Complex)
|
|
116
|
-
#
|
|
117
|
-
# @return [Array<When::TM::TopologicalPrimitive>]
|
|
118
|
-
#
|
|
119
|
-
attr_reader :primitive
|
|
120
|
-
|
|
121
|
-
# オブジェクトの生成
|
|
122
|
-
#
|
|
123
|
-
# @param [When::TM::TopologicalPrimitive] primitive 対応するプリミティブの Array
|
|
124
|
-
#
|
|
125
|
-
def initialize(primitive)
|
|
126
|
-
@primitive = primitive
|
|
127
|
-
@primitive.each do |p|
|
|
128
|
-
p.complex << self
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# 時間プリミティブ
|
|
134
|
-
#
|
|
135
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimePrimitiveType gml schema}
|
|
136
|
-
#
|
|
137
|
-
class Primitive < Object
|
|
138
|
-
|
|
139
|
-
include Order
|
|
140
|
-
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# 時間幾何プリミティブ
|
|
144
|
-
#
|
|
145
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimeGeometricPrimitiveType gml schema}
|
|
146
|
-
#
|
|
147
|
-
class GeometricPrimitive < Primitive
|
|
148
|
-
|
|
149
|
-
include Separation
|
|
150
|
-
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# 瞬間 - 零次元幾何プリミティブ
|
|
154
|
-
#
|
|
155
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimeInstantType gml schema}
|
|
156
|
-
#
|
|
157
|
-
class Instant < GeometricPrimitive
|
|
158
|
-
|
|
159
|
-
# この瞬間の時間位置
|
|
160
|
-
#
|
|
161
|
-
# @return [When::TM::Position]
|
|
162
|
-
#
|
|
163
|
-
attr_reader :position
|
|
164
|
-
|
|
165
|
-
# この瞬間を始まりとする期間 (relation - Beginning)
|
|
166
|
-
#
|
|
167
|
-
# @return [Array<When::TM::Period>]
|
|
168
|
-
#
|
|
169
|
-
attr_reader :begun_by
|
|
170
|
-
alias :begunBy :begun_by
|
|
171
|
-
|
|
172
|
-
# この瞬間を終わりとする期間 (relation - Ending)
|
|
173
|
-
#
|
|
174
|
-
# @return [Array<When::TM::Period>]
|
|
175
|
-
#
|
|
176
|
-
attr_reader :ended_by
|
|
177
|
-
alias :endedBy :ended_by
|
|
178
|
-
|
|
179
|
-
# 対応するノード (relation - Realization)
|
|
180
|
-
#
|
|
181
|
-
# @return [When::TM::Node]
|
|
182
|
-
#
|
|
183
|
-
attr_reader :topology
|
|
184
|
-
|
|
185
|
-
# When::TM::GeometricPrimitive 自身の持続時間
|
|
186
|
-
#
|
|
187
|
-
# @return [When::TM::Duration]
|
|
188
|
-
#
|
|
189
|
-
def length()
|
|
190
|
-
return When.Duration(0)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
# 他のWhen::TM::GeometricPrimitiveとの時間位置の差の絶対値
|
|
194
|
-
#
|
|
195
|
-
# @param [When::TM::GeometricPrimitive] other
|
|
196
|
-
#
|
|
197
|
-
# @return [When::TM::Duration]
|
|
198
|
-
#
|
|
199
|
-
def distance(other)
|
|
200
|
-
case other
|
|
201
|
-
when Instant
|
|
202
|
-
return (self.position - other.position).abs
|
|
203
|
-
when Period
|
|
204
|
-
verify = other.begin.position - self.position
|
|
205
|
-
return verify if verify.sign >= 0
|
|
206
|
-
return [self.position - other.end.position, When::TM::PeriodDuration.new(0,When::DAY)].max
|
|
207
|
-
else
|
|
208
|
-
raise TypeError, "The right operand should be When::TM::Instant or When::TM::Period"
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
# 他のWhen::TM::Primitiveとの相対的な時間位置
|
|
213
|
-
#
|
|
214
|
-
# @param [When::TM::Primitive] other
|
|
215
|
-
#
|
|
216
|
-
# @return [When::TM::RelativePosition]
|
|
217
|
-
#
|
|
218
|
-
def relative_position(other)
|
|
219
|
-
case other
|
|
220
|
-
when Instant
|
|
221
|
-
verify = self.position <=> other.position
|
|
222
|
-
return RelativePosition::Before if verify < 0
|
|
223
|
-
return RelativePosition::Equals if verify == 0
|
|
224
|
-
return RelativePosition::After
|
|
225
|
-
when Period
|
|
226
|
-
verify = self.position <=> other.begin.position
|
|
227
|
-
return RelativePosition::Before if verify < 0
|
|
228
|
-
return RelativePosition::Begins if verify == 0
|
|
229
|
-
verify = self.position <=> other.end.position
|
|
230
|
-
return RelativePosition::During if verify < 0
|
|
231
|
-
return RelativePosition::Ends if verify == 0
|
|
232
|
-
return RelativePosition::After
|
|
233
|
-
else
|
|
234
|
-
raise TypeError, "The right operand should be When::TM::Instant or When::TM::Period"
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
alias :relativePosition :relative_position
|
|
238
|
-
|
|
239
|
-
# オブジェクトの生成
|
|
240
|
-
#
|
|
241
|
-
# @param [When::TM::Position] position 対応する時間位置
|
|
242
|
-
#
|
|
243
|
-
def initialize(position)
|
|
244
|
-
@position = position
|
|
245
|
-
@begun_by = []
|
|
246
|
-
@ended_by = []
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
private
|
|
250
|
-
|
|
251
|
-
# その他のメソッド
|
|
252
|
-
#
|
|
253
|
-
# @note
|
|
254
|
-
# When::TM::Instant で定義されていないメソッドは
|
|
255
|
-
# 処理を @position (type: When::TM::Position) に委譲する
|
|
256
|
-
#
|
|
257
|
-
def method_missing(name, *args, &block)
|
|
258
|
-
self.class.module_eval %Q{
|
|
259
|
-
def #{name}(*args, &block)
|
|
260
|
-
list = args.map {|arg| arg.kind_of?(self.class) ? arg.position : arg}
|
|
261
|
-
@position.send("#{name}", *list, &block)
|
|
262
|
-
end
|
|
263
|
-
} unless When::Parts::MethodCash.escape(name)
|
|
264
|
-
list = args.map {|arg| arg.kind_of?(self.class) ? arg.position : arg}
|
|
265
|
-
@position.send(name, *list, &block)
|
|
266
|
-
end
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
# 期間 - 一次元幾何プリミティブ
|
|
270
|
-
#
|
|
271
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimePeriodType gml schema}
|
|
272
|
-
#
|
|
273
|
-
class Period < GeometricPrimitive
|
|
274
|
-
|
|
275
|
-
RELATIVE_POSITION = {
|
|
276
|
-
RelativePosition::Contains => {
|
|
277
|
-
RelativePosition::Before => RelativePosition::Overlaps,
|
|
278
|
-
RelativePosition::EndedBy => RelativePosition::EndedBy,
|
|
279
|
-
RelativePosition::Contains => RelativePosition::Contains
|
|
280
|
-
},
|
|
281
|
-
RelativePosition::BegunBy => {
|
|
282
|
-
RelativePosition::Before => RelativePosition::Begins,
|
|
283
|
-
RelativePosition::EndedBy => RelativePosition::Equals,
|
|
284
|
-
RelativePosition::Contains => RelativePosition::BegunBy
|
|
285
|
-
},
|
|
286
|
-
RelativePosition::After => {
|
|
287
|
-
RelativePosition::Before => RelativePosition::During,
|
|
288
|
-
RelativePosition::EndedBy => RelativePosition::Ends,
|
|
289
|
-
RelativePosition::Contains => RelativePosition::OverlappedBy
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
# この期間が始まる瞬間 (relation - Beginning)
|
|
294
|
-
#
|
|
295
|
-
# @return [When::TM::Instant]
|
|
296
|
-
#
|
|
297
|
-
attr_reader :begin
|
|
298
|
-
|
|
299
|
-
# この期間が終わる瞬間 (relation - Ending)
|
|
300
|
-
#
|
|
301
|
-
# @return [When::TM::Instant]
|
|
302
|
-
#
|
|
303
|
-
attr_reader :end
|
|
304
|
-
|
|
305
|
-
# 対応するエッジ (relation - Realization)
|
|
306
|
-
#
|
|
307
|
-
# @return [When::TM::Edge]
|
|
308
|
-
#
|
|
309
|
-
attr_reader :topology
|
|
310
|
-
|
|
311
|
-
# When::TM::GeometricPrimitive 自身の持続時間
|
|
312
|
-
#
|
|
313
|
-
# @return [When::TM::Duration]
|
|
314
|
-
#
|
|
315
|
-
def length()
|
|
316
|
-
@length ||= @end - @begin
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
# 他のWhen::TM::GeometricPrimitiveとの時間位置の差の絶対値
|
|
320
|
-
#
|
|
321
|
-
# @param [When::TM::GeometricPrimitive] other
|
|
322
|
-
#
|
|
323
|
-
# @return [When::TM::Duration]
|
|
324
|
-
#
|
|
325
|
-
def distance(other)
|
|
326
|
-
case other
|
|
327
|
-
when Instant
|
|
328
|
-
return other.distance(self)
|
|
329
|
-
when Period
|
|
330
|
-
verify = other.begin.position - self.end.position
|
|
331
|
-
return verify if verify.sign >= 0
|
|
332
|
-
return [self.begin.position - other.end.position, When::TM::PeriodDuration.new(0,When::DAY)].max
|
|
333
|
-
else
|
|
334
|
-
raise TypeError, "The right operand should be Instant or Period"
|
|
335
|
-
end
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
# 他のPrimitiveとの相対的な時間位置
|
|
339
|
-
#
|
|
340
|
-
# @param [When::TM::Primitive] other
|
|
341
|
-
#
|
|
342
|
-
# @return [When::TM::RelativePosition]
|
|
343
|
-
#
|
|
344
|
-
def relative_position(other)
|
|
345
|
-
case other
|
|
346
|
-
when Instant
|
|
347
|
-
verify = self.end.position <=> other.position
|
|
348
|
-
return RelativePosition::Before if verify < 0
|
|
349
|
-
return RelativePosition::EndedBy if verify == 0
|
|
350
|
-
verify = self.begin.position <=> other.position
|
|
351
|
-
return RelativePosition::Contains if verify < 0
|
|
352
|
-
return RelativePosition::BegunBy if verify == 0
|
|
353
|
-
return RelativePosition::After
|
|
354
|
-
when Period
|
|
355
|
-
verify_b = relative_position(other.begin)
|
|
356
|
-
case verify_b
|
|
357
|
-
when RelativePosition::Before ; return RelativePosition::Before
|
|
358
|
-
when RelativePosition::EndedBy ; return RelativePosition::Meets
|
|
359
|
-
end
|
|
360
|
-
verify_e = relative_position(other.end)
|
|
361
|
-
case verify_e
|
|
362
|
-
when RelativePosition::BegunBy ; return RelativePosition::MetBy
|
|
363
|
-
when RelativePosition::After ; return RelativePosition::After
|
|
364
|
-
else ; return RELATIVE_POSITION[verify_b][verify_e]
|
|
365
|
-
end
|
|
366
|
-
else
|
|
367
|
-
raise TypeError, "The right operand should be Instant or Period"
|
|
368
|
-
end
|
|
369
|
-
end
|
|
370
|
-
alias :relativePosition :relative_position
|
|
371
|
-
|
|
372
|
-
# オブジェクトの生成
|
|
373
|
-
#
|
|
374
|
-
# @param [When::TM::Instant] begun 始点
|
|
375
|
-
#
|
|
376
|
-
# @param [When::TM::Instant] ended 終点
|
|
377
|
-
#
|
|
378
|
-
def initialize(begun, ended)
|
|
379
|
-
raise ArgumentError, 'Order mismatch: begun > ended' if begun > ended
|
|
380
|
-
@begin = begun
|
|
381
|
-
@end = ended
|
|
382
|
-
@begin.begun_by << self
|
|
383
|
-
@end.ended_by << self
|
|
384
|
-
end
|
|
385
|
-
|
|
386
|
-
private
|
|
387
|
-
|
|
388
|
-
# その他のメソッド
|
|
389
|
-
#
|
|
390
|
-
# @note
|
|
391
|
-
# When::TM::Period で定義されていないメソッドは
|
|
392
|
-
# 処理を @begin (type: When::TM::Instant) に委譲する
|
|
393
|
-
#
|
|
394
|
-
def method_missing(name, *args, &block)
|
|
395
|
-
self.class.module_eval %Q{
|
|
396
|
-
def #{name}(*args, &block)
|
|
397
|
-
@begin.send("#{name}", *args, &block)
|
|
398
|
-
end
|
|
399
|
-
} unless When::Parts::MethodCash.escape(name)
|
|
400
|
-
@begin.send(name, *args, &block)
|
|
401
|
-
end
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
# 時間位相プリミティブ - 単独で不可分な位相要素
|
|
405
|
-
#
|
|
406
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#AbstractTimeTopologyPrimitiveType gml schema}
|
|
407
|
-
#
|
|
408
|
-
class TopologicalPrimitive < Primitive
|
|
409
|
-
|
|
410
|
-
# 対応するコンプレックス (relation - Complex)
|
|
411
|
-
#
|
|
412
|
-
# @return [Array<When::TM::TopologicalComplex>]
|
|
413
|
-
#
|
|
414
|
-
attr_accessor :complex
|
|
415
|
-
|
|
416
|
-
#
|
|
417
|
-
# オブジェクトの生成
|
|
418
|
-
#
|
|
419
|
-
def initialize
|
|
420
|
-
@complex = []
|
|
421
|
-
end
|
|
422
|
-
|
|
423
|
-
private
|
|
424
|
-
|
|
425
|
-
alias :_method_missing :method_missing
|
|
426
|
-
|
|
427
|
-
# その他のメソッド
|
|
428
|
-
#
|
|
429
|
-
# @note
|
|
430
|
-
# When::TM::TopologicalPrimitive で定義されていないメソッドは
|
|
431
|
-
# 処理を @geometry (type: When::TM::Instant) に委譲する
|
|
432
|
-
#
|
|
433
|
-
def method_missing(name, *args, &block)
|
|
434
|
-
return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name) ||
|
|
435
|
-
!respond_to?(:geometry)
|
|
436
|
-
self.class.module_eval %Q{
|
|
437
|
-
def #{name}(*args, &block)
|
|
438
|
-
list = args.map {|arg| arg.respond_to?(:geometry) ? arg.geometry : arg}
|
|
439
|
-
geometry.send("#{name}", *list, &block)
|
|
440
|
-
end
|
|
441
|
-
} unless When::Parts::MethodCash.escape(name)
|
|
442
|
-
list = args.map {|arg| arg.respond_to?(:geometry) ? arg.geometry : arg}
|
|
443
|
-
geometry.send(name, *list, &block)
|
|
444
|
-
end
|
|
445
|
-
end
|
|
446
|
-
|
|
447
|
-
# 零次元位相プリミティブ - 幾何的実現は When::TM::Instant と対応する
|
|
448
|
-
#
|
|
449
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#TimeNodeType gml schema}
|
|
450
|
-
#
|
|
451
|
-
class Node < TopologicalPrimitive
|
|
452
|
-
|
|
453
|
-
# 対応するエッジ (relation - Termination)
|
|
454
|
-
#
|
|
455
|
-
# @return [Array<When::TM::Edge>]
|
|
456
|
-
#
|
|
457
|
-
attr_reader :previous_edge
|
|
458
|
-
alias :previousEdge :previous_edge
|
|
459
|
-
|
|
460
|
-
# 対応するエッジ (relation - Initiation)
|
|
461
|
-
#
|
|
462
|
-
# @return [Array<When::TM::Edge>]
|
|
463
|
-
#
|
|
464
|
-
attr_reader :next_edge
|
|
465
|
-
alias :nextEdge :next_edge
|
|
466
|
-
|
|
467
|
-
# 対応する瞬間 (relation - Realization)
|
|
468
|
-
#
|
|
469
|
-
# @return [When::TM::Instant]
|
|
470
|
-
#
|
|
471
|
-
attr_reader :geometry
|
|
472
|
-
|
|
473
|
-
# オブジェクトの生成
|
|
474
|
-
#
|
|
475
|
-
# @param [When::TM::Instant] geometry 対応する瞬間
|
|
476
|
-
#
|
|
477
|
-
def initialize(geometry)
|
|
478
|
-
super()
|
|
479
|
-
@previous_edge = []
|
|
480
|
-
@next_edge = []
|
|
481
|
-
@geometry = geometry
|
|
482
|
-
@geometry.topology = self
|
|
483
|
-
end
|
|
484
|
-
end
|
|
485
|
-
|
|
486
|
-
# 一次元位相プリミティブ - 幾何的実現は When::TM::Period と対応する
|
|
487
|
-
#
|
|
488
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#TimeEdgeType gml schema}
|
|
489
|
-
#
|
|
490
|
-
class Edge < TopologicalPrimitive
|
|
491
|
-
|
|
492
|
-
# 対応するノード (relation - Termination)
|
|
493
|
-
#
|
|
494
|
-
# @return [When::TM::Node]
|
|
495
|
-
#
|
|
496
|
-
attr_reader :end
|
|
497
|
-
|
|
498
|
-
# 対応するノード (relation - Initiation)
|
|
499
|
-
#
|
|
500
|
-
# @return [When::TM::Node]
|
|
501
|
-
#
|
|
502
|
-
attr_reader :start
|
|
503
|
-
|
|
504
|
-
# 対応する期間 (relation - Realization)
|
|
505
|
-
#
|
|
506
|
-
# @return [When::TM::Period]
|
|
507
|
-
#
|
|
508
|
-
attr_reader :geometry
|
|
509
|
-
|
|
510
|
-
# オブジェクトの生成
|
|
511
|
-
#
|
|
512
|
-
# @param [When::TM::Node] start 始点
|
|
513
|
-
#
|
|
514
|
-
# @param [When::TM::Node] ended 終点
|
|
515
|
-
#
|
|
516
|
-
def initialize(start, ended)
|
|
517
|
-
super()
|
|
518
|
-
@start = start
|
|
519
|
-
@end = ended
|
|
520
|
-
@geometry = Period.new(@start.geometry, @end.geometry)
|
|
521
|
-
@geometry.topology = self
|
|
522
|
-
@start.next_edge << self
|
|
523
|
-
@end.previous_edge << self
|
|
524
|
-
end
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
# 時間次元における長さ又は距離を記述するために使うデータ型
|
|
528
|
-
#
|
|
529
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#duration gml schema}
|
|
530
|
-
#
|
|
531
|
-
class Duration
|
|
532
|
-
|
|
533
|
-
#
|
|
534
|
-
# When::TM::IntervalLength への変換
|
|
535
|
-
#
|
|
536
|
-
# @return [When::TM::IntervalLength]
|
|
537
|
-
#
|
|
538
|
-
def to_interval_length
|
|
539
|
-
[['week', WEEK], ['day', DAY], ['hour', HOUR], ['minute', MINUTE], ['second', SECOND]].each do |unit|
|
|
540
|
-
div, mod = duration.divmod(unit[1])
|
|
541
|
-
return When::TM::IntervalLength.new(div, unit[0]) if mod == 0
|
|
542
|
-
end
|
|
543
|
-
When::TM::IntervalLength.new(duration / SECOND, 'second')
|
|
544
|
-
end
|
|
545
|
-
|
|
546
|
-
#
|
|
547
|
-
# When::TM::PeriodDuration への変換
|
|
548
|
-
#
|
|
549
|
-
# @return [When::TM::PeriodDuration]
|
|
550
|
-
#
|
|
551
|
-
def to_period_duration
|
|
552
|
-
[[When::WEEK, WEEK], [When::DAY, DAY], [When::HOUR, HOUR], [When::MINUTE, MINUTE], [When::SECOND, SECOND]].each do |unit|
|
|
553
|
-
div, mod = duration.divmod(unit[1])
|
|
554
|
-
return When::TM::PeriodDuration.new(div, unit[0]) if mod == 0
|
|
555
|
-
end
|
|
556
|
-
When::TM::PeriodDuration.new(duration / SECOND, When::SECOND)
|
|
557
|
-
end
|
|
558
|
-
|
|
559
|
-
#
|
|
560
|
-
# Duration 用の Enumerator
|
|
561
|
-
#
|
|
562
|
-
class Enumerator < When::Parts::Enumerator
|
|
563
|
-
|
|
564
|
-
# 次の時間位置を取得する
|
|
565
|
-
#
|
|
566
|
-
# @return [When::TM::TemporalPosition] 次の時間位置
|
|
567
|
-
#
|
|
568
|
-
def succ
|
|
569
|
-
value = @current
|
|
570
|
-
@current = (@count_limit.kind_of?(Numeric) && @count >= @count_limit) ? nil :
|
|
571
|
-
(@current==:first) ? @first :
|
|
572
|
-
(@direction==:forward) ? @first + @parent * @count : @first - @parent * @count
|
|
573
|
-
@count += 1
|
|
574
|
-
return value
|
|
575
|
-
end
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
# Enumerator の生成
|
|
579
|
-
#
|
|
580
|
-
# @overload initialize(range, count_limit=nil))
|
|
581
|
-
# @param [Range, When::Parts::GeometricComplex] range
|
|
582
|
-
# [ 始点 - range.first ]
|
|
583
|
-
# [ 終点 - range.last ]
|
|
584
|
-
# @param [Integer] count_limit 繰り返し回数(デフォルトは指定なし)
|
|
585
|
-
#
|
|
586
|
-
# @overload initialize(first, direction, count_limit=nil))
|
|
587
|
-
# @param [When::TM::TemporalPosition] first 始点
|
|
588
|
-
# @param [Symbol] direction
|
|
589
|
-
# [ :forward - 昇順 ]
|
|
590
|
-
# [ :reverse - 降順 ]
|
|
591
|
-
# @param [Integer] count_limit 繰り返し回数(デフォルトは指定なし)
|
|
592
|
-
#
|
|
593
|
-
def _enumerator(*args)
|
|
594
|
-
return Enumerator.new(*args.unshift(self))
|
|
595
|
-
end
|
|
596
|
-
alias :to_enum :_enumerator
|
|
597
|
-
alias :enum_for :_enumerator
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
#
|
|
601
|
-
# ISO 11404 の時間間隔に基づいて定義された When::TM::Duration の subclass
|
|
602
|
-
#
|
|
603
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#timeIntervalLengthType gml schema}
|
|
604
|
-
#
|
|
605
|
-
class IntervalLength < Duration
|
|
606
|
-
|
|
607
|
-
Alias = {'Y'=>'year', 'M'=>'month' , 'D'=>'day', 'W'=>'week', 'S'=>'system',
|
|
608
|
-
'h'=>'hour', 'm'=>'minute', 's'=>'second'}
|
|
609
|
-
|
|
610
|
-
# Interval Length 形式の表現を分解して配列化する
|
|
611
|
-
#
|
|
612
|
-
# @param [String] interval
|
|
613
|
-
#
|
|
614
|
-
# @return [Array<Numeric, String>] ( value, unit_name, factor, radix )
|
|
615
|
-
# [ value [Numeric] - 時間間隔 / 単位 ]
|
|
616
|
-
# [ unit_name [String] - 単位名 ]
|
|
617
|
-
# [ factor [Numeric] - 冪乗 ]
|
|
618
|
-
# [ radix [Numeric] - 冪乗の基数 ]
|
|
619
|
-
#
|
|
620
|
-
# @note value, factor, radix は Numeric
|
|
621
|
-
#
|
|
622
|
-
def self._to_array(interval)
|
|
623
|
-
return nil unless interval =~
|
|
624
|
-
value, radix, radix_quantity, factor, unit, unit_quantity = $~[1..6]
|
|
625
|
-
value = When::Coordinates::Pair._en_number(value)
|
|
626
|
-
radix = case radix
|
|
627
|
-
when 'E', nil ; 10
|
|
628
|
-
when 'X' ; 60
|
|
629
|
-
else ; radix_quantity.to_i
|
|
630
|
-
end
|
|
631
|
-
factor = factor ? -factor.to_i : 0
|
|
632
|
-
return [value, unit_quantity, factor, radix] if unit_quantity
|
|
633
|
-
unit_quantity = Unit[unit.downcase] || Unit[Alias[unit[0..0]]]
|
|
634
|
-
return [value, UnitName[unit_quantity], factor, radix] if unit_quantity
|
|
635
|
-
return nil
|
|
636
|
-
end
|
|
637
|
-
|
|
638
|
-
# 時間間隔の長さ (128秒単位)
|
|
639
|
-
#
|
|
640
|
-
# @return [Numeric]
|
|
641
|
-
#
|
|
642
|
-
protected :duration=
|
|
643
|
-
|
|
644
|
-
# 時間間隔を表現するために使用した測定単位の名称
|
|
645
|
-
#
|
|
646
|
-
# @return [String] (year|month|week|day|hour|minute|second|system)
|
|
647
|
-
#
|
|
648
|
-
attr_reader :unit
|
|
649
|
-
|
|
650
|
-
# 時間単位となる乗数の基底となる正の整数
|
|
651
|
-
#
|
|
652
|
-
# @return [Integer]
|
|
653
|
-
#
|
|
654
|
-
attr_reader :radix
|
|
655
|
-
|
|
656
|
-
# 基底のべき乗を行う指数
|
|
657
|
-
#
|
|
658
|
-
# @return [Integer]
|
|
659
|
-
#
|
|
660
|
-
attr_reader :factor
|
|
661
|
-
|
|
662
|
-
# 時間間隔の長さ / 測定単位
|
|
663
|
-
#
|
|
664
|
-
# @return [Numeric]
|
|
665
|
-
#
|
|
666
|
-
attr_accessor :value
|
|
667
|
-
protected :value=
|
|
668
|
-
|
|
669
|
-
#
|
|
670
|
-
# 測定単位の大きさ
|
|
671
|
-
#
|
|
672
|
-
# @return [Numeric]
|
|
673
|
-
#
|
|
674
|
-
attr_reader :unit_quantity
|
|
675
|
-
|
|
676
|
-
# 時刻配列
|
|
677
|
-
#
|
|
678
|
-
# @return [Numeric]
|
|
679
|
-
# When::TM::PeriodDuration との互換性のために提供
|
|
680
|
-
#
|
|
681
|
-
# @private
|
|
682
|
-
#
|
|
683
|
-
def time
|
|
684
|
-
[0, 0, @duration / SECOND]
|
|
685
|
-
end
|
|
686
|
-
|
|
687
|
-
# 日付配列
|
|
688
|
-
#
|
|
689
|
-
# @return [nil]
|
|
690
|
-
# When::TM::PeriodDuration との互換性のために提供
|
|
691
|
-
#
|
|
692
|
-
# @private
|
|
693
|
-
#
|
|
694
|
-
def date
|
|
695
|
-
nil
|
|
696
|
-
end
|
|
697
|
-
|
|
698
|
-
# 暦週配列
|
|
699
|
-
#
|
|
700
|
-
# @return [nil]
|
|
701
|
-
# When::TM::PeriodDuration との互換性のために提供
|
|
702
|
-
#
|
|
703
|
-
# @private
|
|
704
|
-
#
|
|
705
|
-
def weeks
|
|
706
|
-
nil
|
|
707
|
-
end
|
|
708
|
-
|
|
709
|
-
# 符号反転
|
|
710
|
-
#
|
|
711
|
-
# @return [When::TM::IntervalLength]
|
|
712
|
-
#
|
|
713
|
-
def -@
|
|
714
|
-
interval = self.dup
|
|
715
|
-
interval.value = -@value
|
|
716
|
-
interval.duration = -@duration
|
|
717
|
-
return interval
|
|
718
|
-
end
|
|
719
|
-
|
|
720
|
-
#
|
|
721
|
-
# 加算
|
|
722
|
-
#
|
|
723
|
-
# @param [When::TM::Duration] other
|
|
724
|
-
# @param [Numeric] other 秒数
|
|
725
|
-
# @param [その他] other 日時とみなす
|
|
726
|
-
#
|
|
727
|
-
# @return [When::TM::IntervalLength] (other が Numeric, When::TM::Duration の場合)
|
|
728
|
-
# @return [other と同じクラス] (other がその他の場合)
|
|
729
|
-
#
|
|
730
|
-
def +(other)
|
|
731
|
-
case other
|
|
732
|
-
when Duration ; diff = other.duration
|
|
733
|
-
when Numeric ; diff = other * SECOND
|
|
734
|
-
else ; return other + self
|
|
735
|
-
end
|
|
736
|
-
interval = self.dup
|
|
737
|
-
interval.duration = @duration + diff
|
|
738
|
-
internal.value = interval.duration / (@radix ** (-@factor) * @unit_quantity)
|
|
739
|
-
return interval
|
|
740
|
-
end
|
|
741
|
-
|
|
742
|
-
#
|
|
743
|
-
# 減算
|
|
744
|
-
#
|
|
745
|
-
# @param [When::TM::IntervalLength] other
|
|
746
|
-
# @param [Numeric] other 秒数
|
|
747
|
-
#
|
|
748
|
-
# @return [When::TM::IntervalLength]
|
|
749
|
-
#
|
|
750
|
-
def -(other)
|
|
751
|
-
interval = self.dup
|
|
752
|
-
interval.duration = @duration - (other.kind_of?(Duration) ? other.duration : other * SECOND)
|
|
753
|
-
internal.value = interval.duration / (@radix ** (-@factor) * @unit_quantity)
|
|
754
|
-
return interval
|
|
755
|
-
end
|
|
756
|
-
|
|
757
|
-
# 乗算
|
|
758
|
-
#
|
|
759
|
-
# @param [Numeric] times
|
|
760
|
-
#
|
|
761
|
-
# @return [When::TM::IntervalLength]
|
|
762
|
-
#
|
|
763
|
-
def *(times)
|
|
764
|
-
interval = self.dup
|
|
765
|
-
interval.value = times * @value
|
|
766
|
-
interval.duration = times * @duration
|
|
767
|
-
return interval
|
|
768
|
-
end
|
|
769
|
-
|
|
770
|
-
#
|
|
771
|
-
# 除算
|
|
772
|
-
#
|
|
773
|
-
# @param [When::TM::IntervalLength] other
|
|
774
|
-
# @param [Numeric] other 秒数
|
|
775
|
-
#
|
|
776
|
-
# @return [When::TM::IntervalLength] (other が Numeric の場合)
|
|
777
|
-
# @return [Numeric] (other が When::TM::Duration の場合)
|
|
778
|
-
#
|
|
779
|
-
def /(other)
|
|
780
|
-
other.kind_of?(Duration) ? @duration / other.duration : self * (1.0 / other)
|
|
781
|
-
end
|
|
782
|
-
|
|
783
|
-
# 文字列化
|
|
784
|
-
#
|
|
785
|
-
# @return [String]
|
|
786
|
-
#
|
|
787
|
-
def to_s
|
|
788
|
-
expression = @value.to_s
|
|
789
|
-
unless @factor == 0
|
|
790
|
-
case @radix
|
|
791
|
-
when 10 ; expression += 'E'
|
|
792
|
-
when 60 ; expression += 'X'
|
|
793
|
-
else ; expression += '(%d)' % @radix
|
|
794
|
-
end
|
|
795
|
-
expression += '%+d' % (-@factor)
|
|
796
|
-
end
|
|
797
|
-
expression += Alias.invert[@unit] || "*#{When::Coordinates::Pair._en_number(@unit)}S"
|
|
798
|
-
return expression
|
|
799
|
-
end
|
|
800
|
-
|
|
801
|
-
#
|
|
802
|
-
# When::TM::IntervalLength への変換
|
|
803
|
-
#
|
|
804
|
-
# 単なるオブジェクトのコピー
|
|
805
|
-
#
|
|
806
|
-
# @return [When::TM::IntervalLength]
|
|
807
|
-
#
|
|
808
|
-
def to_interval_length
|
|
809
|
-
self.dup
|
|
810
|
-
end
|
|
811
|
-
|
|
812
|
-
# オブジェクトの生成
|
|
813
|
-
#
|
|
814
|
-
# @param [Numeric] value 時間間隔の長さ / 測定単位(省略不可)
|
|
815
|
-
# @param [String] unit 時間間隔を表現するために使用した測定単位の名称(デフォルト : system)
|
|
816
|
-
# ('year'|'month'|'week'|'day'|'hour'|'minute'|'second'|'system')
|
|
817
|
-
# @param [Integer] factor 基底の冪乗を行う指数(デフォルト : 0)
|
|
818
|
-
# @param [Integer] radix 時間単位となる乗数の基底となる正の整数(デフォルト : 10)
|
|
819
|
-
#
|
|
820
|
-
def initialize(value, unit='system', factor=0, radix=10)
|
|
821
|
-
@value, @factor, @radix = value, factor, radix
|
|
822
|
-
@unit_quantity = Unit[unit.downcase] || Unit[Alias[unit[0..0]]] if unit.kind_of?(String)
|
|
823
|
-
@unit_quantity ||= unit.to_f
|
|
824
|
-
raise TypeError, "Wrong Unit Type: #{unit}" unless @unit_quantity.kind_of?(Numeric)
|
|
825
|
-
@unit = UnitName[@unit_quantity] ||
|
|
826
|
-
When::Coordinates::Pair._en_number(@unit_quantity).to_s
|
|
827
|
-
@duration = @value * @radix ** (-@factor) * @unit_quantity
|
|
828
|
-
end
|
|
829
|
-
|
|
830
|
-
# オブジェクトの生成(終点と始点を指定)
|
|
831
|
-
#
|
|
832
|
-
# @param [When::TM::TemporalPosition] ended 終点
|
|
833
|
-
# @param [When::TM::TemporalPosition] begun 始点
|
|
834
|
-
#
|
|
835
|
-
# @return [When::TM::IntervalLength]
|
|
836
|
-
# [ 日単位の精度 - 終点と始点の分解能のいずれかが“日”またはそれより粗い場合 ]
|
|
837
|
-
# [ システム精度 - 終点と始点の分解能がともに“日”より細かい場合 ]
|
|
838
|
-
#
|
|
839
|
-
def self.difference(ended, begun)
|
|
840
|
-
precision = [ended.precision, begun.precision].min
|
|
841
|
-
return new(ended-begun) if precision > When::DAY
|
|
842
|
-
return new(ended.to_i - begun.to_i, unit='day')
|
|
843
|
-
end
|
|
844
|
-
|
|
845
|
-
private
|
|
846
|
-
|
|
847
|
-
# その他のメソッド
|
|
848
|
-
#
|
|
849
|
-
# @note
|
|
850
|
-
# When::TM::IntervalLength で定義されていないメソッドは
|
|
851
|
-
# 処理を @duration (type:Numeric) に委譲する
|
|
852
|
-
#
|
|
853
|
-
def method_missing(name, *args, &block)
|
|
854
|
-
self.class.module_eval %Q{
|
|
855
|
-
def #{name}(*args, &block)
|
|
856
|
-
@duration.send("#{name}", *args, &block)
|
|
857
|
-
end
|
|
858
|
-
} unless When::Parts::MethodCash.escape(name)
|
|
859
|
-
@duration.send(name, *args, &block)
|
|
860
|
-
end
|
|
861
|
-
end
|
|
862
|
-
|
|
863
|
-
#
|
|
864
|
-
# ISO 8601 (JIS X0301) の時間間隔に基づいて定義された When::TM::Duration の subclass
|
|
865
|
-
#
|
|
866
|
-
class PeriodDuration < Duration
|
|
867
|
-
|
|
868
|
-
include When
|
|
869
|
-
include Coordinates
|
|
870
|
-
|
|
871
|
-
#
|
|
872
|
-
# When::TM::PeriodDuration オブジェクトが月や年などの可変長の単位に依存する場合
|
|
873
|
-
# に @duration 属性の参照を禁止するために用いる
|
|
874
|
-
#
|
|
875
|
-
module NoDuration
|
|
876
|
-
#
|
|
877
|
-
# 属性 @duration が定義できないとをエラーで示す
|
|
878
|
-
#
|
|
879
|
-
# @return [Numeric]
|
|
880
|
-
#
|
|
881
|
-
def duration
|
|
882
|
-
raise TypeError, "This PeriodDuration object does't have duration value"
|
|
883
|
-
end
|
|
884
|
-
end
|
|
885
|
-
|
|
886
|
-
# ISO 8601 形式の表現を分解して配列化する
|
|
887
|
-
#
|
|
888
|
-
# @param [String] period
|
|
889
|
-
#
|
|
890
|
-
# @return [Array<Numeric, Array<Numeric>>] ( sign, date, time, week )
|
|
891
|
-
# [ sign [Numeric] - +1 , -1 ]
|
|
892
|
-
# [ date [Array<Numeric>] - 年月日 ]
|
|
893
|
-
# [ time [Array<Numeric>] - 時分秒 ]
|
|
894
|
-
# [ week [Array<Numeric>] - 週日 ]
|
|
895
|
-
#
|
|
896
|
-
def self._to_array(period)
|
|
897
|
-
|
|
898
|
-
return nil unless period.gsub(/_+/, '') =~
|
|
899
|
-
|
|
900
|
-
sign = ($1 == '-') ? -1 : +1
|
|
901
|
-
pdate, ptime = $~[2..3]
|
|
902
|
-
|
|
903
|
-
# 時分秒形式
|
|
904
|
-
if (ptime =~
|
|
905
|
-
trunk = [1,3,5].map {|i|
|
|
906
|
-
$~[i] ? Pair._en_pair($~[i], $~[i+1]) : 0
|
|
907
|
-
}
|
|
908
|
-
extra = $7 ? $7.scan(/([.,\d]+)?([:*=])?X/).map {|d|
|
|
909
|
-
d[0] ? Pair._en_pair(d[0], d[1]) : 0
|
|
910
|
-
} : []
|
|
911
|
-
time = [0] + trunk + extra
|
|
912
|
-
time = nil if time.uniq == [0]
|
|
913
|
-
end
|
|
914
|
-
|
|
915
|
-
case pdate
|
|
916
|
-
# 年月日形式
|
|
917
|
-
when
|
|
918
|
-
trunk = [2,4,6].map {|i|
|
|
919
|
-
$~[i] ? Pair._en_pair($~[i], $~[i+1]) : 0
|
|
920
|
-
}
|
|
921
|
-
extra = $1 ? $1.scan(/([.,\d]+)?([:*=])?X/).map {|d|
|
|
922
|
-
d[0] ? Pair._en_pair(d[0], d[1]) : 0
|
|
923
|
-
} : []
|
|
924
|
-
date = extra + trunk
|
|
925
|
-
date = nil if date.uniq == [0]
|
|
926
|
-
return sign, date, time
|
|
927
|
-
|
|
928
|
-
# 週日形式
|
|
929
|
-
when
|
|
930
|
-
week = [1,3].map {|i|
|
|
931
|
-
$~[i] ? Pair._en_pair($~[i], $~[i+1]) : 0
|
|
932
|
-
}
|
|
933
|
-
return sign, nil, time if week.uniq == [0]
|
|
934
|
-
date = [0, 0, week[1] + 7*week[0]]
|
|
935
|
-
return sign, date, time, week
|
|
936
|
-
|
|
937
|
-
# 代用形式
|
|
938
|
-
else
|
|
939
|
-
pdate += 'T' + ptime if ptime
|
|
940
|
-
f, d, t, z, e = When::BasicTypes::DateTime._to_array(pdate, {:abbr=>[0]*20})
|
|
941
|
-
return nil if e
|
|
942
|
-
if d
|
|
943
|
-
case f
|
|
944
|
-
when :day ; date = [d[0], 0, d[1]]
|
|
945
|
-
when :century, nil ; date = (0..2).map {|i| d[i]||0}
|
|
946
|
-
when :week ; date, week = [0,0,d[0]*7+(d[1]||0)], [d[0], d[1]||0]
|
|
947
|
-
end
|
|
948
|
-
end
|
|
949
|
-
time = t ? (t.map {|v| v||0}) : nil
|
|
950
|
-
return sign, date, time, week
|
|
951
|
-
end
|
|
952
|
-
end
|
|
953
|
-
|
|
954
|
-
#
|
|
955
|
-
#
|
|
956
|
-
# @return [
|
|
957
|
-
#
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
#
|
|
963
|
-
#
|
|
964
|
-
#
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
#
|
|
970
|
-
#
|
|
971
|
-
#
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
#
|
|
977
|
-
#
|
|
978
|
-
#
|
|
979
|
-
#
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
end
|
|
1001
|
-
|
|
1002
|
-
#
|
|
1003
|
-
#
|
|
1004
|
-
# @return [
|
|
1005
|
-
#
|
|
1006
|
-
def
|
|
1007
|
-
return
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
#
|
|
1012
|
-
#
|
|
1013
|
-
#
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
return
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
#
|
|
1021
|
-
#
|
|
1022
|
-
#
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
return
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
#
|
|
1030
|
-
#
|
|
1031
|
-
#
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
return
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
#
|
|
1039
|
-
#
|
|
1040
|
-
#
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
return
|
|
1044
|
-
end
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
#
|
|
1048
|
-
#
|
|
1049
|
-
#
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
#
|
|
1057
|
-
#
|
|
1058
|
-
#
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
return
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
#
|
|
1066
|
-
#
|
|
1067
|
-
#
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
return
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
#
|
|
1075
|
-
#
|
|
1076
|
-
#
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
#
|
|
1098
|
-
#
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
sgn
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
#
|
|
1143
|
-
#
|
|
1144
|
-
#
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
#
|
|
1155
|
-
#
|
|
1156
|
-
# @
|
|
1157
|
-
#
|
|
1158
|
-
#
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
#
|
|
1165
|
-
#
|
|
1166
|
-
#
|
|
1167
|
-
#
|
|
1168
|
-
#
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
#
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
end
|
|
1187
|
-
|
|
1188
|
-
#
|
|
1189
|
-
#
|
|
1190
|
-
# @
|
|
1191
|
-
#
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
#
|
|
1224
|
-
#
|
|
1225
|
-
#
|
|
1226
|
-
#
|
|
1227
|
-
#
|
|
1228
|
-
#
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
#
|
|
1234
|
-
#
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
@
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
end
|
|
1324
|
-
|
|
1325
|
-
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
=begin
|
|
3
|
+
Copyright (C) 2011-2013 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
|
+
# (5.2) Temporal Objects Package
|
|
11
|
+
#
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# 長さと距離を計算するための操作を規定する
|
|
16
|
+
#
|
|
17
|
+
module Separation
|
|
18
|
+
|
|
19
|
+
# When::TM::GeometricPrimitive 自身の持続時間
|
|
20
|
+
#
|
|
21
|
+
# @return [When::TM::Duration]
|
|
22
|
+
#
|
|
23
|
+
# @abstract
|
|
24
|
+
#
|
|
25
|
+
def length
|
|
26
|
+
raise TypeError, "Absolute Class #{self.class}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# 他のWhen::TM::GeometricPrimitiveとの時間位置の差の絶対値
|
|
30
|
+
#
|
|
31
|
+
# @param [When::TM::GeometricPrimitive] other
|
|
32
|
+
#
|
|
33
|
+
# @return [When::TM::Duration]
|
|
34
|
+
#
|
|
35
|
+
# @abstract
|
|
36
|
+
#
|
|
37
|
+
def distance(other)
|
|
38
|
+
raise TypeError, "Absolute Class #{self.class}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#
|
|
44
|
+
# 互いの相対位置を判定する操作を規定する
|
|
45
|
+
#
|
|
46
|
+
module Order
|
|
47
|
+
|
|
48
|
+
# 他のWhen::TM::Primitiveとの相対的な時間位置
|
|
49
|
+
#
|
|
50
|
+
# @param [When::TM::Primitive] other
|
|
51
|
+
#
|
|
52
|
+
# @return [When::TM::RelativePosition]
|
|
53
|
+
#
|
|
54
|
+
# @abstract
|
|
55
|
+
#
|
|
56
|
+
def relative_position(other)
|
|
57
|
+
raise TypeError, "Absolute Class #{self.class}"
|
|
58
|
+
end
|
|
59
|
+
alias :relativePosition :relative_position
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# 相対的な時間位置
|
|
64
|
+
#
|
|
65
|
+
# Allen(1983) が分類した13種類の相対的な時間位置を定義している
|
|
66
|
+
#
|
|
67
|
+
# ISO19108では値は Code クラスだが、本実装では値は Symbol である
|
|
68
|
+
#
|
|
69
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#RelatedTimeType gml schema}
|
|
70
|
+
#
|
|
71
|
+
# see Allen,J.F., Maintaining Knowledge about Temporal Intervals, Communications of the ACM, 1983,vol.26 pp.832-843
|
|
72
|
+
#
|
|
73
|
+
module RelativePosition
|
|
74
|
+
|
|
75
|
+
Before = :Before
|
|
76
|
+
After = :After
|
|
77
|
+
Begins = :Begins
|
|
78
|
+
Ends = :Ends
|
|
79
|
+
During = :During
|
|
80
|
+
Equals = :Equals
|
|
81
|
+
Contains = :Contains
|
|
82
|
+
Overlaps = :Overlaps
|
|
83
|
+
Meets = :Meets
|
|
84
|
+
OverlappedBy = :OverlappedBy
|
|
85
|
+
MetBy = :MetBy
|
|
86
|
+
BegunBy = :BegunBy
|
|
87
|
+
EndedBy = :EndedBy
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# 時間のオブジェクト
|
|
92
|
+
#
|
|
93
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimeObjectType gml schema}
|
|
94
|
+
#
|
|
95
|
+
class Object < When::BasicTypes::Object
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# 複数の時間プリミティブの集成
|
|
100
|
+
#
|
|
101
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimeComplexType gml schema}
|
|
102
|
+
#
|
|
103
|
+
class Complex < Object
|
|
104
|
+
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# 位相複体 - 連結した位相プリミティブの集合
|
|
108
|
+
#
|
|
109
|
+
# A temporal topology complex.
|
|
110
|
+
#
|
|
111
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#TimeTopologyComplexType gml schema}
|
|
112
|
+
#
|
|
113
|
+
class TopologicalComplex < Complex
|
|
114
|
+
|
|
115
|
+
# 対応するプリミティブ (relation - Complex)
|
|
116
|
+
#
|
|
117
|
+
# @return [Array<When::TM::TopologicalPrimitive>]
|
|
118
|
+
#
|
|
119
|
+
attr_reader :primitive
|
|
120
|
+
|
|
121
|
+
# オブジェクトの生成
|
|
122
|
+
#
|
|
123
|
+
# @param [When::TM::TopologicalPrimitive] primitive 対応するプリミティブの Array
|
|
124
|
+
#
|
|
125
|
+
def initialize(primitive)
|
|
126
|
+
@primitive = primitive
|
|
127
|
+
@primitive.each do |p|
|
|
128
|
+
p.complex << self
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# 時間プリミティブ
|
|
134
|
+
#
|
|
135
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimePrimitiveType gml schema}
|
|
136
|
+
#
|
|
137
|
+
class Primitive < Object
|
|
138
|
+
|
|
139
|
+
include Order
|
|
140
|
+
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# 時間幾何プリミティブ
|
|
144
|
+
#
|
|
145
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#AbstractTimeGeometricPrimitiveType gml schema}
|
|
146
|
+
#
|
|
147
|
+
class GeometricPrimitive < Primitive
|
|
148
|
+
|
|
149
|
+
include Separation
|
|
150
|
+
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# 瞬間 - 零次元幾何プリミティブ
|
|
154
|
+
#
|
|
155
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimeInstantType gml schema}
|
|
156
|
+
#
|
|
157
|
+
class Instant < GeometricPrimitive
|
|
158
|
+
|
|
159
|
+
# この瞬間の時間位置
|
|
160
|
+
#
|
|
161
|
+
# @return [When::TM::Position]
|
|
162
|
+
#
|
|
163
|
+
attr_reader :position
|
|
164
|
+
|
|
165
|
+
# この瞬間を始まりとする期間 (relation - Beginning)
|
|
166
|
+
#
|
|
167
|
+
# @return [Array<When::TM::Period>]
|
|
168
|
+
#
|
|
169
|
+
attr_reader :begun_by
|
|
170
|
+
alias :begunBy :begun_by
|
|
171
|
+
|
|
172
|
+
# この瞬間を終わりとする期間 (relation - Ending)
|
|
173
|
+
#
|
|
174
|
+
# @return [Array<When::TM::Period>]
|
|
175
|
+
#
|
|
176
|
+
attr_reader :ended_by
|
|
177
|
+
alias :endedBy :ended_by
|
|
178
|
+
|
|
179
|
+
# 対応するノード (relation - Realization)
|
|
180
|
+
#
|
|
181
|
+
# @return [When::TM::Node]
|
|
182
|
+
#
|
|
183
|
+
attr_reader :topology
|
|
184
|
+
|
|
185
|
+
# When::TM::GeometricPrimitive 自身の持続時間
|
|
186
|
+
#
|
|
187
|
+
# @return [When::TM::Duration]
|
|
188
|
+
#
|
|
189
|
+
def length()
|
|
190
|
+
return When.Duration(0)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# 他のWhen::TM::GeometricPrimitiveとの時間位置の差の絶対値
|
|
194
|
+
#
|
|
195
|
+
# @param [When::TM::GeometricPrimitive] other
|
|
196
|
+
#
|
|
197
|
+
# @return [When::TM::Duration]
|
|
198
|
+
#
|
|
199
|
+
def distance(other)
|
|
200
|
+
case other
|
|
201
|
+
when Instant
|
|
202
|
+
return (self.position - other.position).abs
|
|
203
|
+
when Period
|
|
204
|
+
verify = other.begin.position - self.position
|
|
205
|
+
return verify if verify.sign >= 0
|
|
206
|
+
return [self.position - other.end.position, When::TM::PeriodDuration.new(0,When::DAY)].max
|
|
207
|
+
else
|
|
208
|
+
raise TypeError, "The right operand should be When::TM::Instant or When::TM::Period"
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# 他のWhen::TM::Primitiveとの相対的な時間位置
|
|
213
|
+
#
|
|
214
|
+
# @param [When::TM::Primitive] other
|
|
215
|
+
#
|
|
216
|
+
# @return [When::TM::RelativePosition]
|
|
217
|
+
#
|
|
218
|
+
def relative_position(other)
|
|
219
|
+
case other
|
|
220
|
+
when Instant
|
|
221
|
+
verify = self.position <=> other.position
|
|
222
|
+
return RelativePosition::Before if verify < 0
|
|
223
|
+
return RelativePosition::Equals if verify == 0
|
|
224
|
+
return RelativePosition::After
|
|
225
|
+
when Period
|
|
226
|
+
verify = self.position <=> other.begin.position
|
|
227
|
+
return RelativePosition::Before if verify < 0
|
|
228
|
+
return RelativePosition::Begins if verify == 0
|
|
229
|
+
verify = self.position <=> other.end.position
|
|
230
|
+
return RelativePosition::During if verify < 0
|
|
231
|
+
return RelativePosition::Ends if verify == 0
|
|
232
|
+
return RelativePosition::After
|
|
233
|
+
else
|
|
234
|
+
raise TypeError, "The right operand should be When::TM::Instant or When::TM::Period"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
alias :relativePosition :relative_position
|
|
238
|
+
|
|
239
|
+
# オブジェクトの生成
|
|
240
|
+
#
|
|
241
|
+
# @param [When::TM::Position] position 対応する時間位置
|
|
242
|
+
#
|
|
243
|
+
def initialize(position)
|
|
244
|
+
@position = position
|
|
245
|
+
@begun_by = []
|
|
246
|
+
@ended_by = []
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
private
|
|
250
|
+
|
|
251
|
+
# その他のメソッド
|
|
252
|
+
#
|
|
253
|
+
# @note
|
|
254
|
+
# When::TM::Instant で定義されていないメソッドは
|
|
255
|
+
# 処理を @position (type: When::TM::Position) に委譲する
|
|
256
|
+
#
|
|
257
|
+
def method_missing(name, *args, &block)
|
|
258
|
+
self.class.module_eval %Q{
|
|
259
|
+
def #{name}(*args, &block)
|
|
260
|
+
list = args.map {|arg| arg.kind_of?(self.class) ? arg.position : arg}
|
|
261
|
+
@position.send("#{name}", *list, &block)
|
|
262
|
+
end
|
|
263
|
+
} unless When::Parts::MethodCash.escape(name)
|
|
264
|
+
list = args.map {|arg| arg.kind_of?(self.class) ? arg.position : arg}
|
|
265
|
+
@position.send(name, *list, &block)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# 期間 - 一次元幾何プリミティブ
|
|
270
|
+
#
|
|
271
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimePeriodType gml schema}
|
|
272
|
+
#
|
|
273
|
+
class Period < GeometricPrimitive
|
|
274
|
+
|
|
275
|
+
RELATIVE_POSITION = {
|
|
276
|
+
RelativePosition::Contains => {
|
|
277
|
+
RelativePosition::Before => RelativePosition::Overlaps,
|
|
278
|
+
RelativePosition::EndedBy => RelativePosition::EndedBy,
|
|
279
|
+
RelativePosition::Contains => RelativePosition::Contains
|
|
280
|
+
},
|
|
281
|
+
RelativePosition::BegunBy => {
|
|
282
|
+
RelativePosition::Before => RelativePosition::Begins,
|
|
283
|
+
RelativePosition::EndedBy => RelativePosition::Equals,
|
|
284
|
+
RelativePosition::Contains => RelativePosition::BegunBy
|
|
285
|
+
},
|
|
286
|
+
RelativePosition::After => {
|
|
287
|
+
RelativePosition::Before => RelativePosition::During,
|
|
288
|
+
RelativePosition::EndedBy => RelativePosition::Ends,
|
|
289
|
+
RelativePosition::Contains => RelativePosition::OverlappedBy
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
# この期間が始まる瞬間 (relation - Beginning)
|
|
294
|
+
#
|
|
295
|
+
# @return [When::TM::Instant]
|
|
296
|
+
#
|
|
297
|
+
attr_reader :begin
|
|
298
|
+
|
|
299
|
+
# この期間が終わる瞬間 (relation - Ending)
|
|
300
|
+
#
|
|
301
|
+
# @return [When::TM::Instant]
|
|
302
|
+
#
|
|
303
|
+
attr_reader :end
|
|
304
|
+
|
|
305
|
+
# 対応するエッジ (relation - Realization)
|
|
306
|
+
#
|
|
307
|
+
# @return [When::TM::Edge]
|
|
308
|
+
#
|
|
309
|
+
attr_reader :topology
|
|
310
|
+
|
|
311
|
+
# When::TM::GeometricPrimitive 自身の持続時間
|
|
312
|
+
#
|
|
313
|
+
# @return [When::TM::Duration]
|
|
314
|
+
#
|
|
315
|
+
def length()
|
|
316
|
+
@length ||= @end - @begin
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# 他のWhen::TM::GeometricPrimitiveとの時間位置の差の絶対値
|
|
320
|
+
#
|
|
321
|
+
# @param [When::TM::GeometricPrimitive] other
|
|
322
|
+
#
|
|
323
|
+
# @return [When::TM::Duration]
|
|
324
|
+
#
|
|
325
|
+
def distance(other)
|
|
326
|
+
case other
|
|
327
|
+
when Instant
|
|
328
|
+
return other.distance(self)
|
|
329
|
+
when Period
|
|
330
|
+
verify = other.begin.position - self.end.position
|
|
331
|
+
return verify if verify.sign >= 0
|
|
332
|
+
return [self.begin.position - other.end.position, When::TM::PeriodDuration.new(0,When::DAY)].max
|
|
333
|
+
else
|
|
334
|
+
raise TypeError, "The right operand should be Instant or Period"
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
# 他のPrimitiveとの相対的な時間位置
|
|
339
|
+
#
|
|
340
|
+
# @param [When::TM::Primitive] other
|
|
341
|
+
#
|
|
342
|
+
# @return [When::TM::RelativePosition]
|
|
343
|
+
#
|
|
344
|
+
def relative_position(other)
|
|
345
|
+
case other
|
|
346
|
+
when Instant
|
|
347
|
+
verify = self.end.position <=> other.position
|
|
348
|
+
return RelativePosition::Before if verify < 0
|
|
349
|
+
return RelativePosition::EndedBy if verify == 0
|
|
350
|
+
verify = self.begin.position <=> other.position
|
|
351
|
+
return RelativePosition::Contains if verify < 0
|
|
352
|
+
return RelativePosition::BegunBy if verify == 0
|
|
353
|
+
return RelativePosition::After
|
|
354
|
+
when Period
|
|
355
|
+
verify_b = relative_position(other.begin)
|
|
356
|
+
case verify_b
|
|
357
|
+
when RelativePosition::Before ; return RelativePosition::Before
|
|
358
|
+
when RelativePosition::EndedBy ; return RelativePosition::Meets
|
|
359
|
+
end
|
|
360
|
+
verify_e = relative_position(other.end)
|
|
361
|
+
case verify_e
|
|
362
|
+
when RelativePosition::BegunBy ; return RelativePosition::MetBy
|
|
363
|
+
when RelativePosition::After ; return RelativePosition::After
|
|
364
|
+
else ; return RELATIVE_POSITION[verify_b][verify_e]
|
|
365
|
+
end
|
|
366
|
+
else
|
|
367
|
+
raise TypeError, "The right operand should be Instant or Period"
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
alias :relativePosition :relative_position
|
|
371
|
+
|
|
372
|
+
# オブジェクトの生成
|
|
373
|
+
#
|
|
374
|
+
# @param [When::TM::Instant] begun 始点
|
|
375
|
+
#
|
|
376
|
+
# @param [When::TM::Instant] ended 終点
|
|
377
|
+
#
|
|
378
|
+
def initialize(begun, ended)
|
|
379
|
+
raise ArgumentError, 'Order mismatch: begun > ended' if begun > ended
|
|
380
|
+
@begin = begun
|
|
381
|
+
@end = ended
|
|
382
|
+
@begin.begun_by << self
|
|
383
|
+
@end.ended_by << self
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
private
|
|
387
|
+
|
|
388
|
+
# その他のメソッド
|
|
389
|
+
#
|
|
390
|
+
# @note
|
|
391
|
+
# When::TM::Period で定義されていないメソッドは
|
|
392
|
+
# 処理を @begin (type: When::TM::Instant) に委譲する
|
|
393
|
+
#
|
|
394
|
+
def method_missing(name, *args, &block)
|
|
395
|
+
self.class.module_eval %Q{
|
|
396
|
+
def #{name}(*args, &block)
|
|
397
|
+
@begin.send("#{name}", *args, &block)
|
|
398
|
+
end
|
|
399
|
+
} unless When::Parts::MethodCash.escape(name)
|
|
400
|
+
@begin.send(name, *args, &block)
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
# 時間位相プリミティブ - 単独で不可分な位相要素
|
|
405
|
+
#
|
|
406
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#AbstractTimeTopologyPrimitiveType gml schema}
|
|
407
|
+
#
|
|
408
|
+
class TopologicalPrimitive < Primitive
|
|
409
|
+
|
|
410
|
+
# 対応するコンプレックス (relation - Complex)
|
|
411
|
+
#
|
|
412
|
+
# @return [Array<When::TM::TopologicalComplex>]
|
|
413
|
+
#
|
|
414
|
+
attr_accessor :complex
|
|
415
|
+
|
|
416
|
+
#
|
|
417
|
+
# オブジェクトの生成
|
|
418
|
+
#
|
|
419
|
+
def initialize
|
|
420
|
+
@complex = []
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
private
|
|
424
|
+
|
|
425
|
+
alias :_method_missing :method_missing
|
|
426
|
+
|
|
427
|
+
# その他のメソッド
|
|
428
|
+
#
|
|
429
|
+
# @note
|
|
430
|
+
# When::TM::TopologicalPrimitive で定義されていないメソッドは
|
|
431
|
+
# 処理を @geometry (type: When::TM::Instant) に委譲する
|
|
432
|
+
#
|
|
433
|
+
def method_missing(name, *args, &block)
|
|
434
|
+
return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name) ||
|
|
435
|
+
!respond_to?(:geometry)
|
|
436
|
+
self.class.module_eval %Q{
|
|
437
|
+
def #{name}(*args, &block)
|
|
438
|
+
list = args.map {|arg| arg.respond_to?(:geometry) ? arg.geometry : arg}
|
|
439
|
+
geometry.send("#{name}", *list, &block)
|
|
440
|
+
end
|
|
441
|
+
} unless When::Parts::MethodCash.escape(name)
|
|
442
|
+
list = args.map {|arg| arg.respond_to?(:geometry) ? arg.geometry : arg}
|
|
443
|
+
geometry.send(name, *list, &block)
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# 零次元位相プリミティブ - 幾何的実現は When::TM::Instant と対応する
|
|
448
|
+
#
|
|
449
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#TimeNodeType gml schema}
|
|
450
|
+
#
|
|
451
|
+
class Node < TopologicalPrimitive
|
|
452
|
+
|
|
453
|
+
# 対応するエッジ (relation - Termination)
|
|
454
|
+
#
|
|
455
|
+
# @return [Array<When::TM::Edge>]
|
|
456
|
+
#
|
|
457
|
+
attr_reader :previous_edge
|
|
458
|
+
alias :previousEdge :previous_edge
|
|
459
|
+
|
|
460
|
+
# 対応するエッジ (relation - Initiation)
|
|
461
|
+
#
|
|
462
|
+
# @return [Array<When::TM::Edge>]
|
|
463
|
+
#
|
|
464
|
+
attr_reader :next_edge
|
|
465
|
+
alias :nextEdge :next_edge
|
|
466
|
+
|
|
467
|
+
# 対応する瞬間 (relation - Realization)
|
|
468
|
+
#
|
|
469
|
+
# @return [When::TM::Instant]
|
|
470
|
+
#
|
|
471
|
+
attr_reader :geometry
|
|
472
|
+
|
|
473
|
+
# オブジェクトの生成
|
|
474
|
+
#
|
|
475
|
+
# @param [When::TM::Instant] geometry 対応する瞬間
|
|
476
|
+
#
|
|
477
|
+
def initialize(geometry)
|
|
478
|
+
super()
|
|
479
|
+
@previous_edge = []
|
|
480
|
+
@next_edge = []
|
|
481
|
+
@geometry = geometry
|
|
482
|
+
@geometry.topology = self
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
# 一次元位相プリミティブ - 幾何的実現は When::TM::Period と対応する
|
|
487
|
+
#
|
|
488
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalTopology.xsd#TimeEdgeType gml schema}
|
|
489
|
+
#
|
|
490
|
+
class Edge < TopologicalPrimitive
|
|
491
|
+
|
|
492
|
+
# 対応するノード (relation - Termination)
|
|
493
|
+
#
|
|
494
|
+
# @return [When::TM::Node]
|
|
495
|
+
#
|
|
496
|
+
attr_reader :end
|
|
497
|
+
|
|
498
|
+
# 対応するノード (relation - Initiation)
|
|
499
|
+
#
|
|
500
|
+
# @return [When::TM::Node]
|
|
501
|
+
#
|
|
502
|
+
attr_reader :start
|
|
503
|
+
|
|
504
|
+
# 対応する期間 (relation - Realization)
|
|
505
|
+
#
|
|
506
|
+
# @return [When::TM::Period]
|
|
507
|
+
#
|
|
508
|
+
attr_reader :geometry
|
|
509
|
+
|
|
510
|
+
# オブジェクトの生成
|
|
511
|
+
#
|
|
512
|
+
# @param [When::TM::Node] start 始点
|
|
513
|
+
#
|
|
514
|
+
# @param [When::TM::Node] ended 終点
|
|
515
|
+
#
|
|
516
|
+
def initialize(start, ended)
|
|
517
|
+
super()
|
|
518
|
+
@start = start
|
|
519
|
+
@end = ended
|
|
520
|
+
@geometry = Period.new(@start.geometry, @end.geometry)
|
|
521
|
+
@geometry.topology = self
|
|
522
|
+
@start.next_edge << self
|
|
523
|
+
@end.previous_edge << self
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# 時間次元における長さ又は距離を記述するために使うデータ型
|
|
528
|
+
#
|
|
529
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#duration gml schema}
|
|
530
|
+
#
|
|
531
|
+
class Duration
|
|
532
|
+
|
|
533
|
+
#
|
|
534
|
+
# When::TM::IntervalLength への変換
|
|
535
|
+
#
|
|
536
|
+
# @return [When::TM::IntervalLength]
|
|
537
|
+
#
|
|
538
|
+
def to_interval_length
|
|
539
|
+
[['week', WEEK], ['day', DAY], ['hour', HOUR], ['minute', MINUTE], ['second', SECOND]].each do |unit|
|
|
540
|
+
div, mod = duration.divmod(unit[1])
|
|
541
|
+
return When::TM::IntervalLength.new(div, unit[0]) if mod == 0
|
|
542
|
+
end
|
|
543
|
+
When::TM::IntervalLength.new(duration / SECOND, 'second')
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
#
|
|
547
|
+
# When::TM::PeriodDuration への変換
|
|
548
|
+
#
|
|
549
|
+
# @return [When::TM::PeriodDuration]
|
|
550
|
+
#
|
|
551
|
+
def to_period_duration
|
|
552
|
+
[[When::WEEK, WEEK], [When::DAY, DAY], [When::HOUR, HOUR], [When::MINUTE, MINUTE], [When::SECOND, SECOND]].each do |unit|
|
|
553
|
+
div, mod = duration.divmod(unit[1])
|
|
554
|
+
return When::TM::PeriodDuration.new(div, unit[0]) if mod == 0
|
|
555
|
+
end
|
|
556
|
+
When::TM::PeriodDuration.new(duration / SECOND, When::SECOND)
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
#
|
|
560
|
+
# Duration 用の Enumerator
|
|
561
|
+
#
|
|
562
|
+
class Enumerator < When::Parts::Enumerator
|
|
563
|
+
|
|
564
|
+
# 次の時間位置を取得する
|
|
565
|
+
#
|
|
566
|
+
# @return [When::TM::TemporalPosition] 次の時間位置
|
|
567
|
+
#
|
|
568
|
+
def succ
|
|
569
|
+
value = @current
|
|
570
|
+
@current = (@count_limit.kind_of?(Numeric) && @count >= @count_limit) ? nil :
|
|
571
|
+
(@current==:first) ? @first :
|
|
572
|
+
(@direction==:forward) ? @first + @parent * @count : @first - @parent * @count
|
|
573
|
+
@count += 1
|
|
574
|
+
return value
|
|
575
|
+
end
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
# Enumerator の生成
|
|
579
|
+
#
|
|
580
|
+
# @overload initialize(range, count_limit=nil))
|
|
581
|
+
# @param [Range, When::Parts::GeometricComplex] range
|
|
582
|
+
# [ 始点 - range.first ]
|
|
583
|
+
# [ 終点 - range.last ]
|
|
584
|
+
# @param [Integer] count_limit 繰り返し回数(デフォルトは指定なし)
|
|
585
|
+
#
|
|
586
|
+
# @overload initialize(first, direction, count_limit=nil))
|
|
587
|
+
# @param [When::TM::TemporalPosition] first 始点
|
|
588
|
+
# @param [Symbol] direction
|
|
589
|
+
# [ :forward - 昇順 ]
|
|
590
|
+
# [ :reverse - 降順 ]
|
|
591
|
+
# @param [Integer] count_limit 繰り返し回数(デフォルトは指定なし)
|
|
592
|
+
#
|
|
593
|
+
def _enumerator(*args)
|
|
594
|
+
return Enumerator.new(*args.unshift(self))
|
|
595
|
+
end
|
|
596
|
+
alias :to_enum :_enumerator
|
|
597
|
+
alias :enum_for :_enumerator
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
#
|
|
601
|
+
# ISO 11404 の時間間隔に基づいて定義された When::TM::Duration の subclass
|
|
602
|
+
#
|
|
603
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#timeIntervalLengthType gml schema}
|
|
604
|
+
#
|
|
605
|
+
class IntervalLength < Duration
|
|
606
|
+
|
|
607
|
+
Alias = {'Y'=>'year', 'M'=>'month' , 'D'=>'day', 'W'=>'week', 'S'=>'system',
|
|
608
|
+
'h'=>'hour', 'm'=>'minute', 's'=>'second'}
|
|
609
|
+
|
|
610
|
+
# Interval Length 形式の表現を分解して配列化する
|
|
611
|
+
#
|
|
612
|
+
# @param [String] interval
|
|
613
|
+
#
|
|
614
|
+
# @return [Array<Numeric, String>] ( value, unit_name, factor, radix )
|
|
615
|
+
# [ value [Numeric] - 時間間隔 / 単位 ]
|
|
616
|
+
# [ unit_name [String] - 単位名 ]
|
|
617
|
+
# [ factor [Numeric] - 冪乗 ]
|
|
618
|
+
# [ radix [Numeric] - 冪乗の基数 ]
|
|
619
|
+
#
|
|
620
|
+
# @note value, factor, radix は Numeric
|
|
621
|
+
#
|
|
622
|
+
def self._to_array(interval)
|
|
623
|
+
return nil unless interval =~ /\A([-+]?[\d.]+)(?:(E|X|\((\d+)\))([-+]?\d+))?([A-Za-z]+|\*([\d.]+)S)\z/
|
|
624
|
+
value, radix, radix_quantity, factor, unit, unit_quantity = $~[1..6]
|
|
625
|
+
value = When::Coordinates::Pair._en_number(value)
|
|
626
|
+
radix = case radix
|
|
627
|
+
when 'E', nil ; 10
|
|
628
|
+
when 'X' ; 60
|
|
629
|
+
else ; radix_quantity.to_i
|
|
630
|
+
end
|
|
631
|
+
factor = factor ? -factor.to_i : 0
|
|
632
|
+
return [value, unit_quantity, factor, radix] if unit_quantity
|
|
633
|
+
unit_quantity = Unit[unit.downcase] || Unit[Alias[unit[0..0]]]
|
|
634
|
+
return [value, UnitName[unit_quantity], factor, radix] if unit_quantity
|
|
635
|
+
return nil
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
# 時間間隔の長さ (128秒単位)
|
|
639
|
+
#
|
|
640
|
+
# @return [Numeric]
|
|
641
|
+
#
|
|
642
|
+
protected :duration=
|
|
643
|
+
|
|
644
|
+
# 時間間隔を表現するために使用した測定単位の名称
|
|
645
|
+
#
|
|
646
|
+
# @return [String] (year|month|week|day|hour|minute|second|system)
|
|
647
|
+
#
|
|
648
|
+
attr_reader :unit
|
|
649
|
+
|
|
650
|
+
# 時間単位となる乗数の基底となる正の整数
|
|
651
|
+
#
|
|
652
|
+
# @return [Integer]
|
|
653
|
+
#
|
|
654
|
+
attr_reader :radix
|
|
655
|
+
|
|
656
|
+
# 基底のべき乗を行う指数
|
|
657
|
+
#
|
|
658
|
+
# @return [Integer]
|
|
659
|
+
#
|
|
660
|
+
attr_reader :factor
|
|
661
|
+
|
|
662
|
+
# 時間間隔の長さ / 測定単位
|
|
663
|
+
#
|
|
664
|
+
# @return [Numeric]
|
|
665
|
+
#
|
|
666
|
+
attr_accessor :value
|
|
667
|
+
protected :value=
|
|
668
|
+
|
|
669
|
+
#
|
|
670
|
+
# 測定単位の大きさ
|
|
671
|
+
#
|
|
672
|
+
# @return [Numeric]
|
|
673
|
+
#
|
|
674
|
+
attr_reader :unit_quantity
|
|
675
|
+
|
|
676
|
+
# 時刻配列
|
|
677
|
+
#
|
|
678
|
+
# @return [Numeric]
|
|
679
|
+
# When::TM::PeriodDuration との互換性のために提供
|
|
680
|
+
#
|
|
681
|
+
# @private
|
|
682
|
+
#
|
|
683
|
+
def time
|
|
684
|
+
[0, 0, @duration / SECOND]
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
# 日付配列
|
|
688
|
+
#
|
|
689
|
+
# @return [nil]
|
|
690
|
+
# When::TM::PeriodDuration との互換性のために提供
|
|
691
|
+
#
|
|
692
|
+
# @private
|
|
693
|
+
#
|
|
694
|
+
def date
|
|
695
|
+
nil
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
# 暦週配列
|
|
699
|
+
#
|
|
700
|
+
# @return [nil]
|
|
701
|
+
# When::TM::PeriodDuration との互換性のために提供
|
|
702
|
+
#
|
|
703
|
+
# @private
|
|
704
|
+
#
|
|
705
|
+
def weeks
|
|
706
|
+
nil
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
# 符号反転
|
|
710
|
+
#
|
|
711
|
+
# @return [When::TM::IntervalLength]
|
|
712
|
+
#
|
|
713
|
+
def -@
|
|
714
|
+
interval = self.dup
|
|
715
|
+
interval.value = -@value
|
|
716
|
+
interval.duration = -@duration
|
|
717
|
+
return interval
|
|
718
|
+
end
|
|
719
|
+
|
|
720
|
+
#
|
|
721
|
+
# 加算
|
|
722
|
+
#
|
|
723
|
+
# @param [When::TM::Duration] other
|
|
724
|
+
# @param [Numeric] other 秒数
|
|
725
|
+
# @param [その他] other 日時とみなす
|
|
726
|
+
#
|
|
727
|
+
# @return [When::TM::IntervalLength] (other が Numeric, When::TM::Duration の場合)
|
|
728
|
+
# @return [other と同じクラス] (other がその他の場合)
|
|
729
|
+
#
|
|
730
|
+
def +(other)
|
|
731
|
+
case other
|
|
732
|
+
when Duration ; diff = other.duration
|
|
733
|
+
when Numeric ; diff = other * SECOND
|
|
734
|
+
else ; return other + self
|
|
735
|
+
end
|
|
736
|
+
interval = self.dup
|
|
737
|
+
interval.duration = @duration + diff
|
|
738
|
+
internal.value = interval.duration / (@radix ** (-@factor) * @unit_quantity)
|
|
739
|
+
return interval
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
#
|
|
743
|
+
# 減算
|
|
744
|
+
#
|
|
745
|
+
# @param [When::TM::IntervalLength] other
|
|
746
|
+
# @param [Numeric] other 秒数
|
|
747
|
+
#
|
|
748
|
+
# @return [When::TM::IntervalLength]
|
|
749
|
+
#
|
|
750
|
+
def -(other)
|
|
751
|
+
interval = self.dup
|
|
752
|
+
interval.duration = @duration - (other.kind_of?(Duration) ? other.duration : other * SECOND)
|
|
753
|
+
internal.value = interval.duration / (@radix ** (-@factor) * @unit_quantity)
|
|
754
|
+
return interval
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
# 乗算
|
|
758
|
+
#
|
|
759
|
+
# @param [Numeric] times
|
|
760
|
+
#
|
|
761
|
+
# @return [When::TM::IntervalLength]
|
|
762
|
+
#
|
|
763
|
+
def *(times)
|
|
764
|
+
interval = self.dup
|
|
765
|
+
interval.value = times * @value
|
|
766
|
+
interval.duration = times * @duration
|
|
767
|
+
return interval
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
#
|
|
771
|
+
# 除算
|
|
772
|
+
#
|
|
773
|
+
# @param [When::TM::IntervalLength] other
|
|
774
|
+
# @param [Numeric] other 秒数
|
|
775
|
+
#
|
|
776
|
+
# @return [When::TM::IntervalLength] (other が Numeric の場合)
|
|
777
|
+
# @return [Numeric] (other が When::TM::Duration の場合)
|
|
778
|
+
#
|
|
779
|
+
def /(other)
|
|
780
|
+
other.kind_of?(Duration) ? @duration / other.duration : self * (1.0 / other)
|
|
781
|
+
end
|
|
782
|
+
|
|
783
|
+
# 文字列化
|
|
784
|
+
#
|
|
785
|
+
# @return [String]
|
|
786
|
+
#
|
|
787
|
+
def to_s
|
|
788
|
+
expression = @value.to_s
|
|
789
|
+
unless @factor == 0
|
|
790
|
+
case @radix
|
|
791
|
+
when 10 ; expression += 'E'
|
|
792
|
+
when 60 ; expression += 'X'
|
|
793
|
+
else ; expression += '(%d)' % @radix
|
|
794
|
+
end
|
|
795
|
+
expression += '%+d' % (-@factor)
|
|
796
|
+
end
|
|
797
|
+
expression += Alias.invert[@unit] || "*#{When::Coordinates::Pair._en_number(@unit)}S"
|
|
798
|
+
return expression
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
#
|
|
802
|
+
# When::TM::IntervalLength への変換
|
|
803
|
+
#
|
|
804
|
+
# 単なるオブジェクトのコピー
|
|
805
|
+
#
|
|
806
|
+
# @return [When::TM::IntervalLength]
|
|
807
|
+
#
|
|
808
|
+
def to_interval_length
|
|
809
|
+
self.dup
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
# オブジェクトの生成
|
|
813
|
+
#
|
|
814
|
+
# @param [Numeric] value 時間間隔の長さ / 測定単位(省略不可)
|
|
815
|
+
# @param [String] unit 時間間隔を表現するために使用した測定単位の名称(デフォルト : system)
|
|
816
|
+
# ('year'|'month'|'week'|'day'|'hour'|'minute'|'second'|'system')
|
|
817
|
+
# @param [Integer] factor 基底の冪乗を行う指数(デフォルト : 0)
|
|
818
|
+
# @param [Integer] radix 時間単位となる乗数の基底となる正の整数(デフォルト : 10)
|
|
819
|
+
#
|
|
820
|
+
def initialize(value, unit='system', factor=0, radix=10)
|
|
821
|
+
@value, @factor, @radix = value, factor, radix
|
|
822
|
+
@unit_quantity = Unit[unit.downcase] || Unit[Alias[unit[0..0]]] if unit.kind_of?(String)
|
|
823
|
+
@unit_quantity ||= unit.to_f
|
|
824
|
+
raise TypeError, "Wrong Unit Type: #{unit}" unless @unit_quantity.kind_of?(Numeric)
|
|
825
|
+
@unit = UnitName[@unit_quantity] ||
|
|
826
|
+
When::Coordinates::Pair._en_number(@unit_quantity).to_s
|
|
827
|
+
@duration = @value * @radix ** (-@factor) * @unit_quantity
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
# オブジェクトの生成(終点と始点を指定)
|
|
831
|
+
#
|
|
832
|
+
# @param [When::TM::TemporalPosition] ended 終点
|
|
833
|
+
# @param [When::TM::TemporalPosition] begun 始点
|
|
834
|
+
#
|
|
835
|
+
# @return [When::TM::IntervalLength]
|
|
836
|
+
# [ 日単位の精度 - 終点と始点の分解能のいずれかが“日”またはそれより粗い場合 ]
|
|
837
|
+
# [ システム精度 - 終点と始点の分解能がともに“日”より細かい場合 ]
|
|
838
|
+
#
|
|
839
|
+
def self.difference(ended, begun)
|
|
840
|
+
precision = [ended.precision, begun.precision].min
|
|
841
|
+
return new(ended-begun) if precision > When::DAY
|
|
842
|
+
return new(ended.to_i - begun.to_i, unit='day')
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
private
|
|
846
|
+
|
|
847
|
+
# その他のメソッド
|
|
848
|
+
#
|
|
849
|
+
# @note
|
|
850
|
+
# When::TM::IntervalLength で定義されていないメソッドは
|
|
851
|
+
# 処理を @duration (type:Numeric) に委譲する
|
|
852
|
+
#
|
|
853
|
+
def method_missing(name, *args, &block)
|
|
854
|
+
self.class.module_eval %Q{
|
|
855
|
+
def #{name}(*args, &block)
|
|
856
|
+
@duration.send("#{name}", *args, &block)
|
|
857
|
+
end
|
|
858
|
+
} unless When::Parts::MethodCash.escape(name)
|
|
859
|
+
@duration.send(name, *args, &block)
|
|
860
|
+
end
|
|
861
|
+
end
|
|
862
|
+
|
|
863
|
+
#
|
|
864
|
+
# ISO 8601 (JIS X0301) の時間間隔に基づいて定義された When::TM::Duration の subclass
|
|
865
|
+
#
|
|
866
|
+
class PeriodDuration < Duration
|
|
867
|
+
|
|
868
|
+
include When
|
|
869
|
+
include Coordinates
|
|
870
|
+
|
|
871
|
+
#
|
|
872
|
+
# When::TM::PeriodDuration オブジェクトが月や年などの可変長の単位に依存する場合
|
|
873
|
+
# に @duration 属性の参照を禁止するために用いる
|
|
874
|
+
#
|
|
875
|
+
module NoDuration
|
|
876
|
+
#
|
|
877
|
+
# 属性 @duration が定義できないとをエラーで示す
|
|
878
|
+
#
|
|
879
|
+
# @return [Numeric]
|
|
880
|
+
#
|
|
881
|
+
def duration
|
|
882
|
+
raise TypeError, "This PeriodDuration object does't have duration value"
|
|
883
|
+
end
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
# ISO 8601 形式の表現を分解して配列化する
|
|
887
|
+
#
|
|
888
|
+
# @param [String] period
|
|
889
|
+
#
|
|
890
|
+
# @return [Array<Numeric, Array<Numeric>>] ( sign, date, time, week )
|
|
891
|
+
# [ sign [Numeric] - +1 , -1 ]
|
|
892
|
+
# [ date [Array<Numeric>] - 年月日 ]
|
|
893
|
+
# [ time [Array<Numeric>] - 時分秒 ]
|
|
894
|
+
# [ week [Array<Numeric>] - 週日 ]
|
|
895
|
+
#
|
|
896
|
+
def self._to_array(period)
|
|
897
|
+
|
|
898
|
+
return nil unless period.gsub(/_+/, '') =~ /\A([-+])?P(.*?)?(?:T(.+))?\z/
|
|
899
|
+
|
|
900
|
+
sign = ($1 == '-') ? -1 : +1
|
|
901
|
+
pdate, ptime = $~[2..3]
|
|
902
|
+
|
|
903
|
+
# 時分秒形式
|
|
904
|
+
if (ptime =~ /\A(?:([.,\d]+)?([:*=])?H)?(?:([.,\d]+)?([:*=])?M)?(?:([.,\d]+)?([:*=])?S)?((?:[.,\d]*[:*=]?X)*)\z/)
|
|
905
|
+
trunk = [1,3,5].map {|i|
|
|
906
|
+
$~[i] ? Pair._en_pair($~[i], $~[i+1]) : 0
|
|
907
|
+
}
|
|
908
|
+
extra = $7 ? $7.scan(/([.,\d]+)?([:*=])?X/).map {|d|
|
|
909
|
+
d[0] ? Pair._en_pair(d[0], d[1]) : 0
|
|
910
|
+
} : []
|
|
911
|
+
time = [0] + trunk + extra
|
|
912
|
+
time = nil if time.uniq == [0]
|
|
913
|
+
end
|
|
914
|
+
|
|
915
|
+
case pdate
|
|
916
|
+
# 年月日形式
|
|
917
|
+
when /\A((?:[.,\d]*[-*=]?X)*)(?:([.,\d]+)?([-*=])?Y)?(?:([.,\d]+)?([-+*&%!>=<?])?M)?(?:([.,\d]+)?([-*=?%])?D)?\z/
|
|
918
|
+
trunk = [2,4,6].map {|i|
|
|
919
|
+
$~[i] ? Pair._en_pair($~[i], $~[i+1]) : 0
|
|
920
|
+
}
|
|
921
|
+
extra = $1 ? $1.scan(/([.,\d]+)?([:*=])?X/).map {|d|
|
|
922
|
+
d[0] ? Pair._en_pair(d[0], d[1]) : 0
|
|
923
|
+
} : []
|
|
924
|
+
date = extra + trunk
|
|
925
|
+
date = nil if date.uniq == [0]
|
|
926
|
+
return sign, date, time
|
|
927
|
+
|
|
928
|
+
# 週日形式
|
|
929
|
+
when /\A(?:([.,\d]+)?([:*=])?W)(?:([.,\d]+)?([-*=?%])?D)?\z/
|
|
930
|
+
week = [1,3].map {|i|
|
|
931
|
+
$~[i] ? Pair._en_pair($~[i], $~[i+1]) : 0
|
|
932
|
+
}
|
|
933
|
+
return sign, nil, time if week.uniq == [0]
|
|
934
|
+
date = [0, 0, week[1] + 7*week[0]]
|
|
935
|
+
return sign, date, time, week
|
|
936
|
+
|
|
937
|
+
# 代用形式
|
|
938
|
+
else
|
|
939
|
+
pdate += 'T' + ptime if ptime
|
|
940
|
+
f, d, t, z, e = When::BasicTypes::DateTime._to_array(pdate, {:abbr=>[0]*20})
|
|
941
|
+
return nil if e
|
|
942
|
+
if d
|
|
943
|
+
case f
|
|
944
|
+
when :day ; date = [d[0], 0, d[1]]
|
|
945
|
+
when :century, nil ; date = (0..2).map {|i| d[i]||0}
|
|
946
|
+
when :week ; date, week = [0,0,d[0]*7+(d[1]||0)], [d[0], d[1]||0]
|
|
947
|
+
end
|
|
948
|
+
end
|
|
949
|
+
time = t ? (t.map {|v| v||0}) : nil
|
|
950
|
+
return sign, date, time, week
|
|
951
|
+
end
|
|
952
|
+
end
|
|
953
|
+
|
|
954
|
+
# 期間の日数
|
|
955
|
+
#
|
|
956
|
+
# @return [Integer]
|
|
957
|
+
#
|
|
958
|
+
# @note 固定の整数で表現できない場合は nil
|
|
959
|
+
#
|
|
960
|
+
attr_reader :to_day
|
|
961
|
+
|
|
962
|
+
# 期間の日付要素
|
|
963
|
+
#
|
|
964
|
+
# @return [Array<Numeric>]
|
|
965
|
+
#
|
|
966
|
+
attr_accessor :date
|
|
967
|
+
private :date=
|
|
968
|
+
|
|
969
|
+
# 期間の週日要素
|
|
970
|
+
#
|
|
971
|
+
# @return [Array<Numeric>]
|
|
972
|
+
#
|
|
973
|
+
attr_accessor :week
|
|
974
|
+
private :week=
|
|
975
|
+
|
|
976
|
+
# 期間の時刻要素
|
|
977
|
+
#
|
|
978
|
+
# @return [Array<Numeric>]
|
|
979
|
+
#
|
|
980
|
+
attr_accessor :time
|
|
981
|
+
private :time=
|
|
982
|
+
|
|
983
|
+
# 要素の参照
|
|
984
|
+
#
|
|
985
|
+
# @param [Numeric] index When::Coordinates で定義している分解能定数に対応する列挙型( YEAR, ... , SECOND)
|
|
986
|
+
#
|
|
987
|
+
# @return [Numeric]
|
|
988
|
+
#
|
|
989
|
+
def [](index)
|
|
990
|
+
if index == WEEK
|
|
991
|
+
return nil unless @week
|
|
992
|
+
return @week[0]
|
|
993
|
+
elsif index <= 0
|
|
994
|
+
return nil unless @date
|
|
995
|
+
return @date[index-1]
|
|
996
|
+
else
|
|
997
|
+
return nil unless @time
|
|
998
|
+
return @time[index]
|
|
999
|
+
end
|
|
1000
|
+
end
|
|
1001
|
+
|
|
1002
|
+
# 持続期間であることを文字'P'で示す
|
|
1003
|
+
#
|
|
1004
|
+
# @return [String]
|
|
1005
|
+
#
|
|
1006
|
+
def designator
|
|
1007
|
+
return 'P'
|
|
1008
|
+
end
|
|
1009
|
+
|
|
1010
|
+
# 期間に含まれる年数を示す
|
|
1011
|
+
#
|
|
1012
|
+
# @return [String]
|
|
1013
|
+
#
|
|
1014
|
+
def years
|
|
1015
|
+
return nil unless @date
|
|
1016
|
+
return @date[YEAR-1].to_s
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
# 期間に含まれる月数を示す
|
|
1020
|
+
#
|
|
1021
|
+
# @return [String
|
|
1022
|
+
#
|
|
1023
|
+
def months
|
|
1024
|
+
return nil unless @date
|
|
1025
|
+
return @date[MONTH-1].to_s
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
# 期間に含まれる週数を示す
|
|
1029
|
+
#
|
|
1030
|
+
# @return [String]
|
|
1031
|
+
#
|
|
1032
|
+
def weeks
|
|
1033
|
+
return nil unless @week
|
|
1034
|
+
return @week[0].to_s
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
# 期間に含まれる日数を示す
|
|
1038
|
+
#
|
|
1039
|
+
# @return [String]
|
|
1040
|
+
#
|
|
1041
|
+
def days
|
|
1042
|
+
return nil unless @date
|
|
1043
|
+
return @date[DAY-1].to_s
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
# 期間が1日より短い時間単位を含むとき文字'T'で示す
|
|
1047
|
+
#
|
|
1048
|
+
# @return [String]
|
|
1049
|
+
#
|
|
1050
|
+
def time_indicator
|
|
1051
|
+
return (@time) ? 'T' : nil
|
|
1052
|
+
end
|
|
1053
|
+
alias :timeIndicator :time_indicator
|
|
1054
|
+
|
|
1055
|
+
# 期間に含まれる時間数を示す
|
|
1056
|
+
#
|
|
1057
|
+
# @return [String]
|
|
1058
|
+
#
|
|
1059
|
+
def hours
|
|
1060
|
+
return nil unless @time
|
|
1061
|
+
return @time[HOUR].to_s
|
|
1062
|
+
end
|
|
1063
|
+
|
|
1064
|
+
# 期間に含まれる分数を示す
|
|
1065
|
+
#
|
|
1066
|
+
# @return [String]
|
|
1067
|
+
#
|
|
1068
|
+
def minutes
|
|
1069
|
+
return nil unless @time
|
|
1070
|
+
return @time[MINUTE].to_s
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
# 期間に含まれる秒数を示す
|
|
1074
|
+
#
|
|
1075
|
+
# @return [String]
|
|
1076
|
+
#
|
|
1077
|
+
def seconds
|
|
1078
|
+
return nil unless @time
|
|
1079
|
+
return @time[SECOND].to_s
|
|
1080
|
+
end
|
|
1081
|
+
|
|
1082
|
+
# 符号反転
|
|
1083
|
+
#
|
|
1084
|
+
# @return [When::TM::PeriodDuration]
|
|
1085
|
+
#
|
|
1086
|
+
def -@
|
|
1087
|
+
period = self.dup
|
|
1088
|
+
period.send(:date=, @date.map {|v| -v}) if @date
|
|
1089
|
+
period.send(:week=, @week.map {|v| -v}) if @week
|
|
1090
|
+
period.send(:time=, @time.map {|v| -v}) if @time
|
|
1091
|
+
period.send(:_duration)
|
|
1092
|
+
return period
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
# 符号
|
|
1096
|
+
#
|
|
1097
|
+
# @return [Integer] 0 との比較により、負,0,正の値を返す
|
|
1098
|
+
#
|
|
1099
|
+
def sign
|
|
1100
|
+
((@week || @date || []) + (@time || [])).each do |v|
|
|
1101
|
+
return -1 if +v < 0
|
|
1102
|
+
end
|
|
1103
|
+
return +1
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1106
|
+
# 比較
|
|
1107
|
+
#
|
|
1108
|
+
# @param [When::TM::PeriodDuration] other
|
|
1109
|
+
#
|
|
1110
|
+
# @return [Integer] other との比較により、負,0,正の値を返す
|
|
1111
|
+
#
|
|
1112
|
+
def <=>(other)
|
|
1113
|
+
unless (@date && @date.size) == (other.date && other.date.size) &&
|
|
1114
|
+
(@week && @week.size) == (other.week && other.week.size) &&
|
|
1115
|
+
(@time && @time.size) == (other.time && other.time.size)
|
|
1116
|
+
raise ArgumentError, "PeriodDuration structure mismatch"
|
|
1117
|
+
end
|
|
1118
|
+
|
|
1119
|
+
(0...@week.size).each do |i|
|
|
1120
|
+
sgn = +@week[i] <=> +other.week[i]
|
|
1121
|
+
return sgn unless sgn == 0
|
|
1122
|
+
end if @week
|
|
1123
|
+
|
|
1124
|
+
(0...@date.size).each do |i|
|
|
1125
|
+
sgn = +@date[i] <=> +other.date[i]
|
|
1126
|
+
return sgn unless sgn == 0
|
|
1127
|
+
end if @date
|
|
1128
|
+
|
|
1129
|
+
(0...@time.size).each do |i|
|
|
1130
|
+
sgn = +@time[i] <=> +other.time[i]
|
|
1131
|
+
return sgn unless sgn == 0
|
|
1132
|
+
end if @time
|
|
1133
|
+
|
|
1134
|
+
return 0
|
|
1135
|
+
end
|
|
1136
|
+
|
|
1137
|
+
# オブジェクトの同値
|
|
1138
|
+
#
|
|
1139
|
+
# @param [比較先] other
|
|
1140
|
+
#
|
|
1141
|
+
# @return [Boolean]
|
|
1142
|
+
# [ true - 同値 ]
|
|
1143
|
+
# [ false - 非同値 ]
|
|
1144
|
+
#
|
|
1145
|
+
def ==(other)
|
|
1146
|
+
(self <=> other) == 0
|
|
1147
|
+
rescue
|
|
1148
|
+
false
|
|
1149
|
+
end
|
|
1150
|
+
|
|
1151
|
+
# 加算
|
|
1152
|
+
#
|
|
1153
|
+
# @param [When::TM::PeriodDuration] other
|
|
1154
|
+
# @param [その他] other 日時とみなす
|
|
1155
|
+
#
|
|
1156
|
+
# @return [WWhen::TM::PeriodDuration] (other が When::TM::PeriodDuration の場合)
|
|
1157
|
+
# @return [other と同じクラス] (other がその他の場合)
|
|
1158
|
+
#
|
|
1159
|
+
def +(other)
|
|
1160
|
+
other.kind_of?(When::TM::PeriodDuration) ? _plus(other, +1) : other + self
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
# 減算
|
|
1164
|
+
#
|
|
1165
|
+
# @param [When::TM::PeriodDuration] other
|
|
1166
|
+
#
|
|
1167
|
+
# @return [When::TM::PeriodDuration]
|
|
1168
|
+
#
|
|
1169
|
+
def -(other)
|
|
1170
|
+
_plus(other, -1)
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1173
|
+
# 乗算
|
|
1174
|
+
#
|
|
1175
|
+
# @param [Numeric] times
|
|
1176
|
+
#
|
|
1177
|
+
# @return [When::TM::PeriodDuration]
|
|
1178
|
+
#
|
|
1179
|
+
def *(times)
|
|
1180
|
+
period = self.dup
|
|
1181
|
+
period.send(:date=, @date.map {|v| v *= times; v.to_i==v.to_f ? v.to_i : v}) if @date
|
|
1182
|
+
period.send(:week=, @week.map {|v| v *= times; v.to_i==v.to_f ? v.to_i : v}) if @week
|
|
1183
|
+
period.send(:time=, @time.map {|v| v *= times; v.to_i==v.to_f ? v.to_i : v}) if @time
|
|
1184
|
+
period.send(:_duration)
|
|
1185
|
+
return period
|
|
1186
|
+
end
|
|
1187
|
+
|
|
1188
|
+
# 除算
|
|
1189
|
+
#
|
|
1190
|
+
# @param [Numeric] divisor
|
|
1191
|
+
#
|
|
1192
|
+
# @return [When::TM::PeriodDuration]
|
|
1193
|
+
#
|
|
1194
|
+
def /(divisor)
|
|
1195
|
+
self * (1.0 / divisor)
|
|
1196
|
+
end
|
|
1197
|
+
|
|
1198
|
+
# 文字列化
|
|
1199
|
+
#
|
|
1200
|
+
# @return [String]
|
|
1201
|
+
#
|
|
1202
|
+
def to_s
|
|
1203
|
+
period = 'P'
|
|
1204
|
+
if @week
|
|
1205
|
+
period += @week[0].abs.to_s + 'W'
|
|
1206
|
+
period += @week[1].abs.to_s + 'D' unless @week[1] == 0
|
|
1207
|
+
elsif @date
|
|
1208
|
+
(-@date.length..-1).each do |i|
|
|
1209
|
+
period += @date[i].abs.to_s + PRECISION_NAME[i+1][0..0] unless @date[i] == 0
|
|
1210
|
+
end
|
|
1211
|
+
end
|
|
1212
|
+
if @time
|
|
1213
|
+
period += 'T'
|
|
1214
|
+
(1..@time.length-1).each do |i|
|
|
1215
|
+
period += @time[i].abs.to_s + PRECISION_NAME[i][0..0] unless @time[i] == 0
|
|
1216
|
+
end
|
|
1217
|
+
end
|
|
1218
|
+
period = '-' + period if sign < 0
|
|
1219
|
+
period == 'P' ? 'P0D' : period
|
|
1220
|
+
end
|
|
1221
|
+
|
|
1222
|
+
#
|
|
1223
|
+
# When::TM::PeriodDuration への変換
|
|
1224
|
+
#
|
|
1225
|
+
# 単なるオブジェクトのコピー
|
|
1226
|
+
#
|
|
1227
|
+
# @return [When::TM::PeriodDuration]
|
|
1228
|
+
#
|
|
1229
|
+
def to_period_duration
|
|
1230
|
+
self.dup
|
|
1231
|
+
end
|
|
1232
|
+
|
|
1233
|
+
# オブジェクトの生成
|
|
1234
|
+
#
|
|
1235
|
+
# @overload initialize(date=nil, time=nil, week=nil)
|
|
1236
|
+
# @param [Array<Numeric>] date 期間の日付要素
|
|
1237
|
+
# @param [Array<Numeric>] time 期間の時刻要素
|
|
1238
|
+
# @param [Array<Numeric>] week 期間の週日要素
|
|
1239
|
+
#
|
|
1240
|
+
# @overload initialize(value, index, range=YEAR..SECOND)
|
|
1241
|
+
# @param [Numeric] value ndex に対応する桁での)時間間隔
|
|
1242
|
+
# @param [Numeric] index When で定義している分解能定数(YEAR, ... ,SECOND)
|
|
1243
|
+
# @param [Range] range 生成する桁の範囲
|
|
1244
|
+
#
|
|
1245
|
+
def initialize(*args)
|
|
1246
|
+
@options = (args[-1].kind_of?(Hash)) ? (args.pop.reject {|key,value| value == nil}) : {}
|
|
1247
|
+
if args[0].kind_of?(Numeric)
|
|
1248
|
+
_initialize_by_unit(*args)
|
|
1249
|
+
else
|
|
1250
|
+
@date, @time, @week = args
|
|
1251
|
+
end
|
|
1252
|
+
_duration
|
|
1253
|
+
end
|
|
1254
|
+
|
|
1255
|
+
private
|
|
1256
|
+
|
|
1257
|
+
#
|
|
1258
|
+
# 引数パターン2での初期化
|
|
1259
|
+
#
|
|
1260
|
+
def _initialize_by_unit(value, index, range=YEAR..SECOND)
|
|
1261
|
+
max = range.first
|
|
1262
|
+
min = range.last
|
|
1263
|
+
min += 1 if (range.exclude_end?)
|
|
1264
|
+
if (index < max)
|
|
1265
|
+
if (index > MONTH)
|
|
1266
|
+
max = index.floor
|
|
1267
|
+
else
|
|
1268
|
+
value *= 10**(max-index)
|
|
1269
|
+
index = max
|
|
1270
|
+
end
|
|
1271
|
+
elsif (index > min)
|
|
1272
|
+
if (index <= DAY)
|
|
1273
|
+
min = index.ceil
|
|
1274
|
+
else
|
|
1275
|
+
value *= 0.1**(index-min)
|
|
1276
|
+
index = min
|
|
1277
|
+
end
|
|
1278
|
+
end
|
|
1279
|
+
value = value.to_i unless value.kind_of?(Pair) || value.to_i != value.to_f
|
|
1280
|
+
@date = Array.new(1-max, 0) if (max <= DAY) && (index <= DAY)
|
|
1281
|
+
@time = Array.new(1+min, 0) if (min > DAY) && (index > DAY)
|
|
1282
|
+
if (index == WEEK)
|
|
1283
|
+
@week = [value, 0]
|
|
1284
|
+
@date[DAY-1] = 7 * value
|
|
1285
|
+
elsif (index <= DAY)
|
|
1286
|
+
@date[index-1] = value
|
|
1287
|
+
else
|
|
1288
|
+
@time[index] = value
|
|
1289
|
+
end
|
|
1290
|
+
end
|
|
1291
|
+
|
|
1292
|
+
#
|
|
1293
|
+
# 属性 @duration の計算
|
|
1294
|
+
#
|
|
1295
|
+
def _duration
|
|
1296
|
+
@duration = nil
|
|
1297
|
+
|
|
1298
|
+
if @time
|
|
1299
|
+
@duration = +@time[HOUR ] * Duration::HOUR
|
|
1300
|
+
@duration += +@time[MINUTE] * Duration::MINUTE if @time[MINUTE]
|
|
1301
|
+
@duration += +@time[SECOND] * Duration::SECOND if @time[SECOND]
|
|
1302
|
+
end
|
|
1303
|
+
|
|
1304
|
+
if @week
|
|
1305
|
+
@duration = +@week[0] * Duration::WEEK + +@week[1] * Duration::DAY + (@duration||0)
|
|
1306
|
+
|
|
1307
|
+
elsif @date
|
|
1308
|
+
date = @date.dup
|
|
1309
|
+
date.shift while date.first == 0
|
|
1310
|
+
case date.size
|
|
1311
|
+
when 0 ; @duration ||= 0
|
|
1312
|
+
when 1 ; @duration = +@date[DAY-1] * Duration::DAY + (@duration||0)
|
|
1313
|
+
else ; @duration = nil
|
|
1314
|
+
end
|
|
1315
|
+
end
|
|
1316
|
+
|
|
1317
|
+
if @duration
|
|
1318
|
+
length = @duration / Duration::DAY
|
|
1319
|
+
@to_day = length.to_i if length.to_i == length.to_f
|
|
1320
|
+
else
|
|
1321
|
+
extend NoDuration
|
|
1322
|
+
end
|
|
1323
|
+
end
|
|
1324
|
+
|
|
1325
|
+
# 加減算共通処理
|
|
1326
|
+
#
|
|
1327
|
+
# @param [When::TM::PeriodDuration] other
|
|
1328
|
+
# @param [Numeric] sgn +1, -1
|
|
1329
|
+
#
|
|
1330
|
+
# @return [When::TM::PeriodDuration]
|
|
1331
|
+
#
|
|
1332
|
+
def _plus(other, sgn)
|
|
1333
|
+
unless (@week && @week.size) == (other.week && other.week.size) &&
|
|
1334
|
+
(@date && @date.size) == (other.date && other.date.size) &&
|
|
1335
|
+
(@time && @time.size) == (other.time && other.time.size)
|
|
1336
|
+
raise ArgumentError, "PeriodDuration structure mismatch"
|
|
1337
|
+
end
|
|
1338
|
+
period = self.dup
|
|
1339
|
+
period.send(:week=, (0...@week.size).to_a.map {|i| @week[i] + sgn * other.week[i]}) if @week
|
|
1340
|
+
period.send(:date=, (0...@date.size).to_a.map {|i| @date[i] + sgn * other.date[i]}) if @date
|
|
1341
|
+
period.send(:time=, (0...@time.size).to_a.map {|i| @time[i] + sgn * other.time[i]}) if @time
|
|
1342
|
+
period.send(:_duration)
|
|
1343
|
+
return period
|
|
1344
|
+
end
|
|
1345
|
+
end
|
|
1346
|
+
end
|