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/tmposition.rb
CHANGED
|
@@ -1,2072 +1,2115 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
=begin
|
|
3
|
-
Copyright (C) 2011-2014 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.4) Temporal Position Package
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
# 列挙データ型である When::TM::IndeterminateValue は,不確定な位置のために
|
|
15
|
-
# 6つの値を規定する.このうち Min と Max は 本ライブラリでの拡張である.
|
|
16
|
-
#
|
|
17
|
-
# These values are interpreted as follows:
|
|
18
|
-
#- “Unknown” 時間位置を示す値が与えられていないことを示す(本ライブラリでは“Unknown”は使用しない)
|
|
19
|
-
#- “Now” 常に現時点の時間位置を示す(オブジェクト生成時の時間位置でないことに注意)
|
|
20
|
-
#- “Before” 実際の時間位置は未知だが、指定した値よりも前であることを示す(本ライブラリでは“Before”は無視される)
|
|
21
|
-
#- “After” 実際の時間位置は未知だが、指定した値よりも後であることを示す(本ライブラリでは“After”は無視される)
|
|
22
|
-
#- “Min” 無限の過去を示す
|
|
23
|
-
#- “Max” 無限の未来を示す
|
|
24
|
-
#
|
|
25
|
-
# see {gml schema}[link:http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimeIndeterminateValueType]
|
|
26
|
-
#
|
|
27
|
-
module IndeterminateValue
|
|
28
|
-
|
|
29
|
-
After = :After
|
|
30
|
-
Before = :Before
|
|
31
|
-
Now = :Now
|
|
32
|
-
Unknown = :Unknown
|
|
33
|
-
# additional value for this library
|
|
34
|
-
Min = :Min
|
|
35
|
-
# additional value for this library
|
|
36
|
-
Max = :Max
|
|
37
|
-
|
|
38
|
-
S = {'After'=>After, 'Before'=>Before, 'Now'=>Now, 'Unknown'=>Unknown, '-Infinity'=>Min, '+Infinity'=>Max}
|
|
39
|
-
I = S.invert
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# 時間位置共用体
|
|
43
|
-
# union of
|
|
44
|
-
# When::TM::TemporalPosition
|
|
45
|
-
# When::BasicTypes::Date
|
|
46
|
-
# When::BasicTypes::Time
|
|
47
|
-
# When::BasicTypes::DateTime
|
|
48
|
-
#
|
|
49
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimePositionType gml schema}
|
|
50
|
-
#
|
|
51
|
-
class Position
|
|
52
|
-
|
|
53
|
-
include IndeterminateValue
|
|
54
|
-
include When::Parts::Resource
|
|
55
|
-
|
|
56
|
-
# @private
|
|
57
|
-
HashProperty =
|
|
58
|
-
[:indeterminated_position, :frame,
|
|
59
|
-
[:precision, When::SYSTEM], :events, :options, :trans, :query,
|
|
60
|
-
:location, [:time_standard, When::TimeStandard::UniversalTime], [:rate_of_clock, 1.0]]
|
|
61
|
-
|
|
62
|
-
# 代表文字列
|
|
63
|
-
#
|
|
64
|
-
# @return [When::BasicTypes::DateTime]
|
|
65
|
-
#
|
|
66
|
-
attr_reader :date_time8601
|
|
67
|
-
alias :dateTime8601 :date_time8601
|
|
68
|
-
|
|
69
|
-
# 時間位置
|
|
70
|
-
#
|
|
71
|
-
# @return [When::TM::TemporalPosition]
|
|
72
|
-
#
|
|
73
|
-
attr_reader :any_other
|
|
74
|
-
alias :anyOther :any_other
|
|
75
|
-
|
|
76
|
-
# 諸々のオブジェクトから When::TM::TemporalPosition を取り出す
|
|
77
|
-
#
|
|
78
|
-
# @param [Object] position 変換元の時間位置
|
|
79
|
-
# @param [Hash] options
|
|
80
|
-
# see {When::TM::TemporalPosition._instance}
|
|
81
|
-
#
|
|
82
|
-
# @return [When::TM::TemporalPosition] position の型により下記を返す
|
|
83
|
-
# - {When::BasicTypes::Date}, {When::BasicTypes::Time}, {When::BasicTypes::DateTime} - When::TM::Calendar#jul_trans による変換結果
|
|
84
|
-
# - {When::TM::TemporalPosition} - そのまま position ( optionは無視 )
|
|
85
|
-
# - {When::TM::Position} - position.any_other ( optionは無視 )
|
|
86
|
-
# - {When::Parts::GeometricComplex} - position.first ( optionは無視 )
|
|
87
|
-
#
|
|
88
|
-
def self.any_other(position, options={})
|
|
89
|
-
case position
|
|
90
|
-
when TemporalPosition ; position
|
|
91
|
-
when Position ; position.any_other
|
|
92
|
-
when When::Parts::GeometricComplex ; position.first
|
|
93
|
-
else ; When.Calendar(options[:frame] || 'Gregorian').jul_trans(position, options) || position
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# オブジェクトの生成
|
|
98
|
-
#
|
|
99
|
-
# @param [String] specification When.exe Standard Representation として解釈して生成する
|
|
100
|
-
# @param [Hash] options 暦法や時法などの指定
|
|
101
|
-
# see {When::TM::TemporalPosition._instance}
|
|
102
|
-
#
|
|
103
|
-
# @note
|
|
104
|
-
# specification が String 以外の場合、そのオブジェクトの代表的な日時
|
|
105
|
-
# (When::TM::CalendarEra#reference_dateなど)により解釈する
|
|
106
|
-
#
|
|
107
|
-
def initialize(specification, options={})
|
|
108
|
-
|
|
109
|
-
case specification
|
|
110
|
-
when String
|
|
111
|
-
@date_time8601 = specification
|
|
112
|
-
@any_other = TemporalPosition._instance(specification, options)
|
|
113
|
-
when Position
|
|
114
|
-
@date_time8601 = specification.date_time8601
|
|
115
|
-
@any_other = specification.any_other
|
|
116
|
-
return
|
|
117
|
-
else
|
|
118
|
-
@any_other = specification
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
klass = specification.class
|
|
122
|
-
message = "Irregal specification type: #{klass}"
|
|
123
|
-
|
|
124
|
-
case specification
|
|
125
|
-
when CalDate ; @date_time8601 = When::BasicTypes::Date.new(specification.to_s)
|
|
126
|
-
when ClockTime ; @date_time8601 = When::BasicTypes::Time.new(specification.to_s)
|
|
127
|
-
when TemporalPosition ; @date_time8601 = When::BasicTypes::DateTime.new(specification.to_s)
|
|
128
|
-
when CalendarEra ; @date_time8601 = When::BasicTypes::Date.new(specification.reference_date.to_s)
|
|
129
|
-
when OrdinalEra ; @date_time8601 = When::BasicTypes::Date.new(specification.begin.to_s)
|
|
130
|
-
when When::BasicTypes::Date ; raise TypeError, message unless klass == CalDate
|
|
131
|
-
when When::BasicTypes::Time ; raise TypeError, message unless klass == ClockTime
|
|
132
|
-
when String ;
|
|
133
|
-
else ; raise TypeError, message
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
private
|
|
138
|
-
|
|
139
|
-
alias :_method_missing :method_missing
|
|
140
|
-
|
|
141
|
-
# その他のメソッド
|
|
142
|
-
#
|
|
143
|
-
# @note
|
|
144
|
-
# When::TM::Position で定義されていないメソッドは
|
|
145
|
-
# 処理を @date_time8601 (type: When::BasicTypes::DateTime)
|
|
146
|
-
# または @any_other (type: When::TM::TemporalPosition) に委譲する
|
|
147
|
-
# (両方ともに有効なメソッドは@any_otherを優先する)
|
|
148
|
-
#
|
|
149
|
-
def method_missing(name, *args, &block)
|
|
150
|
-
return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
|
|
151
|
-
self.class.module_eval %Q{
|
|
152
|
-
def #{name}(*args, &block)
|
|
153
|
-
union = @any_other.respond_to?("#{name}") ? @any_other : @date_time8601
|
|
154
|
-
union.send("#{name}", *args, &block)
|
|
155
|
-
end
|
|
156
|
-
} unless When::Parts::MethodCash.escape(name)
|
|
157
|
-
union = @any_other.respond_to?(name) ? @any_other : @date_time8601
|
|
158
|
-
union.send(name, *args, &block)
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
# 「時間位置」の基底クラス
|
|
163
|
-
#
|
|
164
|
-
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#TemporalPositionType gml schema}
|
|
165
|
-
#
|
|
166
|
-
class TemporalPosition < ::Object
|
|
167
|
-
|
|
168
|
-
#
|
|
169
|
-
# When::TM::JulianDate, When::TM::CalDate or DateAndTime への変換メソッドを提供
|
|
170
|
-
#
|
|
171
|
-
module Conversion
|
|
172
|
-
#
|
|
173
|
-
# 対応する When::TM::JulianDate を生成
|
|
174
|
-
#
|
|
175
|
-
# @param [Hash] options 以下の通り
|
|
176
|
-
# @option options [When::TM::Clock] :clock
|
|
177
|
-
# @option options [When::Parts::Timezone] :tz
|
|
178
|
-
#
|
|
179
|
-
# @return [When::TM::JulianDate]
|
|
180
|
-
#
|
|
181
|
-
def julian_date(options={})
|
|
182
|
-
When::TM::JulianDate.new(self, options)
|
|
183
|
-
end
|
|
184
|
-
alias :to_julian_date :julian_date
|
|
185
|
-
|
|
186
|
-
#
|
|
187
|
-
# 対応する When::TM::CalDate or DateAndTime を生成
|
|
188
|
-
#
|
|
189
|
-
# @param [Hash] options 暦法や時法などの指定
|
|
190
|
-
# see {When::TM::TemporalPosition._instance}
|
|
191
|
-
#
|
|
192
|
-
# @return [When::TM::CalDate, When::TM::DateAndTime]
|
|
193
|
-
#
|
|
194
|
-
def tm_pos(options={})
|
|
195
|
-
When.Calendar(options[:frame] || 'Gregorian').jul_trans(self, options)
|
|
196
|
-
end
|
|
197
|
-
alias :to_tm_pos :tm_pos
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
include When
|
|
201
|
-
include Comparable
|
|
202
|
-
include IndeterminateValue
|
|
203
|
-
include Coordinates
|
|
204
|
-
include Parts::Resource
|
|
205
|
-
include Conversion
|
|
206
|
-
|
|
207
|
-
# @private
|
|
208
|
-
HashProperty = Position::HashProperty
|
|
209
|
-
|
|
210
|
-
# この時間位置の意味づけ
|
|
211
|
-
#
|
|
212
|
-
# @return [When::TM::IndeterminateValue]
|
|
213
|
-
#
|
|
214
|
-
attr_reader :indeterminated_position
|
|
215
|
-
alias :indeterminatedPosition :indeterminated_position
|
|
216
|
-
|
|
217
|
-
# この時間位置と関連付けられた時間参照系 (relation - Reference)
|
|
218
|
-
#
|
|
219
|
-
# The time reference system associated with the temporal position being described
|
|
220
|
-
#
|
|
221
|
-
# @return [When::TM::ReferenceSystem]
|
|
222
|
-
#
|
|
223
|
-
attr_accessor :frame
|
|
224
|
-
|
|
225
|
-
# この時間位置と関連付けられたイベント - additional attribute
|
|
226
|
-
#
|
|
227
|
-
# @return [Array<When::Parts::Enumerator>]
|
|
228
|
-
#
|
|
229
|
-
attr_accessor :events
|
|
230
|
-
#protected :events=
|
|
231
|
-
|
|
232
|
-
# この時間位置の分解能 - additional attribute
|
|
233
|
-
#
|
|
234
|
-
# @return [Numeric]
|
|
235
|
-
#
|
|
236
|
-
# @note precision より resolution の方が分解能の意味にふさわしいが ISO19108 で別の意味に用いられているため resolution とした。
|
|
237
|
-
#
|
|
238
|
-
attr_accessor :precision
|
|
239
|
-
|
|
240
|
-
# その他の属性 - additional attribute
|
|
241
|
-
#
|
|
242
|
-
# @return [Hash] { String=>Object }
|
|
243
|
-
#
|
|
244
|
-
attr_reader :options
|
|
245
|
-
|
|
246
|
-
# その他の属性 - additional attribute
|
|
247
|
-
#
|
|
248
|
-
# @return [Hash] { String=>Object }
|
|
249
|
-
#
|
|
250
|
-
attr_accessor :trans
|
|
251
|
-
|
|
252
|
-
# その他の属性 - additional attribute
|
|
253
|
-
#
|
|
254
|
-
# @return [Hash] { String=>When::BasicTypes::M17n }
|
|
255
|
-
#
|
|
256
|
-
attr_accessor :query
|
|
257
|
-
|
|
258
|
-
# その他の属性 - additional attribute
|
|
259
|
-
#
|
|
260
|
-
# @return [When::Coordinates::Spatial]
|
|
261
|
-
#
|
|
262
|
-
attr_accessor :location
|
|
263
|
-
|
|
264
|
-
class << self
|
|
265
|
-
|
|
266
|
-
include When
|
|
267
|
-
include Coordinates
|
|
268
|
-
|
|
269
|
-
# Temporal Objetct の生成
|
|
270
|
-
#
|
|
271
|
-
# @param [String] specification When.exe Standard Representation
|
|
272
|
-
# @param [Hash] options 下記の通り
|
|
273
|
-
# @option options [When::TM::ReferenceSystem] :frame 暦法の指定
|
|
274
|
-
# @option options [When::Parts::Timezone::Base, String] :clock 時法の指定
|
|
275
|
-
# @option options [String] :tz 時法の指定(時間帯を指定する場合 :clock の替わりに用いることができる)
|
|
276
|
-
# @option options [Array<Numeric>] :abbr ISO8601上位省略形式のためのデフォルト日付(省略時 指定なし)
|
|
277
|
-
# @option options [Integer] :extra_year_digits ISO8601拡大表記のための年の構成要素拡大桁数(省略時 1桁)
|
|
278
|
-
# @option options [Integer] :ordinal_date_digits ISO8601拡大表記の年内通日の桁数(省略時 3桁)
|
|
279
|
-
# @option options [String] :wkst ISO8601週日形式のための暦週開始曜日(省略時 'MO')
|
|
280
|
-
# @option options [Integer] :precision 生成するオブジェクトの分解能
|
|
281
|
-
# @option options [When::TimeStandard::TimeStandard] :time_standard 時刻系の指定(省略時 When::TimeStandard::UnversalTime)
|
|
282
|
-
# @option options [When::Ephemeris::Spatial] :location 観測地の指定(省略時 指定なし)
|
|
283
|
-
# @option options [String] :era_name 暦年代
|
|
284
|
-
# @option options [Hash] :trans 暦年代の上下限
|
|
285
|
-
# - :count => 条件に合致する暦年代のうち何番目を採用するか
|
|
286
|
-
# - :lower => 暦年代適用の下限
|
|
287
|
-
# true - epoch_of_use の始め(省略時)
|
|
288
|
-
# :reference_date - 参照事象の日付
|
|
289
|
-
# - :upper => 暦年代適用の上限
|
|
290
|
-
# true - epoch_of_use の終わり(省略時)
|
|
291
|
-
# :reference_date - 参照事象の日付
|
|
292
|
-
# @option options [Hash] :query 暦年代の絞込み条件
|
|
293
|
-
# - :area => area による暦年代絞込み
|
|
294
|
-
# - :period => period による暦年代絞込み
|
|
295
|
-
# - :name => name による暦年代絞込み(epoch の attribute使用可)
|
|
296
|
-
#
|
|
297
|
-
# @note options の中身は本メソッドによって更新されることがある。
|
|
298
|
-
#
|
|
299
|
-
# @note :tz は 'Asia/Tokyo'など時間帯を表す文字列をキーにして、登録済みのWhen::V::Timezone, When::Parts::Timezoneを検索して使用する。
|
|
300
|
-
# :clock はWhen::Parts::Timezone::Baseオブジェクトをそのまま使用するか '+09:00'などの文字列をWhen::TM::Clock化して使用する。
|
|
301
|
-
# :tz の方が :clock よりも優先される。
|
|
302
|
-
#
|
|
303
|
-
# @return [When::TM::TemporalPosition] ISO8601 time point
|
|
304
|
-
# @return [When::TM::Duration] ISO8601 duration
|
|
305
|
-
# @return [When::Parts::GeometricComplex] ISO8601 repeating interval
|
|
306
|
-
#
|
|
307
|
-
def _instance(specification, options={})
|
|
308
|
-
|
|
309
|
-
# Suffix - Frame specification
|
|
310
|
-
rfc5545form, frame, *rest = specification.split(/\^{1,2}/)
|
|
311
|
-
return rest.inject(_instance(rfc5545form + '^' + frame, options)) {|p,c| When.Resource(c, '_c:').jul_trans(p)} if rest.size > 0
|
|
312
|
-
|
|
313
|
-
options[:frame] = When.Resource(frame, '_c:') if (frame)
|
|
314
|
-
|
|
315
|
-
# Prefix - RFC 5545 Options
|
|
316
|
-
if (rfc5545form =~
|
|
317
|
-
rfc5545option, iso8601form = $~[1..2]
|
|
318
|
-
rfc5545option.split(/;/).each do |eq|
|
|
319
|
-
key, value = eq.split(/=/, 2)
|
|
320
|
-
case key
|
|
321
|
-
when 'VALUE' ; options[:precision] = value
|
|
322
|
-
when 'TZID' ; options[:clock] =
|
|
323
|
-
case When::V::Timezone[value]
|
|
324
|
-
when Array ; When::V::Timezone[value][-1]
|
|
325
|
-
when nil ; When::Parts::Timezone.new(value)
|
|
326
|
-
else ; When::V::Timezone[value]
|
|
327
|
-
end
|
|
328
|
-
else ; options[key] = value
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
else
|
|
332
|
-
iso8601form = rfc5545form
|
|
333
|
-
end
|
|
334
|
-
options = options.dup
|
|
335
|
-
|
|
336
|
-
# IndeterminateValue
|
|
337
|
-
if (iso8601form.sub!(/\/After$|^Before\/|^Now$|^Unknown$|^[-+]Infinity
|
|
338
|
-
options[:indeterminated_position] = When::TimeValue::S[$&.sub(/\//,'')]
|
|
339
|
-
case options[:indeterminated_position]
|
|
340
|
-
when When::TimeValue::Now,
|
|
341
|
-
When::TimeValue::Unknown,
|
|
342
|
-
When::TimeValue::Max,
|
|
343
|
-
When::TimeValue::Min
|
|
344
|
-
return self.new(self._options(options))
|
|
345
|
-
end
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
# each specification
|
|
349
|
-
splitted = iso8601form.split(/\//)
|
|
350
|
-
if (splitted[0] =~
|
|
351
|
-
repeat = $1 ? $1.to_i : true
|
|
352
|
-
splitted.shift
|
|
353
|
-
end
|
|
354
|
-
case splitted.length
|
|
355
|
-
when 1
|
|
356
|
-
when 2
|
|
357
|
-
if (splitted[0] !~
|
|
358
|
-
splitted[1] = splitted[0][0..(splitted[0].length-splitted[1].length-1)] + splitted[1]
|
|
359
|
-
end
|
|
360
|
-
else
|
|
361
|
-
raise ArgumentError, "Irregal ISO8601 Format: #{iso8601form}"
|
|
362
|
-
end
|
|
363
|
-
options = self._options(options)
|
|
364
|
-
element = splitted.map { |v| _date_time_or_duration(v, options.dup) }
|
|
365
|
-
|
|
366
|
-
# total result
|
|
367
|
-
case repeat
|
|
368
|
-
when nil
|
|
369
|
-
case element[1]
|
|
370
|
-
when nil
|
|
371
|
-
return element[0]
|
|
372
|
-
when Duration
|
|
373
|
-
case element[0]
|
|
374
|
-
when Duration ; raise TypeError, "Duplicate Duration: #{element[0]} and #{element[1]}"
|
|
375
|
-
when self ; return When::Parts::GeometricComplex.new(*element)
|
|
376
|
-
else ; return When::Parts::GeometricComplex.new(element[0].first, element[1])
|
|
377
|
-
end
|
|
378
|
-
when self
|
|
379
|
-
case element[0]
|
|
380
|
-
when Duration ; return When::Parts::GeometricComplex.new([[element[1]-element[0],false], [element[1],true ]])
|
|
381
|
-
when self ; return When::Parts::GeometricComplex.new(element[0]..element[1])
|
|
382
|
-
else ; return When::Parts::GeometricComplex.new(element[0].first..element[1])
|
|
383
|
-
end
|
|
384
|
-
else
|
|
385
|
-
case element[0]
|
|
386
|
-
when Duration ; return When::Parts::GeometricComplex.new([[element[1].first-element[0],false],
|
|
387
|
-
[element[1].last-element[0]-1,true ]])
|
|
388
|
-
when self ; return When::Parts::GeometricComplex.new(element[0]...element[1].last)
|
|
389
|
-
else ; return When::Parts::GeometricComplex.new(element[0].first...element[1].last)
|
|
390
|
-
end
|
|
391
|
-
end
|
|
392
|
-
when 0 ; return []
|
|
393
|
-
when Integer ; return [element[0]] * repeat unless element[1]
|
|
394
|
-
end
|
|
395
|
-
|
|
396
|
-
case element[1]
|
|
397
|
-
when Duration
|
|
398
|
-
case element[0]
|
|
399
|
-
when Duration ; raise TypeError, "Duplicate Duration: #{element[0]} and #{element[1]}"
|
|
400
|
-
else ; duration = element[1]
|
|
401
|
-
end
|
|
402
|
-
when self
|
|
403
|
-
case element[0]
|
|
404
|
-
when Duration ; duration = -element[0]
|
|
405
|
-
when self ; duration = element[1] - element[0]
|
|
406
|
-
else ; duration = element[1] - element[0].first
|
|
407
|
-
end
|
|
408
|
-
else
|
|
409
|
-
case element[0]
|
|
410
|
-
when Duration ; duration = -element[0]
|
|
411
|
-
when self ; duration = element[1].first - element[0]
|
|
412
|
-
else ; duration = element[1].first - element[0].first
|
|
413
|
-
end
|
|
414
|
-
end
|
|
415
|
-
base = element[0].kind_of?(Duration) ? element[1] : element[0]
|
|
416
|
-
|
|
417
|
-
if repeat.kind_of?(Integer)
|
|
418
|
-
result = case base
|
|
419
|
-
when self ; (1..repeat-1).inject([base]) {|a,i| a << (a[-1] + duration) }
|
|
420
|
-
else ; (1..repeat-1).inject([base]) {|a,i| a << When::Parts::GeometricComplex.new(
|
|
421
|
-
a[-1].first+duration...a[-1].last+duration)}
|
|
422
|
-
end
|
|
423
|
-
result.reverse! if duration.sign < 0
|
|
424
|
-
return result
|
|
425
|
-
|
|
426
|
-
else
|
|
427
|
-
duration = -duration if duration.sign < 0
|
|
428
|
-
return case base
|
|
429
|
-
when self ; When::V::Event.new({'rrule'=>{'FREQ'=>duration}, 'dtstart'=>base})
|
|
430
|
-
else ; When::V::Event.new({'rrule'=>{'FREQ'=>duration}, 'dtstart'=>base.first,
|
|
431
|
-
'dtend' =>base.last})
|
|
432
|
-
end
|
|
433
|
-
end
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
# option の正規化
|
|
437
|
-
# @private
|
|
438
|
-
def _options(options)
|
|
439
|
-
query = options.dup
|
|
440
|
-
main = {}
|
|
441
|
-
clock = Clock.get_clock_option(query)
|
|
442
|
-
main[:clock] = clock if clock
|
|
443
|
-
[:indeterminated_position, :frame, :events, :precision,
|
|
444
|
-
:era_name, :era, :abbr, :extra_year_digits, :ordinal_date_digits, :wkst, :time_standard, :location].each do |key|
|
|
445
|
-
main[key] = query.delete(key) if (query.key?(key))
|
|
446
|
-
end
|
|
447
|
-
long = query.delete(:long)
|
|
448
|
-
lat = query.delete(:lat)
|
|
449
|
-
alt = query.delete(:alt)
|
|
450
|
-
main[:location] ||= "_l:long=#{long||0}&lat=#{lat||0}&alt=#{alt||0}" if long && lat
|
|
451
|
-
trans = query.delete(:trans) || {}
|
|
452
|
-
[:lower, :upper, :count].each do |key|
|
|
453
|
-
trans[key] = query.delete(key) if (query.key?(key))
|
|
454
|
-
end
|
|
455
|
-
query = query.merge(query.delete(:query)) if (query.key?(:query))
|
|
456
|
-
main[:query] = query if (query.size > 0)
|
|
457
|
-
main[:trans] = trans if (trans.size > 0)
|
|
458
|
-
return main
|
|
459
|
-
end
|
|
460
|
-
|
|
461
|
-
# 比較
|
|
462
|
-
# @private
|
|
463
|
-
def _verify(source, target)
|
|
464
|
-
return source.universal_time <=> target.universal_time if source.time_standard.equal?(target.time_standard)
|
|
465
|
-
return source.dynamical_time <=> target.dynamical_time
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
private
|
|
469
|
-
|
|
470
|
-
# date_time_or_duration
|
|
471
|
-
def _date_time_or_duration(specification, options)
|
|
472
|
-
# IntervalLength
|
|
473
|
-
args = IntervalLength._to_array(specification)
|
|
474
|
-
return IntervalLength.new(*args) if args
|
|
475
|
-
|
|
476
|
-
# PeriodDuration
|
|
477
|
-
sign, *args = PeriodDuration._to_array(specification)
|
|
478
|
-
if (sign)
|
|
479
|
-
args << options
|
|
480
|
-
duration = PeriodDuration.new(*args)
|
|
481
|
-
return (sign >= 0) ? duration : -duration
|
|
482
|
-
end
|
|
483
|
-
|
|
484
|
-
# TemporalPosition
|
|
485
|
-
specification =~ /(.+?)(?:\[([-+]?\d+)\])
|
|
486
|
-
options[:sdn] = $2.to_i if $2
|
|
487
|
-
f, d, t, z, e = When::BasicTypes::DateTime._to_array($1, options)
|
|
488
|
-
raise ArgumentError, "Timezone conflict: #{z} - #{options[:clock]}" if (z && options[:clock])
|
|
489
|
-
options.delete(:abbr)
|
|
490
|
-
z ||= options[:clock]
|
|
491
|
-
z = When.Clock(z) if (z =~
|
|
492
|
-
|
|
493
|
-
unless (d)
|
|
494
|
-
# ClockTime
|
|
495
|
-
raise ArgumentError, "Timezone conflict: #{z} - #{options[:clock]}" if (z && options[:frame])
|
|
496
|
-
options[:frame] ||= z
|
|
497
|
-
options.delete(:clock)
|
|
498
|
-
return ClockTime.new(t, options)
|
|
499
|
-
end
|
|
500
|
-
|
|
501
|
-
options[:era_name] = e if e
|
|
502
|
-
options[:_format ] = f if f
|
|
503
|
-
d, w = d[0..0], d[1..-1] if (f == :week || f == :day)
|
|
504
|
-
position = z ? DateAndTime.new(d, t||[0], options.update({:clock => z})) :
|
|
505
|
-
t ? DateAndTime.new(d, t, options) :
|
|
506
|
-
CalDate.new(d, options)
|
|
507
|
-
case f
|
|
508
|
-
when :day
|
|
509
|
-
position += PeriodDuration.new(w[0]-1, DAY)
|
|
510
|
-
when :week
|
|
511
|
-
position = ((position + PeriodDuration.new(4, DAY)) & (Residue.day_of_week(options[:wkst]) << 1)) +
|
|
512
|
-
PeriodDuration.new((w[0]-1)*7 + (w[1]||1)-1, DAY)
|
|
513
|
-
position = When::Parts::GeometricComplex.new(position...(position+P1W)) unless w[1]
|
|
514
|
-
end
|
|
515
|
-
return position
|
|
516
|
-
end
|
|
517
|
-
end
|
|
518
|
-
|
|
519
|
-
# 時刻系
|
|
520
|
-
#
|
|
521
|
-
# @return [When::TimeStandard]
|
|
522
|
-
#
|
|
523
|
-
def time_standard
|
|
524
|
-
return @time_standard if @time_standard.kind_of?(When::TimeStandard)
|
|
525
|
-
@time_standard ||= clock.time_standard if respond_to?(:clock) && clock
|
|
526
|
-
@time_standard ||= frame.time_standard if frame
|
|
527
|
-
@time_standard ||= 'UniversalTime'
|
|
528
|
-
@time_standard = When.Resource(@time_standard, '_t:')
|
|
529
|
-
end
|
|
530
|
-
|
|
531
|
-
# 時間の歩度
|
|
532
|
-
#
|
|
533
|
-
# @return [Numeric]
|
|
534
|
-
#
|
|
535
|
-
def rate_of_clock
|
|
536
|
-
time_standard.rate_of_clock
|
|
537
|
-
end
|
|
538
|
-
|
|
539
|
-
# 内部時間
|
|
540
|
-
#
|
|
541
|
-
# @return [Numeric]
|
|
542
|
-
#
|
|
543
|
-
# 1970-01-01T00:00:00Z からの Universal Time, Coordinated の経過時間 / 128秒
|
|
544
|
-
#
|
|
545
|
-
# 暦法によっては、異なる意味を持つことがある
|
|
546
|
-
#
|
|
547
|
-
def universal_time
|
|
548
|
-
case @indeterminated_position
|
|
549
|
-
when Now ; time_standard.from_time_object(Time.now)
|
|
550
|
-
when Max ; +Float::MAX/4
|
|
551
|
-
when Min ; -Float::MAX/4
|
|
552
|
-
else ; raise NameError, "Temporal Reference System is not defined"
|
|
553
|
-
end
|
|
554
|
-
end
|
|
555
|
-
|
|
556
|
-
# 外部時間
|
|
557
|
-
#
|
|
558
|
-
# @return [Numeric]
|
|
559
|
-
#
|
|
560
|
-
# 1970-01-01T00:00:00TT からの terrestrial time の経過時間 / 128秒
|
|
561
|
-
#
|
|
562
|
-
def dynamical_time
|
|
563
|
-
return @dynamical_time if @dynamical_time && @indeterminated_position != Now
|
|
564
|
-
@dynamical_time =
|
|
565
|
-
case @indeterminated_position
|
|
566
|
-
when Max ; +Float::MAX/4
|
|
567
|
-
when Min ; -Float::MAX/4
|
|
568
|
-
else ; time_standard.to_dynamical_time(universal_time)
|
|
569
|
-
end
|
|
570
|
-
end
|
|
571
|
-
|
|
572
|
-
# ユリウス日時(実数)
|
|
573
|
-
#
|
|
574
|
-
# @return [Float]
|
|
575
|
-
#
|
|
576
|
-
# universal time での経過日数を, ユリウス日と1970-01-01T00:00:00Zで時計あわせしたもの
|
|
577
|
-
#
|
|
578
|
-
def to_f
|
|
579
|
-
JulianDate._t_to_d(universal_time)
|
|
580
|
-
end
|
|
581
|
-
|
|
582
|
-
# ユリウス日(整数)
|
|
583
|
-
#
|
|
584
|
-
# @return [Integer]
|
|
585
|
-
#
|
|
586
|
-
# -4712-01-01T12:00:00Z からの経過日数に対応する通番(当該時間帯での午前0時に1進める)
|
|
587
|
-
#
|
|
588
|
-
def to_i
|
|
589
|
-
sd = universal_time
|
|
590
|
-
sd -= @frame.universal_time if @frame.kind_of?(Clock)
|
|
591
|
-
div, mod = sd.divmod(Duration::DAY)
|
|
592
|
-
div + JulianDate::JD19700101
|
|
593
|
-
end
|
|
594
|
-
|
|
595
|
-
# 剰余類化
|
|
596
|
-
#
|
|
597
|
-
# @param [Numeric] remainder 剰余
|
|
598
|
-
# @param [Integer] divisor 法(>0)
|
|
599
|
-
#
|
|
600
|
-
# @return [When::Coordinates::Residue]
|
|
601
|
-
#
|
|
602
|
-
# 当日を基準とする剰余類
|
|
603
|
-
#
|
|
604
|
-
def to_residue(remainder, divisor)
|
|
605
|
-
When::Coordinates::Residue.new(remainder, divisor, {'day'=>to_i})
|
|
606
|
-
end
|
|
607
|
-
|
|
608
|
-
# ユリウス日時(実数)
|
|
609
|
-
#
|
|
610
|
-
# @return [Float]
|
|
611
|
-
#
|
|
612
|
-
# dynamical time での経過日数を, ユリウス日と1970-01-01T00:00:00TTで時計あわせしたもの
|
|
613
|
-
#
|
|
614
|
-
def +@
|
|
615
|
-
JulianDate._t_to_d(dynamical_time)
|
|
616
|
-
end
|
|
617
|
-
|
|
618
|
-
# When::TM::ClockTime オブジェクトへの変換
|
|
619
|
-
#
|
|
620
|
-
# @return [When::TM::ClokTime]
|
|
621
|
-
#
|
|
622
|
-
def to_clock_time
|
|
623
|
-
raise TypeError, "Clock not assigned" unless clock
|
|
624
|
-
clk_time = clock.to_clk_time(universal_time - (to_i - JulianDate::JD19700101)*Duration::DAY)
|
|
625
|
-
clk_time.clk_time[0] += to_i
|
|
626
|
-
return clk_time
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
# 標準ライブラリの DateTime オブジェクトへの変換
|
|
630
|
-
#
|
|
631
|
-
# @param [Hash] option 時間の歩度が1.0でない場合のための option
|
|
632
|
-
# see {When::TM::TemporalPosition._instance}
|
|
633
|
-
#
|
|
634
|
-
# @param [Integer] start ::DateTime オブジェクトのグレゴリオ改暦日(ユリウス通日)
|
|
635
|
-
#
|
|
636
|
-
# @return [::DateTime]
|
|
637
|
-
#
|
|
638
|
-
def to_date_time(option={:frame=>When::UTC}, start=_default_start)
|
|
639
|
-
return JulianDate.dynamical_time(dynamical_time, option).to_date_time unless time_standard.rate_of_clock == 1.0
|
|
640
|
-
raise TypeError, "Clock not assigned" unless clock
|
|
641
|
-
Rational
|
|
642
|
-
offset = Rational(-(clock.universal_time/Duration::SECOND).to_i, (Duration::DAY/Duration::SECOND).to_i)
|
|
643
|
-
clk_time = clock.to_clk_time(universal_time - (to_i - JulianDate::JD19700101)*Duration::DAY).clk_time
|
|
644
|
-
::DateTime.jd(to_i, clk_time[1], clk_time[2], clk_time[3].to_i, offset, start)
|
|
645
|
-
end
|
|
646
|
-
|
|
647
|
-
# 標準ライブラリの Date オブジェクトへの変換
|
|
648
|
-
#
|
|
649
|
-
# @param [Hash] option 時間の歩度が1.0でない場合のための option
|
|
650
|
-
# see {When::TM::TemporalPosition._instance}
|
|
651
|
-
#
|
|
652
|
-
# @param [Integer] start ::DateTime オブジェクトのグレゴリオ改暦日(ユリウス通日)
|
|
653
|
-
#
|
|
654
|
-
# @return [::Date]
|
|
655
|
-
#
|
|
656
|
-
def to_date(option={}, start=_default_start)
|
|
657
|
-
return JulianDate.dynamical_time(dynamical_time, option).to_date unless time_standard.rate_of_clock == 1.0
|
|
658
|
-
::Date.jd(to_i, start)
|
|
659
|
-
end
|
|
660
|
-
|
|
661
|
-
# 組み込みライブラリの Time オブジェクトへの変換
|
|
662
|
-
#
|
|
663
|
-
# @return [::Time]
|
|
664
|
-
#
|
|
665
|
-
def to_time
|
|
666
|
-
time_standard.to_time_object(universal_time)
|
|
667
|
-
end
|
|
668
|
-
|
|
669
|
-
# 要素の参照
|
|
670
|
-
#
|
|
671
|
-
# @param [Integer, String] index 参照する要素の指定
|
|
672
|
-
#
|
|
673
|
-
# @return [Numeric]
|
|
674
|
-
#
|
|
675
|
-
def [](index)
|
|
676
|
-
return value(index) if index.kind_of?(String) || !index.respond_to?(:inject)
|
|
677
|
-
index.inject([]) {|list, i| list << value(i) }
|
|
678
|
-
end
|
|
679
|
-
|
|
680
|
-
# 加算
|
|
681
|
-
#
|
|
682
|
-
# @param [Numeric, When::TM::Duration] other
|
|
683
|
-
#
|
|
684
|
-
# @return [When::TM::TemporalPosition]
|
|
685
|
-
#
|
|
686
|
-
def +(other)
|
|
687
|
-
case other
|
|
688
|
-
when Integer ; self + PeriodDuration.new(other, When::DAY)
|
|
689
|
-
when Numeric ; self + IntervalLength.new(other, 'day')
|
|
690
|
-
when PeriodDuration ; _plus(other)
|
|
691
|
-
when Duration ; @frame.kind_of?(Calendar) ? @frame.jul_trans(JulianDate.dynamical_time(dynamical_time + other.duration), self._attr) :
|
|
692
|
-
JulianDate.dynamical_time(dynamical_time + other.duration, self._attr)
|
|
693
|
-
else ; raise TypeError, "The right operand should be Numeric or Duration"
|
|
694
|
-
end
|
|
695
|
-
rescue RangeError
|
|
696
|
-
(@frame ^ self) + other
|
|
697
|
-
end
|
|
698
|
-
|
|
699
|
-
# 減算
|
|
700
|
-
#
|
|
701
|
-
# @param [Numeric, When::TM::Duration, When::TM::TemporalPosition] other
|
|
702
|
-
#
|
|
703
|
-
# @return [When::TM::TemporalPosition] if other is a Numeric or When::TM::Duration
|
|
704
|
-
# @return [When::TM::Duration] if other is a When::TM::TemporalPosition
|
|
705
|
-
#
|
|
706
|
-
def -(other)
|
|
707
|
-
case other
|
|
708
|
-
when TimeValue ; self.time_standard.rate_of_clock == other.time_standard.rate_of_clock && [@precision, other.precision].min <= When::DAY ?
|
|
709
|
-
PeriodDuration.new(self.to_i - other.to_i, When::DAY) :
|
|
710
|
-
IntervalLength.new((self.dynamical_time - other.dynamical_time) / Duration::SECOND, 'second')
|
|
711
|
-
when Integer ; self - PeriodDuration.new(other, When::DAY)
|
|
712
|
-
when Numeric ; self - IntervalLength.new(other, 'day')
|
|
713
|
-
when PeriodDuration ; _plus(-other)
|
|
714
|
-
when Duration ; @frame.kind_of?(Calendar) ? @frame.jul_trans(JulianDate.dynamical_time(dynamical_time - other.duration), self._attr) :
|
|
715
|
-
JulianDate.dynamical_time(dynamical_time - other.duration, self._attr)
|
|
716
|
-
else ; raise TypeError, "The right operand should be Numeric, Duration or TemporalPosition"
|
|
717
|
-
end
|
|
718
|
-
rescue RangeError
|
|
719
|
-
(@frame ^ self) - other
|
|
720
|
-
end
|
|
721
|
-
|
|
722
|
-
# 分解能に対応する Duration
|
|
723
|
-
#
|
|
724
|
-
# @return [When::TM::PeriodDuration]
|
|
725
|
-
#
|
|
726
|
-
def period
|
|
727
|
-
return @period if @period
|
|
728
|
-
period_name = When::Coordinates::PERIOD_NAME[@precision]
|
|
729
|
-
raise ArgumentError, "Presicion not defined" unless period_name
|
|
730
|
-
@period = When.Duration(period_name)
|
|
731
|
-
end
|
|
732
|
-
|
|
733
|
-
# 前の日時
|
|
734
|
-
#
|
|
735
|
-
# @return [When::TM::TemporalPosition]
|
|
736
|
-
#
|
|
737
|
-
# 分解能に対応する Duration だけ,日時を戻す
|
|
738
|
-
#
|
|
739
|
-
def prev
|
|
740
|
-
@precision==When::DAY ? _force_euqal_day(-1) : self-period
|
|
741
|
-
rescue RangeError
|
|
742
|
-
(When::Gregorian ^ self) - period
|
|
743
|
-
end
|
|
744
|
-
|
|
745
|
-
# 次の日時
|
|
746
|
-
#
|
|
747
|
-
# @return [When::TM::TemporalPosition]
|
|
748
|
-
#
|
|
749
|
-
# 分解能に対応する Duration だけ,日時を進める
|
|
750
|
-
#
|
|
751
|
-
def succ
|
|
752
|
-
@precision==When::DAY ? _force_euqal_day(+1) : self+period
|
|
753
|
-
rescue RangeError
|
|
754
|
-
(When::Gregorian ^ self) + period
|
|
755
|
-
end
|
|
756
|
-
alias :next :succ
|
|
757
|
-
|
|
758
|
-
#
|
|
759
|
-
# 前後の日時を取得可能か?
|
|
760
|
-
#
|
|
761
|
-
# @return [Boolean]
|
|
762
|
-
# [ true - 可能 ]
|
|
763
|
-
# [ false - 不可 ]
|
|
764
|
-
#
|
|
765
|
-
def has_next?
|
|
766
|
-
When::Coordinates::PERIOD_NAME[@precision] != nil
|
|
767
|
-
end
|
|
768
|
-
|
|
769
|
-
# 下位桁の切り捨て
|
|
770
|
-
#
|
|
771
|
-
# @param [Integer] digit これより下の桁を切り捨てる(省略すると When::DAY)
|
|
772
|
-
#
|
|
773
|
-
# @param [Integer] precision 切り捨て結果の分解能
|
|
774
|
-
#
|
|
775
|
-
# @return [When::TM::TemporalPosition] (本 Class では、実際には切り捨てない)
|
|
776
|
-
#
|
|
777
|
-
def floor(digit=DAY, precision=digit)
|
|
778
|
-
self
|
|
779
|
-
end
|
|
780
|
-
|
|
781
|
-
# 分解能が時刻を持つか
|
|
782
|
-
#
|
|
783
|
-
# @return [Boolean]
|
|
784
|
-
#
|
|
785
|
-
def has_time?
|
|
786
|
-
(@precision > 0)
|
|
787
|
-
end
|
|
788
|
-
|
|
789
|
-
# 指定の日時を含むか?
|
|
790
|
-
#
|
|
791
|
-
# @param [When::TM::TemporalPosition] date チェックされる日時
|
|
792
|
-
#
|
|
793
|
-
# @return [Boolean]
|
|
794
|
-
# [ true - 含む ]
|
|
795
|
-
# [ false - 含まない ]
|
|
796
|
-
#
|
|
797
|
-
def include?(date)
|
|
798
|
-
return false if self.precision > date.precision
|
|
799
|
-
return self == date
|
|
800
|
-
end
|
|
801
|
-
|
|
802
|
-
# オブジェクトの同値
|
|
803
|
-
#
|
|
804
|
-
# @param [比較先] other
|
|
805
|
-
#
|
|
806
|
-
# @return [Boolean]
|
|
807
|
-
# [ true - 同値 ]
|
|
808
|
-
# [ false - 非同値 ]
|
|
809
|
-
#
|
|
810
|
-
def ==(other)
|
|
811
|
-
(self <=> other) == 0
|
|
812
|
-
rescue
|
|
813
|
-
false
|
|
814
|
-
end
|
|
815
|
-
|
|
816
|
-
# 大小比較
|
|
817
|
-
#
|
|
818
|
-
# @param [When::TM::TemporalPosition] other チェックされる日時
|
|
819
|
-
# @param [Numeric] other チェックされる日時の universal time(self と同じtime_standardとみなす)
|
|
820
|
-
#
|
|
821
|
-
# @return [Integer] (-1, 0, 1)
|
|
822
|
-
#
|
|
823
|
-
# 分解能の低い方にあわせて比較を行う
|
|
824
|
-
#
|
|
825
|
-
# Ex. when?('2011-03') <=> when?('2011-03-10') -> 0
|
|
826
|
-
#
|
|
827
|
-
def <=>(other)
|
|
828
|
-
other = other.first if other.kind_of?(Range)
|
|
829
|
-
return universal_time <=> other if other.kind_of?(Numeric)
|
|
830
|
-
|
|
831
|
-
[self.indeterminated_position, other.indeterminated_position].each do |position|
|
|
832
|
-
prec = SYSTEM if [TimeValue::Min, TimeValue::Max].include?(position)
|
|
833
|
-
end
|
|
834
|
-
prec = [self.precision, other.precision].min unless prec
|
|
835
|
-
|
|
836
|
-
case prec
|
|
837
|
-
when DAY ; return self.to_i <=> other.to_i
|
|
838
|
-
when SYSTEM ; return TemporalPosition._verify(self, other)
|
|
839
|
-
end
|
|
840
|
-
|
|
841
|
-
if prec < DAY && respond_to?(:most_significant_coordinate) &&
|
|
842
|
-
other.respond_to?(:most_significant_coordinate) && @frame.equal?(other.frame)
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
end
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
#
|
|
865
|
-
#
|
|
866
|
-
# @
|
|
867
|
-
# @
|
|
868
|
-
# @
|
|
869
|
-
#
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
end
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
#
|
|
924
|
-
#
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
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
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
end
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
#
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
#
|
|
1059
|
-
#
|
|
1060
|
-
#
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
#
|
|
1066
|
-
#
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
#
|
|
1072
|
-
#
|
|
1073
|
-
# @
|
|
1074
|
-
#
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
when
|
|
1086
|
-
options[:frame] ||= When.
|
|
1087
|
-
universal_time
|
|
1088
|
-
when
|
|
1089
|
-
options[:frame] ||= time.clock
|
|
1090
|
-
universal_time
|
|
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
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
#
|
|
1126
|
-
#
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
#
|
|
1134
|
-
#
|
|
1135
|
-
# @return [
|
|
1136
|
-
#
|
|
1137
|
-
def
|
|
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
|
-
|
|
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
|
-
# @return [
|
|
1302
|
-
#
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
#
|
|
1309
|
-
#
|
|
1310
|
-
#
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
#
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
#
|
|
1334
|
-
#
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
#
|
|
1342
|
-
#
|
|
1343
|
-
# @return [Numeric]
|
|
1344
|
-
#
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
#
|
|
1365
|
-
#
|
|
1366
|
-
#
|
|
1367
|
-
#
|
|
1368
|
-
# @
|
|
1369
|
-
#
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
if (
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
#
|
|
1454
|
-
#
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
#
|
|
1461
|
-
#
|
|
1462
|
-
#
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
#
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
#
|
|
1475
|
-
#
|
|
1476
|
-
#
|
|
1477
|
-
#
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
#
|
|
1487
|
-
#
|
|
1488
|
-
#
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
#
|
|
1502
|
-
#
|
|
1503
|
-
#
|
|
1504
|
-
#
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
#
|
|
1514
|
-
#
|
|
1515
|
-
#
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
@frame.
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
#
|
|
1538
|
-
#
|
|
1539
|
-
#
|
|
1540
|
-
# @return [
|
|
1541
|
-
#
|
|
1542
|
-
def
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
#
|
|
1548
|
-
#
|
|
1549
|
-
#
|
|
1550
|
-
#
|
|
1551
|
-
#
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
#
|
|
1575
|
-
#
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
#
|
|
1610
|
-
#
|
|
1611
|
-
# @param [
|
|
1612
|
-
#
|
|
1613
|
-
# @return [
|
|
1614
|
-
#
|
|
1615
|
-
def
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
#
|
|
1633
|
-
#
|
|
1634
|
-
# @return [When::TM::CalDate]
|
|
1635
|
-
#
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
#
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
#
|
|
1659
|
-
# @
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
#
|
|
1668
|
-
#
|
|
1669
|
-
# @
|
|
1670
|
-
#
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
#
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
#
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
end
|
|
1775
|
-
|
|
1776
|
-
#
|
|
1777
|
-
def
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
#
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
#
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
#
|
|
1841
|
-
#
|
|
1842
|
-
# @return [When::TM::
|
|
1843
|
-
#
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
#
|
|
1870
|
-
#
|
|
1871
|
-
# @param [Integer]
|
|
1872
|
-
#
|
|
1873
|
-
# @return [
|
|
1874
|
-
#
|
|
1875
|
-
def
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
#
|
|
1911
|
-
#
|
|
1912
|
-
#
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
#
|
|
1941
|
-
#
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
#
|
|
1964
|
-
#
|
|
1965
|
-
# @
|
|
1966
|
-
#
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
#
|
|
1979
|
-
def
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
=begin
|
|
3
|
+
Copyright (C) 2011-2014 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.4) Temporal Position Package
|
|
11
|
+
#
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
# 列挙データ型である When::TM::IndeterminateValue は,不確定な位置のために
|
|
15
|
+
# 6つの値を規定する.このうち Min と Max は 本ライブラリでの拡張である.
|
|
16
|
+
#
|
|
17
|
+
# These values are interpreted as follows:
|
|
18
|
+
#- “Unknown” 時間位置を示す値が与えられていないことを示す(本ライブラリでは“Unknown”は使用しない)
|
|
19
|
+
#- “Now” 常に現時点の時間位置を示す(オブジェクト生成時の時間位置でないことに注意)
|
|
20
|
+
#- “Before” 実際の時間位置は未知だが、指定した値よりも前であることを示す(本ライブラリでは“Before”は無視される)
|
|
21
|
+
#- “After” 実際の時間位置は未知だが、指定した値よりも後であることを示す(本ライブラリでは“After”は無視される)
|
|
22
|
+
#- “Min” 無限の過去を示す
|
|
23
|
+
#- “Max” 無限の未来を示す
|
|
24
|
+
#
|
|
25
|
+
# see {gml schema}[link:http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimeIndeterminateValueType]
|
|
26
|
+
#
|
|
27
|
+
module IndeterminateValue
|
|
28
|
+
|
|
29
|
+
After = :After
|
|
30
|
+
Before = :Before
|
|
31
|
+
Now = :Now
|
|
32
|
+
Unknown = :Unknown
|
|
33
|
+
# additional value for this library
|
|
34
|
+
Min = :Min
|
|
35
|
+
# additional value for this library
|
|
36
|
+
Max = :Max
|
|
37
|
+
|
|
38
|
+
S = {'After'=>After, 'Before'=>Before, 'Now'=>Now, 'Unknown'=>Unknown, '-Infinity'=>Min, '+Infinity'=>Max}
|
|
39
|
+
I = S.invert
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# 時間位置共用体
|
|
43
|
+
# union of
|
|
44
|
+
# When::TM::TemporalPosition
|
|
45
|
+
# When::BasicTypes::Date
|
|
46
|
+
# When::BasicTypes::Time
|
|
47
|
+
# When::BasicTypes::DateTime
|
|
48
|
+
#
|
|
49
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporal.xsd#TimePositionType gml schema}
|
|
50
|
+
#
|
|
51
|
+
class Position
|
|
52
|
+
|
|
53
|
+
include IndeterminateValue
|
|
54
|
+
include When::Parts::Resource
|
|
55
|
+
|
|
56
|
+
# @private
|
|
57
|
+
HashProperty =
|
|
58
|
+
[:indeterminated_position, :frame,
|
|
59
|
+
[:precision, When::SYSTEM], :events, :options, :trans, :query,
|
|
60
|
+
:location, [:time_standard, When::TimeStandard::UniversalTime], [:rate_of_clock, 1.0]]
|
|
61
|
+
|
|
62
|
+
# 代表文字列
|
|
63
|
+
#
|
|
64
|
+
# @return [When::BasicTypes::DateTime]
|
|
65
|
+
#
|
|
66
|
+
attr_reader :date_time8601
|
|
67
|
+
alias :dateTime8601 :date_time8601
|
|
68
|
+
|
|
69
|
+
# 時間位置
|
|
70
|
+
#
|
|
71
|
+
# @return [When::TM::TemporalPosition]
|
|
72
|
+
#
|
|
73
|
+
attr_reader :any_other
|
|
74
|
+
alias :anyOther :any_other
|
|
75
|
+
|
|
76
|
+
# 諸々のオブジェクトから When::TM::TemporalPosition を取り出す
|
|
77
|
+
#
|
|
78
|
+
# @param [Object] position 変換元の時間位置
|
|
79
|
+
# @param [Hash] options
|
|
80
|
+
# see {When::TM::TemporalPosition._instance}
|
|
81
|
+
#
|
|
82
|
+
# @return [When::TM::TemporalPosition] position の型により下記を返す
|
|
83
|
+
# - {When::BasicTypes::Date}, {When::BasicTypes::Time}, {When::BasicTypes::DateTime} - When::TM::Calendar#jul_trans による変換結果
|
|
84
|
+
# - {When::TM::TemporalPosition} - そのまま position ( optionは無視 )
|
|
85
|
+
# - {When::TM::Position} - position.any_other ( optionは無視 )
|
|
86
|
+
# - {When::Parts::GeometricComplex} - position.first ( optionは無視 )
|
|
87
|
+
#
|
|
88
|
+
def self.any_other(position, options={})
|
|
89
|
+
case position
|
|
90
|
+
when TemporalPosition ; position
|
|
91
|
+
when Position ; position.any_other
|
|
92
|
+
when When::Parts::GeometricComplex ; position.first
|
|
93
|
+
else ; When.Calendar(options[:frame] || 'Gregorian').jul_trans(position, options) || position
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# オブジェクトの生成
|
|
98
|
+
#
|
|
99
|
+
# @param [String] specification When.exe Standard Representation として解釈して生成する
|
|
100
|
+
# @param [Hash] options 暦法や時法などの指定
|
|
101
|
+
# see {When::TM::TemporalPosition._instance}
|
|
102
|
+
#
|
|
103
|
+
# @note
|
|
104
|
+
# specification が String 以外の場合、そのオブジェクトの代表的な日時
|
|
105
|
+
# (When::TM::CalendarEra#reference_dateなど)により解釈する
|
|
106
|
+
#
|
|
107
|
+
def initialize(specification, options={})
|
|
108
|
+
|
|
109
|
+
case specification
|
|
110
|
+
when String
|
|
111
|
+
@date_time8601 = specification
|
|
112
|
+
@any_other = TemporalPosition._instance(specification, options)
|
|
113
|
+
when Position
|
|
114
|
+
@date_time8601 = specification.date_time8601
|
|
115
|
+
@any_other = specification.any_other
|
|
116
|
+
return
|
|
117
|
+
else
|
|
118
|
+
@any_other = specification
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
klass = specification.class
|
|
122
|
+
message = "Irregal specification type: #{klass}"
|
|
123
|
+
|
|
124
|
+
case specification
|
|
125
|
+
when CalDate ; @date_time8601 = When::BasicTypes::Date.new(specification.to_s)
|
|
126
|
+
when ClockTime ; @date_time8601 = When::BasicTypes::Time.new(specification.to_s)
|
|
127
|
+
when TemporalPosition ; @date_time8601 = When::BasicTypes::DateTime.new(specification.to_s)
|
|
128
|
+
when CalendarEra ; @date_time8601 = When::BasicTypes::Date.new(specification.reference_date.to_s)
|
|
129
|
+
when OrdinalEra ; @date_time8601 = When::BasicTypes::Date.new(specification.begin.to_s)
|
|
130
|
+
when When::BasicTypes::Date ; raise TypeError, message unless klass == CalDate
|
|
131
|
+
when When::BasicTypes::Time ; raise TypeError, message unless klass == ClockTime
|
|
132
|
+
when String ;
|
|
133
|
+
else ; raise TypeError, message
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
private
|
|
138
|
+
|
|
139
|
+
alias :_method_missing :method_missing
|
|
140
|
+
|
|
141
|
+
# その他のメソッド
|
|
142
|
+
#
|
|
143
|
+
# @note
|
|
144
|
+
# When::TM::Position で定義されていないメソッドは
|
|
145
|
+
# 処理を @date_time8601 (type: When::BasicTypes::DateTime)
|
|
146
|
+
# または @any_other (type: When::TM::TemporalPosition) に委譲する
|
|
147
|
+
# (両方ともに有効なメソッドは@any_otherを優先する)
|
|
148
|
+
#
|
|
149
|
+
def method_missing(name, *args, &block)
|
|
150
|
+
return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
|
|
151
|
+
self.class.module_eval %Q{
|
|
152
|
+
def #{name}(*args, &block)
|
|
153
|
+
union = @any_other.respond_to?("#{name}") ? @any_other : @date_time8601
|
|
154
|
+
union.send("#{name}", *args, &block)
|
|
155
|
+
end
|
|
156
|
+
} unless When::Parts::MethodCash.escape(name)
|
|
157
|
+
union = @any_other.respond_to?(name) ? @any_other : @date_time8601
|
|
158
|
+
union.send(name, *args, &block)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# 「時間位置」の基底クラス
|
|
163
|
+
#
|
|
164
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#TemporalPositionType gml schema}
|
|
165
|
+
#
|
|
166
|
+
class TemporalPosition < ::Object
|
|
167
|
+
|
|
168
|
+
#
|
|
169
|
+
# When::TM::JulianDate, When::TM::CalDate or DateAndTime への変換メソッドを提供
|
|
170
|
+
#
|
|
171
|
+
module Conversion
|
|
172
|
+
#
|
|
173
|
+
# 対応する When::TM::JulianDate を生成
|
|
174
|
+
#
|
|
175
|
+
# @param [Hash] options 以下の通り
|
|
176
|
+
# @option options [When::TM::Clock] :clock
|
|
177
|
+
# @option options [When::Parts::Timezone] :tz
|
|
178
|
+
#
|
|
179
|
+
# @return [When::TM::JulianDate]
|
|
180
|
+
#
|
|
181
|
+
def julian_date(options={})
|
|
182
|
+
When::TM::JulianDate.new(self, options)
|
|
183
|
+
end
|
|
184
|
+
alias :to_julian_date :julian_date
|
|
185
|
+
|
|
186
|
+
#
|
|
187
|
+
# 対応する When::TM::CalDate or DateAndTime を生成
|
|
188
|
+
#
|
|
189
|
+
# @param [Hash] options 暦法や時法などの指定
|
|
190
|
+
# see {When::TM::TemporalPosition._instance}
|
|
191
|
+
#
|
|
192
|
+
# @return [When::TM::CalDate, When::TM::DateAndTime]
|
|
193
|
+
#
|
|
194
|
+
def tm_pos(options={})
|
|
195
|
+
When.Calendar(options[:frame] || 'Gregorian').jul_trans(self, options)
|
|
196
|
+
end
|
|
197
|
+
alias :to_tm_pos :tm_pos
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
include When
|
|
201
|
+
include Comparable
|
|
202
|
+
include IndeterminateValue
|
|
203
|
+
include Coordinates
|
|
204
|
+
include Parts::Resource
|
|
205
|
+
include Conversion
|
|
206
|
+
|
|
207
|
+
# @private
|
|
208
|
+
HashProperty = Position::HashProperty
|
|
209
|
+
|
|
210
|
+
# この時間位置の意味づけ
|
|
211
|
+
#
|
|
212
|
+
# @return [When::TM::IndeterminateValue]
|
|
213
|
+
#
|
|
214
|
+
attr_reader :indeterminated_position
|
|
215
|
+
alias :indeterminatedPosition :indeterminated_position
|
|
216
|
+
|
|
217
|
+
# この時間位置と関連付けられた時間参照系 (relation - Reference)
|
|
218
|
+
#
|
|
219
|
+
# The time reference system associated with the temporal position being described
|
|
220
|
+
#
|
|
221
|
+
# @return [When::TM::ReferenceSystem]
|
|
222
|
+
#
|
|
223
|
+
attr_accessor :frame
|
|
224
|
+
|
|
225
|
+
# この時間位置と関連付けられたイベント - additional attribute
|
|
226
|
+
#
|
|
227
|
+
# @return [Array<When::Parts::Enumerator>]
|
|
228
|
+
#
|
|
229
|
+
attr_accessor :events
|
|
230
|
+
#protected :events=
|
|
231
|
+
|
|
232
|
+
# この時間位置の分解能 - additional attribute
|
|
233
|
+
#
|
|
234
|
+
# @return [Numeric]
|
|
235
|
+
#
|
|
236
|
+
# @note precision より resolution の方が分解能の意味にふさわしいが ISO19108 で別の意味に用いられているため resolution とした。
|
|
237
|
+
#
|
|
238
|
+
attr_accessor :precision
|
|
239
|
+
|
|
240
|
+
# その他の属性 - additional attribute
|
|
241
|
+
#
|
|
242
|
+
# @return [Hash] { String=>Object }
|
|
243
|
+
#
|
|
244
|
+
attr_reader :options
|
|
245
|
+
|
|
246
|
+
# その他の属性 - additional attribute
|
|
247
|
+
#
|
|
248
|
+
# @return [Hash] { String=>Object }
|
|
249
|
+
#
|
|
250
|
+
attr_accessor :trans
|
|
251
|
+
|
|
252
|
+
# その他の属性 - additional attribute
|
|
253
|
+
#
|
|
254
|
+
# @return [Hash] { String=>When::BasicTypes::M17n }
|
|
255
|
+
#
|
|
256
|
+
attr_accessor :query
|
|
257
|
+
|
|
258
|
+
# その他の属性 - additional attribute
|
|
259
|
+
#
|
|
260
|
+
# @return [When::Coordinates::Spatial]
|
|
261
|
+
#
|
|
262
|
+
attr_accessor :location
|
|
263
|
+
|
|
264
|
+
class << self
|
|
265
|
+
|
|
266
|
+
include When
|
|
267
|
+
include Coordinates
|
|
268
|
+
|
|
269
|
+
# Temporal Objetct の生成
|
|
270
|
+
#
|
|
271
|
+
# @param [String] specification When.exe Standard Representation
|
|
272
|
+
# @param [Hash] options 下記の通り
|
|
273
|
+
# @option options [When::TM::ReferenceSystem] :frame 暦法の指定
|
|
274
|
+
# @option options [When::Parts::Timezone::Base, String] :clock 時法の指定
|
|
275
|
+
# @option options [String] :tz 時法の指定(時間帯を指定する場合 :clock の替わりに用いることができる)
|
|
276
|
+
# @option options [Array<Numeric>] :abbr ISO8601上位省略形式のためのデフォルト日付(省略時 指定なし)
|
|
277
|
+
# @option options [Integer] :extra_year_digits ISO8601拡大表記のための年の構成要素拡大桁数(省略時 1桁)
|
|
278
|
+
# @option options [Integer] :ordinal_date_digits ISO8601拡大表記の年内通日の桁数(省略時 3桁)
|
|
279
|
+
# @option options [String] :wkst ISO8601週日形式のための暦週開始曜日(省略時 'MO')
|
|
280
|
+
# @option options [Integer] :precision 生成するオブジェクトの分解能
|
|
281
|
+
# @option options [When::TimeStandard::TimeStandard] :time_standard 時刻系の指定(省略時 When::TimeStandard::UnversalTime)
|
|
282
|
+
# @option options [When::Ephemeris::Spatial] :location 観測地の指定(省略時 指定なし)
|
|
283
|
+
# @option options [String] :era_name 暦年代
|
|
284
|
+
# @option options [Hash] :trans 暦年代の上下限
|
|
285
|
+
# - :count => 条件に合致する暦年代のうち何番目を採用するか
|
|
286
|
+
# - :lower => 暦年代適用の下限
|
|
287
|
+
# true - epoch_of_use の始め(省略時)
|
|
288
|
+
# :reference_date - 参照事象の日付
|
|
289
|
+
# - :upper => 暦年代適用の上限
|
|
290
|
+
# true - epoch_of_use の終わり(省略時)
|
|
291
|
+
# :reference_date - 参照事象の日付
|
|
292
|
+
# @option options [Hash] :query 暦年代の絞込み条件
|
|
293
|
+
# - :area => area による暦年代絞込み
|
|
294
|
+
# - :period => period による暦年代絞込み
|
|
295
|
+
# - :name => name による暦年代絞込み(epoch の attribute使用可)
|
|
296
|
+
#
|
|
297
|
+
# @note options の中身は本メソッドによって更新されることがある。
|
|
298
|
+
#
|
|
299
|
+
# @note :tz は 'Asia/Tokyo'など時間帯を表す文字列をキーにして、登録済みのWhen::V::Timezone, When::Parts::Timezoneを検索して使用する。
|
|
300
|
+
# :clock はWhen::Parts::Timezone::Baseオブジェクトをそのまま使用するか '+09:00'などの文字列をWhen::TM::Clock化して使用する。
|
|
301
|
+
# :tz の方が :clock よりも優先される。
|
|
302
|
+
#
|
|
303
|
+
# @return [When::TM::TemporalPosition] ISO8601 time point
|
|
304
|
+
# @return [When::TM::Duration] ISO8601 duration
|
|
305
|
+
# @return [When::Parts::GeometricComplex] ISO8601 repeating interval
|
|
306
|
+
#
|
|
307
|
+
def _instance(specification, options={})
|
|
308
|
+
|
|
309
|
+
# Suffix - Frame specification
|
|
310
|
+
rfc5545form, frame, *rest = specification.split(/\^{1,2}/)
|
|
311
|
+
return rest.inject(_instance(rfc5545form + '^' + frame, options)) {|p,c| When.Resource(c, '_c:').jul_trans(p)} if rest.size > 0
|
|
312
|
+
|
|
313
|
+
options[:frame] = When.Resource(frame, '_c:') if (frame)
|
|
314
|
+
|
|
315
|
+
# Prefix - RFC 5545 Options
|
|
316
|
+
if (rfc5545form =~ /\A([^:]+[^-:\d]{2}):([^:].+)\z/)
|
|
317
|
+
rfc5545option, iso8601form = $~[1..2]
|
|
318
|
+
rfc5545option.split(/;/).each do |eq|
|
|
319
|
+
key, value = eq.split(/=/, 2)
|
|
320
|
+
case key
|
|
321
|
+
when 'VALUE' ; options[:precision] = value
|
|
322
|
+
when 'TZID' ; options[:clock] =
|
|
323
|
+
case When::V::Timezone[value]
|
|
324
|
+
when Array ; When::V::Timezone[value][-1]
|
|
325
|
+
when nil ; When::Parts::Timezone.new(value)
|
|
326
|
+
else ; When::V::Timezone[value]
|
|
327
|
+
end
|
|
328
|
+
else ; options[key] = value
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
else
|
|
332
|
+
iso8601form = rfc5545form
|
|
333
|
+
end
|
|
334
|
+
options = options.dup
|
|
335
|
+
|
|
336
|
+
# IndeterminateValue
|
|
337
|
+
if (iso8601form.sub!(/\/After$|^Before\/|^Now$|^Unknown$|^[-+]Infinity\z/i, ''))
|
|
338
|
+
options[:indeterminated_position] = When::TimeValue::S[$&.sub(/\//,'')]
|
|
339
|
+
case options[:indeterminated_position]
|
|
340
|
+
when When::TimeValue::Now,
|
|
341
|
+
When::TimeValue::Unknown,
|
|
342
|
+
When::TimeValue::Max,
|
|
343
|
+
When::TimeValue::Min
|
|
344
|
+
return self.new(self._options(options))
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# each specification
|
|
349
|
+
splitted = iso8601form.split(/\//)
|
|
350
|
+
if (splitted[0] =~ /\AR(\d+)?\z/)
|
|
351
|
+
repeat = $1 ? $1.to_i : true
|
|
352
|
+
splitted.shift
|
|
353
|
+
end
|
|
354
|
+
case splitted.length
|
|
355
|
+
when 1
|
|
356
|
+
when 2
|
|
357
|
+
if (splitted[0] !~ /\A[-+]?P/ && splitted[1] =~ /\A\d/ && splitted[1].length < splitted[0].length)
|
|
358
|
+
splitted[1] = splitted[0][0..(splitted[0].length-splitted[1].length-1)] + splitted[1]
|
|
359
|
+
end
|
|
360
|
+
else
|
|
361
|
+
raise ArgumentError, "Irregal ISO8601 Format: #{iso8601form}"
|
|
362
|
+
end
|
|
363
|
+
options = self._options(options)
|
|
364
|
+
element = splitted.map { |v| _date_time_or_duration(v, options.dup) }
|
|
365
|
+
|
|
366
|
+
# total result
|
|
367
|
+
case repeat
|
|
368
|
+
when nil
|
|
369
|
+
case element[1]
|
|
370
|
+
when nil
|
|
371
|
+
return element[0]
|
|
372
|
+
when Duration
|
|
373
|
+
case element[0]
|
|
374
|
+
when Duration ; raise TypeError, "Duplicate Duration: #{element[0]} and #{element[1]}"
|
|
375
|
+
when self ; return When::Parts::GeometricComplex.new(*element)
|
|
376
|
+
else ; return When::Parts::GeometricComplex.new(element[0].first, element[1])
|
|
377
|
+
end
|
|
378
|
+
when self
|
|
379
|
+
case element[0]
|
|
380
|
+
when Duration ; return When::Parts::GeometricComplex.new([[element[1]-element[0],false], [element[1],true ]])
|
|
381
|
+
when self ; return When::Parts::GeometricComplex.new(element[0]..element[1])
|
|
382
|
+
else ; return When::Parts::GeometricComplex.new(element[0].first..element[1])
|
|
383
|
+
end
|
|
384
|
+
else
|
|
385
|
+
case element[0]
|
|
386
|
+
when Duration ; return When::Parts::GeometricComplex.new([[element[1].first-element[0],false],
|
|
387
|
+
[element[1].last-element[0]-1,true ]])
|
|
388
|
+
when self ; return When::Parts::GeometricComplex.new(element[0]...element[1].last)
|
|
389
|
+
else ; return When::Parts::GeometricComplex.new(element[0].first...element[1].last)
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
when 0 ; return []
|
|
393
|
+
when Integer ; return [element[0]] * repeat unless element[1]
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
case element[1]
|
|
397
|
+
when Duration
|
|
398
|
+
case element[0]
|
|
399
|
+
when Duration ; raise TypeError, "Duplicate Duration: #{element[0]} and #{element[1]}"
|
|
400
|
+
else ; duration = element[1]
|
|
401
|
+
end
|
|
402
|
+
when self
|
|
403
|
+
case element[0]
|
|
404
|
+
when Duration ; duration = -element[0]
|
|
405
|
+
when self ; duration = element[1] - element[0]
|
|
406
|
+
else ; duration = element[1] - element[0].first
|
|
407
|
+
end
|
|
408
|
+
else
|
|
409
|
+
case element[0]
|
|
410
|
+
when Duration ; duration = -element[0]
|
|
411
|
+
when self ; duration = element[1].first - element[0]
|
|
412
|
+
else ; duration = element[1].first - element[0].first
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
base = element[0].kind_of?(Duration) ? element[1] : element[0]
|
|
416
|
+
|
|
417
|
+
if repeat.kind_of?(Integer)
|
|
418
|
+
result = case base
|
|
419
|
+
when self ; (1..repeat-1).inject([base]) {|a,i| a << (a[-1] + duration) }
|
|
420
|
+
else ; (1..repeat-1).inject([base]) {|a,i| a << When::Parts::GeometricComplex.new(
|
|
421
|
+
a[-1].first+duration...a[-1].last+duration)}
|
|
422
|
+
end
|
|
423
|
+
result.reverse! if duration.sign < 0
|
|
424
|
+
return result
|
|
425
|
+
|
|
426
|
+
else
|
|
427
|
+
duration = -duration if duration.sign < 0
|
|
428
|
+
return case base
|
|
429
|
+
when self ; When::V::Event.new({'rrule'=>{'FREQ'=>duration}, 'dtstart'=>base})
|
|
430
|
+
else ; When::V::Event.new({'rrule'=>{'FREQ'=>duration}, 'dtstart'=>base.first,
|
|
431
|
+
'dtend' =>base.last})
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# option の正規化
|
|
437
|
+
# @private
|
|
438
|
+
def _options(options)
|
|
439
|
+
query = options.dup
|
|
440
|
+
main = {}
|
|
441
|
+
clock = Clock.get_clock_option(query)
|
|
442
|
+
main[:clock] = clock if clock
|
|
443
|
+
[:indeterminated_position, :frame, :events, :precision,
|
|
444
|
+
:era_name, :era, :abbr, :extra_year_digits, :ordinal_date_digits, :wkst, :time_standard, :location].each do |key|
|
|
445
|
+
main[key] = query.delete(key) if (query.key?(key))
|
|
446
|
+
end
|
|
447
|
+
long = query.delete(:long)
|
|
448
|
+
lat = query.delete(:lat)
|
|
449
|
+
alt = query.delete(:alt)
|
|
450
|
+
main[:location] ||= "_l:long=#{long||0}&lat=#{lat||0}&alt=#{alt||0}" if long && lat
|
|
451
|
+
trans = query.delete(:trans) || {}
|
|
452
|
+
[:lower, :upper, :count].each do |key|
|
|
453
|
+
trans[key] = query.delete(key) if (query.key?(key))
|
|
454
|
+
end
|
|
455
|
+
query = query.merge(query.delete(:query)) if (query.key?(:query))
|
|
456
|
+
main[:query] = query if (query.size > 0)
|
|
457
|
+
main[:trans] = trans if (trans.size > 0)
|
|
458
|
+
return main
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
# 比較
|
|
462
|
+
# @private
|
|
463
|
+
def _verify(source, target)
|
|
464
|
+
return source.universal_time <=> target.universal_time if source.time_standard.equal?(target.time_standard)
|
|
465
|
+
return source.dynamical_time <=> target.dynamical_time
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
private
|
|
469
|
+
|
|
470
|
+
# date_time_or_duration
|
|
471
|
+
def _date_time_or_duration(specification, options)
|
|
472
|
+
# IntervalLength
|
|
473
|
+
args = IntervalLength._to_array(specification)
|
|
474
|
+
return IntervalLength.new(*args) if args
|
|
475
|
+
|
|
476
|
+
# PeriodDuration
|
|
477
|
+
sign, *args = PeriodDuration._to_array(specification)
|
|
478
|
+
if (sign)
|
|
479
|
+
args << options
|
|
480
|
+
duration = PeriodDuration.new(*args)
|
|
481
|
+
return (sign >= 0) ? duration : -duration
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
# TemporalPosition
|
|
485
|
+
specification =~ /(.+?)(?:\[([-+]?\d+)\])?\z/
|
|
486
|
+
options[:sdn] = $2.to_i if $2
|
|
487
|
+
f, d, t, z, e = When::BasicTypes::DateTime._to_array($1, options)
|
|
488
|
+
raise ArgumentError, "Timezone conflict: #{z} - #{options[:clock]}" if (z && options[:clock])
|
|
489
|
+
options.delete(:abbr)
|
|
490
|
+
z ||= options[:clock]
|
|
491
|
+
z = When.Clock(z) if (z =~ /\A[A-Z]+\z/)
|
|
492
|
+
|
|
493
|
+
unless (d)
|
|
494
|
+
# ClockTime
|
|
495
|
+
raise ArgumentError, "Timezone conflict: #{z} - #{options[:clock]}" if (z && options[:frame])
|
|
496
|
+
options[:frame] ||= z
|
|
497
|
+
options.delete(:clock)
|
|
498
|
+
return ClockTime.new(t, options)
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
options[:era_name] = e if e
|
|
502
|
+
options[:_format ] = f if f
|
|
503
|
+
d, w = d[0..0], d[1..-1] if (f == :week || f == :day)
|
|
504
|
+
position = z ? DateAndTime.new(d, t||[0], options.update({:clock => z})) :
|
|
505
|
+
t ? DateAndTime.new(d, t, options) :
|
|
506
|
+
CalDate.new(d, options)
|
|
507
|
+
case f
|
|
508
|
+
when :day
|
|
509
|
+
position += PeriodDuration.new(w[0]-1, DAY)
|
|
510
|
+
when :week
|
|
511
|
+
position = ((position + PeriodDuration.new(4, DAY)) & (Residue.day_of_week(options[:wkst]) << 1)) +
|
|
512
|
+
PeriodDuration.new((w[0]-1)*7 + (w[1]||1)-1, DAY)
|
|
513
|
+
position = When::Parts::GeometricComplex.new(position...(position+P1W)) unless w[1]
|
|
514
|
+
end
|
|
515
|
+
return position
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
# 時刻系
|
|
520
|
+
#
|
|
521
|
+
# @return [When::TimeStandard]
|
|
522
|
+
#
|
|
523
|
+
def time_standard
|
|
524
|
+
return @time_standard if @time_standard.kind_of?(When::TimeStandard)
|
|
525
|
+
@time_standard ||= clock.time_standard if respond_to?(:clock) && clock
|
|
526
|
+
@time_standard ||= frame.time_standard if frame
|
|
527
|
+
@time_standard ||= 'UniversalTime'
|
|
528
|
+
@time_standard = When.Resource(@time_standard, '_t:')
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# 時間の歩度
|
|
532
|
+
#
|
|
533
|
+
# @return [Numeric]
|
|
534
|
+
#
|
|
535
|
+
def rate_of_clock
|
|
536
|
+
time_standard.rate_of_clock
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
# 内部時間
|
|
540
|
+
#
|
|
541
|
+
# @return [Numeric]
|
|
542
|
+
#
|
|
543
|
+
# 1970-01-01T00:00:00Z からの Universal Time, Coordinated の経過時間 / 128秒
|
|
544
|
+
#
|
|
545
|
+
# 暦法によっては、異なる意味を持つことがある
|
|
546
|
+
#
|
|
547
|
+
def universal_time
|
|
548
|
+
case @indeterminated_position
|
|
549
|
+
when Now ; time_standard.from_time_object(Time.now)
|
|
550
|
+
when Max ; +Float::MAX/4
|
|
551
|
+
when Min ; -Float::MAX/4
|
|
552
|
+
else ; raise NameError, "Temporal Reference System is not defined"
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# 外部時間
|
|
557
|
+
#
|
|
558
|
+
# @return [Numeric]
|
|
559
|
+
#
|
|
560
|
+
# 1970-01-01T00:00:00TT からの terrestrial time の経過時間 / 128秒
|
|
561
|
+
#
|
|
562
|
+
def dynamical_time
|
|
563
|
+
return @dynamical_time if @dynamical_time && @indeterminated_position != Now
|
|
564
|
+
@dynamical_time =
|
|
565
|
+
case @indeterminated_position
|
|
566
|
+
when Max ; +Float::MAX/4
|
|
567
|
+
when Min ; -Float::MAX/4
|
|
568
|
+
else ; time_standard.to_dynamical_time(universal_time)
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
# ユリウス日時(実数)
|
|
573
|
+
#
|
|
574
|
+
# @return [Float]
|
|
575
|
+
#
|
|
576
|
+
# universal time での経過日数を, ユリウス日と1970-01-01T00:00:00Zで時計あわせしたもの
|
|
577
|
+
#
|
|
578
|
+
def to_f
|
|
579
|
+
JulianDate._t_to_d(universal_time)
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
# ユリウス日(整数)
|
|
583
|
+
#
|
|
584
|
+
# @return [Integer]
|
|
585
|
+
#
|
|
586
|
+
# -4712-01-01T12:00:00Z からの経過日数に対応する通番(当該時間帯での午前0時に1進める)
|
|
587
|
+
#
|
|
588
|
+
def to_i
|
|
589
|
+
sd = universal_time
|
|
590
|
+
sd -= @frame.universal_time if @frame.kind_of?(Clock)
|
|
591
|
+
div, mod = sd.divmod(Duration::DAY)
|
|
592
|
+
div + JulianDate::JD19700101
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
# 剰余類化
|
|
596
|
+
#
|
|
597
|
+
# @param [Numeric] remainder 剰余
|
|
598
|
+
# @param [Integer] divisor 法(>0)
|
|
599
|
+
#
|
|
600
|
+
# @return [When::Coordinates::Residue]
|
|
601
|
+
#
|
|
602
|
+
# 当日を基準とする剰余類
|
|
603
|
+
#
|
|
604
|
+
def to_residue(remainder, divisor)
|
|
605
|
+
When::Coordinates::Residue.new(remainder, divisor, {'day'=>to_i})
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
# ユリウス日時(実数)
|
|
609
|
+
#
|
|
610
|
+
# @return [Float]
|
|
611
|
+
#
|
|
612
|
+
# dynamical time での経過日数を, ユリウス日と1970-01-01T00:00:00TTで時計あわせしたもの
|
|
613
|
+
#
|
|
614
|
+
def +@
|
|
615
|
+
JulianDate._t_to_d(dynamical_time)
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
# When::TM::ClockTime オブジェクトへの変換
|
|
619
|
+
#
|
|
620
|
+
# @return [When::TM::ClokTime]
|
|
621
|
+
#
|
|
622
|
+
def to_clock_time
|
|
623
|
+
raise TypeError, "Clock not assigned" unless clock
|
|
624
|
+
clk_time = clock.to_clk_time(universal_time - (to_i - JulianDate::JD19700101)*Duration::DAY)
|
|
625
|
+
clk_time.clk_time[0] += to_i
|
|
626
|
+
return clk_time
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
# 標準ライブラリの DateTime オブジェクトへの変換
|
|
630
|
+
#
|
|
631
|
+
# @param [Hash] option 時間の歩度が1.0でない場合のための option
|
|
632
|
+
# see {When::TM::TemporalPosition._instance}
|
|
633
|
+
#
|
|
634
|
+
# @param [Integer] start ::DateTime オブジェクトのグレゴリオ改暦日(ユリウス通日)
|
|
635
|
+
#
|
|
636
|
+
# @return [::DateTime]
|
|
637
|
+
#
|
|
638
|
+
def to_date_time(option={:frame=>When::UTC}, start=_default_start)
|
|
639
|
+
return JulianDate.dynamical_time(dynamical_time, option).to_date_time unless time_standard.rate_of_clock == 1.0
|
|
640
|
+
raise TypeError, "Clock not assigned" unless clock
|
|
641
|
+
Rational
|
|
642
|
+
offset = Rational(-(clock.universal_time/Duration::SECOND).to_i, (Duration::DAY/Duration::SECOND).to_i)
|
|
643
|
+
clk_time = clock.to_clk_time(universal_time - (to_i - JulianDate::JD19700101)*Duration::DAY).clk_time
|
|
644
|
+
::DateTime.jd(to_i, clk_time[1], clk_time[2], clk_time[3].to_i, offset, start)
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
# 標準ライブラリの Date オブジェクトへの変換
|
|
648
|
+
#
|
|
649
|
+
# @param [Hash] option 時間の歩度が1.0でない場合のための option
|
|
650
|
+
# see {When::TM::TemporalPosition._instance}
|
|
651
|
+
#
|
|
652
|
+
# @param [Integer] start ::DateTime オブジェクトのグレゴリオ改暦日(ユリウス通日)
|
|
653
|
+
#
|
|
654
|
+
# @return [::Date]
|
|
655
|
+
#
|
|
656
|
+
def to_date(option={}, start=_default_start)
|
|
657
|
+
return JulianDate.dynamical_time(dynamical_time, option).to_date unless time_standard.rate_of_clock == 1.0
|
|
658
|
+
::Date.jd(to_i, start)
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
# 組み込みライブラリの Time オブジェクトへの変換
|
|
662
|
+
#
|
|
663
|
+
# @return [::Time]
|
|
664
|
+
#
|
|
665
|
+
def to_time
|
|
666
|
+
time_standard.to_time_object(universal_time)
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
# 要素の参照
|
|
670
|
+
#
|
|
671
|
+
# @param [Integer, String] index 参照する要素の指定
|
|
672
|
+
#
|
|
673
|
+
# @return [Numeric]
|
|
674
|
+
#
|
|
675
|
+
def [](index)
|
|
676
|
+
return value(index) if index.kind_of?(String) || !index.respond_to?(:inject)
|
|
677
|
+
index.inject([]) {|list, i| list << value(i) }
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
# 加算
|
|
681
|
+
#
|
|
682
|
+
# @param [Numeric, When::TM::Duration] other
|
|
683
|
+
#
|
|
684
|
+
# @return [When::TM::TemporalPosition]
|
|
685
|
+
#
|
|
686
|
+
def +(other)
|
|
687
|
+
case other
|
|
688
|
+
when Integer ; self + PeriodDuration.new(other, When::DAY)
|
|
689
|
+
when Numeric ; self + IntervalLength.new(other, 'day')
|
|
690
|
+
when PeriodDuration ; _plus(other)
|
|
691
|
+
when Duration ; @frame.kind_of?(Calendar) ? @frame.jul_trans(JulianDate.dynamical_time(dynamical_time + other.duration), self._attr) :
|
|
692
|
+
JulianDate.dynamical_time(dynamical_time + other.duration, self._attr)
|
|
693
|
+
else ; raise TypeError, "The right operand should be Numeric or Duration"
|
|
694
|
+
end
|
|
695
|
+
rescue RangeError
|
|
696
|
+
(@frame ^ self) + other
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
# 減算
|
|
700
|
+
#
|
|
701
|
+
# @param [Numeric, When::TM::Duration, When::TM::TemporalPosition] other
|
|
702
|
+
#
|
|
703
|
+
# @return [When::TM::TemporalPosition] if other is a Numeric or When::TM::Duration
|
|
704
|
+
# @return [When::TM::Duration] if other is a When::TM::TemporalPosition
|
|
705
|
+
#
|
|
706
|
+
def -(other)
|
|
707
|
+
case other
|
|
708
|
+
when TimeValue ; self.time_standard.rate_of_clock == other.time_standard.rate_of_clock && [@precision, other.precision].min <= When::DAY ?
|
|
709
|
+
PeriodDuration.new(self.to_i - other.to_i, When::DAY) :
|
|
710
|
+
IntervalLength.new((self.dynamical_time - other.dynamical_time) / Duration::SECOND, 'second')
|
|
711
|
+
when Integer ; self - PeriodDuration.new(other, When::DAY)
|
|
712
|
+
when Numeric ; self - IntervalLength.new(other, 'day')
|
|
713
|
+
when PeriodDuration ; _plus(-other)
|
|
714
|
+
when Duration ; @frame.kind_of?(Calendar) ? @frame.jul_trans(JulianDate.dynamical_time(dynamical_time - other.duration), self._attr) :
|
|
715
|
+
JulianDate.dynamical_time(dynamical_time - other.duration, self._attr)
|
|
716
|
+
else ; raise TypeError, "The right operand should be Numeric, Duration or TemporalPosition"
|
|
717
|
+
end
|
|
718
|
+
rescue RangeError
|
|
719
|
+
(@frame ^ self) - other
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
# 分解能に対応する Duration
|
|
723
|
+
#
|
|
724
|
+
# @return [When::TM::PeriodDuration]
|
|
725
|
+
#
|
|
726
|
+
def period
|
|
727
|
+
return @period if @period
|
|
728
|
+
period_name = When::Coordinates::PERIOD_NAME[@precision]
|
|
729
|
+
raise ArgumentError, "Presicion not defined" unless period_name
|
|
730
|
+
@period = When.Duration(period_name)
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
# 前の日時
|
|
734
|
+
#
|
|
735
|
+
# @return [When::TM::TemporalPosition]
|
|
736
|
+
#
|
|
737
|
+
# 分解能に対応する Duration だけ,日時を戻す
|
|
738
|
+
#
|
|
739
|
+
def prev
|
|
740
|
+
@precision==When::DAY ? _force_euqal_day(-1) : self-period
|
|
741
|
+
rescue RangeError
|
|
742
|
+
(When::Gregorian ^ self) - period
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
# 次の日時
|
|
746
|
+
#
|
|
747
|
+
# @return [When::TM::TemporalPosition]
|
|
748
|
+
#
|
|
749
|
+
# 分解能に対応する Duration だけ,日時を進める
|
|
750
|
+
#
|
|
751
|
+
def succ
|
|
752
|
+
@precision==When::DAY ? _force_euqal_day(+1) : self+period
|
|
753
|
+
rescue RangeError
|
|
754
|
+
(When::Gregorian ^ self) + period
|
|
755
|
+
end
|
|
756
|
+
alias :next :succ
|
|
757
|
+
|
|
758
|
+
#
|
|
759
|
+
# 前後の日時を取得可能か?
|
|
760
|
+
#
|
|
761
|
+
# @return [Boolean]
|
|
762
|
+
# [ true - 可能 ]
|
|
763
|
+
# [ false - 不可 ]
|
|
764
|
+
#
|
|
765
|
+
def has_next?
|
|
766
|
+
When::Coordinates::PERIOD_NAME[@precision] != nil
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
# 下位桁の切り捨て
|
|
770
|
+
#
|
|
771
|
+
# @param [Integer] digit これより下の桁を切り捨てる(省略すると When::DAY)
|
|
772
|
+
#
|
|
773
|
+
# @param [Integer] precision 切り捨て結果の分解能
|
|
774
|
+
#
|
|
775
|
+
# @return [When::TM::TemporalPosition] (本 Class では、実際には切り捨てない)
|
|
776
|
+
#
|
|
777
|
+
def floor(digit=DAY, precision=digit)
|
|
778
|
+
self
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
# 分解能が時刻を持つか
|
|
782
|
+
#
|
|
783
|
+
# @return [Boolean]
|
|
784
|
+
#
|
|
785
|
+
def has_time?
|
|
786
|
+
(@precision > 0)
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
# 指定の日時を含むか?
|
|
790
|
+
#
|
|
791
|
+
# @param [When::TM::TemporalPosition] date チェックされる日時
|
|
792
|
+
#
|
|
793
|
+
# @return [Boolean]
|
|
794
|
+
# [ true - 含む ]
|
|
795
|
+
# [ false - 含まない ]
|
|
796
|
+
#
|
|
797
|
+
def include?(date)
|
|
798
|
+
return false if self.precision > date.precision
|
|
799
|
+
return self == date
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
# オブジェクトの同値
|
|
803
|
+
#
|
|
804
|
+
# @param [比較先] other
|
|
805
|
+
#
|
|
806
|
+
# @return [Boolean]
|
|
807
|
+
# [ true - 同値 ]
|
|
808
|
+
# [ false - 非同値 ]
|
|
809
|
+
#
|
|
810
|
+
def ==(other)
|
|
811
|
+
(self <=> other) == 0
|
|
812
|
+
rescue
|
|
813
|
+
false
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
# 大小比較
|
|
817
|
+
#
|
|
818
|
+
# @param [When::TM::TemporalPosition] other チェックされる日時
|
|
819
|
+
# @param [Numeric] other チェックされる日時の universal time(self と同じtime_standardとみなす)
|
|
820
|
+
#
|
|
821
|
+
# @return [Integer] (-1, 0, 1)
|
|
822
|
+
#
|
|
823
|
+
# 分解能の低い方にあわせて比較を行う
|
|
824
|
+
#
|
|
825
|
+
# Ex. when?('2011-03') <=> when?('2011-03-10') -> 0
|
|
826
|
+
#
|
|
827
|
+
def <=>(other)
|
|
828
|
+
other = other.first if other.kind_of?(Range)
|
|
829
|
+
return universal_time <=> other if other.kind_of?(Numeric)
|
|
830
|
+
|
|
831
|
+
[self.indeterminated_position, other.indeterminated_position].each do |position|
|
|
832
|
+
prec = SYSTEM if [TimeValue::Min, TimeValue::Max].include?(position)
|
|
833
|
+
end
|
|
834
|
+
prec = [self.precision, other.precision].min unless prec
|
|
835
|
+
|
|
836
|
+
case prec
|
|
837
|
+
when DAY ; return self.to_i <=> other.to_i
|
|
838
|
+
when SYSTEM ; return TemporalPosition._verify(self, other)
|
|
839
|
+
end
|
|
840
|
+
|
|
841
|
+
if prec < DAY && respond_to?(:most_significant_coordinate) &&
|
|
842
|
+
other.respond_to?(:most_significant_coordinate) && @frame.equal?(other.frame)
|
|
843
|
+
self_year = most_significant_coordinate
|
|
844
|
+
other_year = other.most_significant_coordinate
|
|
845
|
+
if @cal_date.length + prec == 1
|
|
846
|
+
self_year *= 1
|
|
847
|
+
other_year *= 1
|
|
848
|
+
end
|
|
849
|
+
result = self_year <=> other_year
|
|
850
|
+
return result unless result == 0 && @cal_date.length + prec > 1
|
|
851
|
+
(@cal_date.length + prec - 2).times do |i|
|
|
852
|
+
result = @cal_date[i+1] <=> other.cal_date[i+1]
|
|
853
|
+
return result unless result == 0
|
|
854
|
+
end
|
|
855
|
+
@cal_date[prec - 1] <=> other.cal_date[prec - 1]
|
|
856
|
+
else
|
|
857
|
+
source = (prec >= self.precision ) ? self : self.floor(prec)
|
|
858
|
+
target = (prec >= other.precision) ? other : other.floor(prec)
|
|
859
|
+
return source.to_i <=> target.to_i if prec <= DAY
|
|
860
|
+
TemporalPosition._verify(source, target)
|
|
861
|
+
end
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
# 条件を満たすオブジェクトの抽出
|
|
865
|
+
#
|
|
866
|
+
# @param [Module, Array<Moduel>, When::Coordinates::Residue, When::TM::Duration, When::TM::Calendar, When::TM::CalendarEra] other
|
|
867
|
+
# @param [Boolean] leaf extract only leaf Objects.
|
|
868
|
+
# @param [Block] block If block is given, the specified block is yield.
|
|
869
|
+
#
|
|
870
|
+
# @return [Array of (element^self) for all When::Parts::Resource registered elements] (If other is Module)
|
|
871
|
+
# @return [Array of (self^element) for elemnt of other which belong to the specified module or class] (If other is [Array])
|
|
872
|
+
# @return [Enumerator which generates temporal position sequence begins from self with the specified duration] (If other is [When::TM::Duration])
|
|
873
|
+
# @return [Array of temporal position using the specified calendar as a frame] (If other is [When::TM::Calendar])
|
|
874
|
+
# @return [Array of temporal position using the specified calendar era as a calendarEraName] (If other is [When::TM::CalendarEra])
|
|
875
|
+
#
|
|
876
|
+
def scan(other, leaf=false, &block)
|
|
877
|
+
list = []
|
|
878
|
+
case other
|
|
879
|
+
when Numeric, TemporalPosition, Position
|
|
880
|
+
raise TypeError, "Operand should not be Numeric or (Temporal)Position"
|
|
881
|
+
|
|
882
|
+
when Module
|
|
883
|
+
objects = []
|
|
884
|
+
ObjectSpace.each_object(other) do |object|
|
|
885
|
+
objects << object if object.registered?
|
|
886
|
+
end
|
|
887
|
+
objects.each do |object|
|
|
888
|
+
element = (object ^ self)
|
|
889
|
+
if element && !(leaf && element.respond_to?(:leaf?) && !element.leaf?)
|
|
890
|
+
list << element
|
|
891
|
+
yield(element) if block_given?
|
|
892
|
+
end
|
|
893
|
+
end
|
|
894
|
+
return list
|
|
895
|
+
|
|
896
|
+
when Array
|
|
897
|
+
return other.map {|v| scan(v, leaf, &block)}
|
|
898
|
+
|
|
899
|
+
else
|
|
900
|
+
if other.respond_to?(:_enumerator)
|
|
901
|
+
enumerator = other._enumerator(self)
|
|
902
|
+
return enumerator unless block_given?
|
|
903
|
+
return enumerator.each(&block)
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
element = (other ^ self)
|
|
907
|
+
if element && !(leaf && element.respond_to?(:leaf?) && !element.leaf?)
|
|
908
|
+
list << element
|
|
909
|
+
yield(element) if block_given?
|
|
910
|
+
end
|
|
911
|
+
if (other.respond_to?(:child) && other.child)
|
|
912
|
+
other.child.each do |object|
|
|
913
|
+
list += scan(object, leaf, &block)
|
|
914
|
+
end
|
|
915
|
+
end
|
|
916
|
+
return list
|
|
917
|
+
end
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
# 条件を満たすオブジェクトの抽出
|
|
921
|
+
#
|
|
922
|
+
# @param (see #scan)
|
|
923
|
+
# @return (see #scan)
|
|
924
|
+
#
|
|
925
|
+
def ^(other, leaf=true, &block)
|
|
926
|
+
scan(other, leaf, &block)
|
|
927
|
+
end
|
|
928
|
+
|
|
929
|
+
# 属性を変更したコピーを作る
|
|
930
|
+
#
|
|
931
|
+
# @param [Hash] options { 属性=>属性値 }
|
|
932
|
+
#
|
|
933
|
+
# @return [When::TM::TemporalPosition]
|
|
934
|
+
#
|
|
935
|
+
def copy(options={})
|
|
936
|
+
position = self.dup
|
|
937
|
+
position._copy(options)
|
|
938
|
+
position
|
|
939
|
+
end
|
|
940
|
+
|
|
941
|
+
# 属性の Hash
|
|
942
|
+
# @private
|
|
943
|
+
def _attr
|
|
944
|
+
attributes = {}
|
|
945
|
+
[:frame, :events, :precision, :options, :trans, :query].each do |key|
|
|
946
|
+
attributes[key] = instance_variable_get("@#{key}")
|
|
947
|
+
end
|
|
948
|
+
attributes[:location] = location
|
|
949
|
+
attributes[:time_standard] = time_standard
|
|
950
|
+
return attributes.delete_if {|k,v| !v}
|
|
951
|
+
end
|
|
952
|
+
|
|
953
|
+
protected
|
|
954
|
+
|
|
955
|
+
# 属性のコピー
|
|
956
|
+
# @private
|
|
957
|
+
def _copy(options={})
|
|
958
|
+
@frame = options[:frame] if (options.key?(:frame))
|
|
959
|
+
@events = options[:events] if (options.key?(:events))
|
|
960
|
+
@precision = options[:precision] if (options.key?(:precision))
|
|
961
|
+
@query = options[:query] if (options.key?(:query))
|
|
962
|
+
@location = options[:location] if (options.key?(:location))
|
|
963
|
+
@time_standard = options[:time_standard] if (options.key?(:time_standard))
|
|
964
|
+
@sdn = @universal_time = @dynamical_time = @period = nil
|
|
965
|
+
_normalize(options)
|
|
966
|
+
return self
|
|
967
|
+
end
|
|
968
|
+
|
|
969
|
+
private
|
|
970
|
+
|
|
971
|
+
# オブジェクトの生成
|
|
972
|
+
#
|
|
973
|
+
# @param [Hash] options see {When::TM::TemporalPosition._instance}
|
|
974
|
+
#
|
|
975
|
+
def initialize(options={})
|
|
976
|
+
options.reject! {|key,value| value == nil}
|
|
977
|
+
options.each_pair do |key,value|
|
|
978
|
+
self.instance_variable_set("@#{key}", value)
|
|
979
|
+
end
|
|
980
|
+
@keys = []
|
|
981
|
+
@location = When.Resource(@location, '_l:') if @location.kind_of?(String)
|
|
982
|
+
# @sdn = @universal_time = @dynamical_time = nil
|
|
983
|
+
_normalize(options)
|
|
984
|
+
end
|
|
985
|
+
|
|
986
|
+
# オブジェクトの正規化
|
|
987
|
+
def _normalize(options={})
|
|
988
|
+
@precision ||= SYSTEM
|
|
989
|
+
@period = nil
|
|
990
|
+
@keys |= @frame.keys if @frame
|
|
991
|
+
end
|
|
992
|
+
|
|
993
|
+
# 指定桁のチェック
|
|
994
|
+
def _digit(index)
|
|
995
|
+
digit = index.kind_of?(String) ? PRECISION[index.upcase] : index
|
|
996
|
+
raise RangeError, " wrong digit: #{index}" unless digit.kind_of?(Integer) && (!block_given? || yield(digit))
|
|
997
|
+
digit
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
# 指定の日を探す
|
|
1001
|
+
def _force_euqal_day(diff)
|
|
1002
|
+
jdn = self.to_i + diff
|
|
1003
|
+
date = self
|
|
1004
|
+
done = {}
|
|
1005
|
+
loop do
|
|
1006
|
+
case
|
|
1007
|
+
when date.to_i == jdn
|
|
1008
|
+
return date
|
|
1009
|
+
when date.to_i > jdn
|
|
1010
|
+
next_date = date - When::P1D
|
|
1011
|
+
date = (date.to_i == next_date.to_i) ? date - When::P2D : next_date
|
|
1012
|
+
when date.to_i < jdn
|
|
1013
|
+
next_date = date + When::P1D
|
|
1014
|
+
date = (date.to_i == next_date.to_i) ? date + When::P2D : next_date
|
|
1015
|
+
end
|
|
1016
|
+
raise RangeError, "can't find target date: #{self} -> #{jdn}" if done.key?(date.to_i)
|
|
1017
|
+
done[date.to_i] = true
|
|
1018
|
+
end
|
|
1019
|
+
end
|
|
1020
|
+
|
|
1021
|
+
#
|
|
1022
|
+
# 対応する ::Date の start 属性
|
|
1023
|
+
def _default_start
|
|
1024
|
+
frame ? frame._default_start : ::Date::GREGORIAN
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
alias :_method_missing :method_missing
|
|
1028
|
+
|
|
1029
|
+
# その他のメソッド
|
|
1030
|
+
#
|
|
1031
|
+
# @note
|
|
1032
|
+
# When::TM::TemporalPosition で定義されていないメソッドは
|
|
1033
|
+
# 処理を @frame (type: When::TM::Calendar or When::TM::Clock) に委譲する
|
|
1034
|
+
#
|
|
1035
|
+
def method_missing(name, *args, &block)
|
|
1036
|
+
|
|
1037
|
+
return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
|
|
1038
|
+
self.class.module_eval %Q{
|
|
1039
|
+
def #{name}(*args, &block)
|
|
1040
|
+
@frame.send("#{name}", self, *args, &block)
|
|
1041
|
+
end
|
|
1042
|
+
} unless When::Parts::MethodCash.escape(name)
|
|
1043
|
+
@frame.send(name, self, *args, &block)
|
|
1044
|
+
end
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
#
|
|
1048
|
+
# 時間座標 - 単一の時間間隔によって定義する連続な間隔尺度を基礎とする
|
|
1049
|
+
#
|
|
1050
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#TimeCoordinateType gml schema}
|
|
1051
|
+
#
|
|
1052
|
+
class Coordinate < TemporalPosition
|
|
1053
|
+
|
|
1054
|
+
class << self
|
|
1055
|
+
# 内部時間によるオブジェクトの生成
|
|
1056
|
+
alias :universal_time :new
|
|
1057
|
+
|
|
1058
|
+
# 外部時間によるオブジェクトの生成
|
|
1059
|
+
#
|
|
1060
|
+
# @param [Numeric] dynamical_time 外部時間による時間座標値
|
|
1061
|
+
#
|
|
1062
|
+
# @param [Hash] options 下記の通り
|
|
1063
|
+
# @option options [When::TimeStandard] :time_standard
|
|
1064
|
+
#
|
|
1065
|
+
# @return [When::TM::Coordinate]
|
|
1066
|
+
#
|
|
1067
|
+
def dynamical_time(dynamical_time, options={})
|
|
1068
|
+
universal_time(When.Resource(options[:time_standard] || 'UniversalTime', '_t:').from_dynamical_time(dynamical_time), options)
|
|
1069
|
+
end
|
|
1070
|
+
|
|
1071
|
+
# 他種の時間位置によるオブジェクトの生成
|
|
1072
|
+
#
|
|
1073
|
+
# @param [Numeric, When::TM::ClockTime, ::Time, ::Date, ::DateTime] time 他種の時間位置によるオブジェクト
|
|
1074
|
+
#
|
|
1075
|
+
# @param [Hash] options 下記の通り
|
|
1076
|
+
# @option options [When::TM::Clock] :clock
|
|
1077
|
+
# @option options [When::Parts::Timezone] :tz
|
|
1078
|
+
#
|
|
1079
|
+
# @return [When::TM::Coordinate]
|
|
1080
|
+
#
|
|
1081
|
+
def new(time, options={})
|
|
1082
|
+
options = options.dup
|
|
1083
|
+
options[:frame] = Clock.get_clock_option(options)
|
|
1084
|
+
case time
|
|
1085
|
+
when Numeric
|
|
1086
|
+
options[:frame] ||= When::UTC unless time.kind_of?(Integer)
|
|
1087
|
+
universal_time = (2*time - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
|
|
1088
|
+
when ClockTime
|
|
1089
|
+
options[:frame] ||= time.clock
|
|
1090
|
+
universal_time = time.clk_time[0] + time.universal_time
|
|
1091
|
+
when ::Time
|
|
1092
|
+
options[:frame] ||= When.Clock(time.gmtoff)
|
|
1093
|
+
universal_time = options[:frame].time_standard.from_time_object(time)
|
|
1094
|
+
when TimeValue
|
|
1095
|
+
options[:frame] ||= time.clock
|
|
1096
|
+
universal_time = time.universal_time
|
|
1097
|
+
else
|
|
1098
|
+
if ::Object.const_defined?(:Date) && time.respond_to?(:ajd)
|
|
1099
|
+
case time
|
|
1100
|
+
when ::DateTime
|
|
1101
|
+
options[:frame] ||= When.Clock((time.offset * 86400).to_i)
|
|
1102
|
+
universal_time = (2*time.ajd - (2*JulianDate::JD19700101-1)) * Duration::DAY.to_i / 2.0
|
|
1103
|
+
when ::Date
|
|
1104
|
+
universal_time = JulianDate._d_to_t(time.jd)
|
|
1105
|
+
if options[:frame] && options[:frame].rate_of_clock != 1.0
|
|
1106
|
+
universal_time = options[:frame].time_standard.from_dynamical_time(
|
|
1107
|
+
When::TimeStandard.to_dynamical_time(universal_time))
|
|
1108
|
+
end
|
|
1109
|
+
end
|
|
1110
|
+
end
|
|
1111
|
+
end
|
|
1112
|
+
raise TypeError, "Can't create #{self} from #{time.class}" unless universal_time
|
|
1113
|
+
universal_time(universal_time, options)
|
|
1114
|
+
end
|
|
1115
|
+
end
|
|
1116
|
+
|
|
1117
|
+
# この時間位置と関連付けられた時間参照系 (relation - Reference)
|
|
1118
|
+
#
|
|
1119
|
+
# The time reference system associated with the temporal position being described
|
|
1120
|
+
#
|
|
1121
|
+
# @return [When::TM::ReferenceSystem]
|
|
1122
|
+
#
|
|
1123
|
+
alias :clock :frame
|
|
1124
|
+
|
|
1125
|
+
# 内部時間による時間座標値
|
|
1126
|
+
#
|
|
1127
|
+
# @return [Numeric]
|
|
1128
|
+
#
|
|
1129
|
+
attr_accessor :universal_time
|
|
1130
|
+
alias :coordinateValue :universal_time
|
|
1131
|
+
protected :universal_time=
|
|
1132
|
+
|
|
1133
|
+
# CoordinateSystem による時間座標値
|
|
1134
|
+
#
|
|
1135
|
+
# @return [Numeric]
|
|
1136
|
+
#
|
|
1137
|
+
def coordinateValue
|
|
1138
|
+
(universal_time - frame.origin.universal_time) / frame.interval.to_f
|
|
1139
|
+
end
|
|
1140
|
+
|
|
1141
|
+
# 加算
|
|
1142
|
+
#
|
|
1143
|
+
# @param [Numeric, When::TM::IntervalLength] other
|
|
1144
|
+
#
|
|
1145
|
+
# @return [When::TM::TemporalPosition]
|
|
1146
|
+
#
|
|
1147
|
+
def +(other)
|
|
1148
|
+
other = other.to_interval_length if other.kind_of?(PeriodDuration)
|
|
1149
|
+
super(other)
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
# 減算
|
|
1153
|
+
#
|
|
1154
|
+
# @param [When::TM::TemporalPosition, Numeric, When::TM::IntervalLength] other
|
|
1155
|
+
#
|
|
1156
|
+
# @return [When::TM::TemporalPosition] if other is a Numeric or When::TM::IntervalLength
|
|
1157
|
+
# @return [When::TM::IntervalLength] if other is a When::TM::TemporalPosition
|
|
1158
|
+
#
|
|
1159
|
+
def -(other)
|
|
1160
|
+
other = other.to_interval_length if other.kind_of?(PeriodDuration)
|
|
1161
|
+
super(other)
|
|
1162
|
+
end
|
|
1163
|
+
|
|
1164
|
+
# オブジェクトの生成
|
|
1165
|
+
#
|
|
1166
|
+
# @param [Numeric] universal_time 内部時間による時間座標値
|
|
1167
|
+
#
|
|
1168
|
+
# @param [Hash] options 下記の通り
|
|
1169
|
+
# @option options [When::TM::CoordinateSystem] :frame
|
|
1170
|
+
#
|
|
1171
|
+
def initialize(universal_time, options={})
|
|
1172
|
+
super(options)
|
|
1173
|
+
@universal_time = universal_time
|
|
1174
|
+
end
|
|
1175
|
+
end
|
|
1176
|
+
|
|
1177
|
+
#
|
|
1178
|
+
# ユリウス日
|
|
1179
|
+
#
|
|
1180
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#JulianDateType gml schema}
|
|
1181
|
+
#
|
|
1182
|
+
class JulianDate < Coordinate
|
|
1183
|
+
|
|
1184
|
+
# Julian Day Number
|
|
1185
|
+
# 19700101T120000Z
|
|
1186
|
+
JD19700101 = 2440588
|
|
1187
|
+
|
|
1188
|
+
class << self
|
|
1189
|
+
|
|
1190
|
+
JD19700100_5 = JD19700101 - 0.5
|
|
1191
|
+
|
|
1192
|
+
#
|
|
1193
|
+
# 日時の内部表現をユリウス日に変換
|
|
1194
|
+
#
|
|
1195
|
+
# @param [Numeric] t
|
|
1196
|
+
#
|
|
1197
|
+
# @return [Numeric]
|
|
1198
|
+
#
|
|
1199
|
+
def _t_to_d(t)
|
|
1200
|
+
t / Duration::DAY + JD19700100_5
|
|
1201
|
+
end
|
|
1202
|
+
|
|
1203
|
+
#
|
|
1204
|
+
# ユリウス日をに日時の内部表現変換
|
|
1205
|
+
#
|
|
1206
|
+
# @param [Numeric] d
|
|
1207
|
+
#
|
|
1208
|
+
# @return [Numeric]
|
|
1209
|
+
#
|
|
1210
|
+
def _d_to_t(d)
|
|
1211
|
+
(d - JD19700100_5) * Duration::DAY
|
|
1212
|
+
end
|
|
1213
|
+
|
|
1214
|
+
# Generation of Temporal Objetct
|
|
1215
|
+
#
|
|
1216
|
+
# @param [String] specification ユリウス通日を表す文字列
|
|
1217
|
+
# @param [Hash] options 暦法や時法などの指定 (see {When::TM::TemporalPosition._instance})
|
|
1218
|
+
#
|
|
1219
|
+
# @return [When::TM::TemporalPosition, When::TM::Duration, When::Parts::GeometricComplex or Array<them>]
|
|
1220
|
+
#
|
|
1221
|
+
def parse(specification, options={})
|
|
1222
|
+
jdn, *calendars = specification.split(/\^{1,2}/)
|
|
1223
|
+
jdn = jdn.sub!(/[.@]/, '.') ? jdn.to_f : jdn.to_i
|
|
1224
|
+
frame = calendars.shift || options[:frame]
|
|
1225
|
+
return self.new(jdn, options) unless frame
|
|
1226
|
+
calendars.unshift(frame).inject(jdn) {|date, calendar| When.Calendar(calendar).jul_trans(date, options)}
|
|
1227
|
+
end
|
|
1228
|
+
end
|
|
1229
|
+
|
|
1230
|
+
# 加算
|
|
1231
|
+
#
|
|
1232
|
+
# @param [Numeric, When::TM::IntervalLength] other
|
|
1233
|
+
#
|
|
1234
|
+
# @return [When::TM::TemporalPosition]
|
|
1235
|
+
#
|
|
1236
|
+
def +(other)
|
|
1237
|
+
new_date = super
|
|
1238
|
+
new_date.frame = new_date.frame._daylight(new_date.universal_time) if new_date.frame && new_date.frame._need_validate
|
|
1239
|
+
return new_date
|
|
1240
|
+
end
|
|
1241
|
+
|
|
1242
|
+
# ユリウス日が指定の剰余となる日
|
|
1243
|
+
#
|
|
1244
|
+
# @param [When::Coordinates::Residue] other
|
|
1245
|
+
#
|
|
1246
|
+
# @return [When::TM::TemporalPosition]
|
|
1247
|
+
#
|
|
1248
|
+
def &(other)
|
|
1249
|
+
raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
|
|
1250
|
+
raise ArgumentError,"The right operand should have a unit 'day'" unless other.event == 'day'
|
|
1251
|
+
jdn = to_i
|
|
1252
|
+
new_date = self.dup
|
|
1253
|
+
new_date.universal_time += ((other & jdn) - jdn) * Duration::DAY
|
|
1254
|
+
return new_date
|
|
1255
|
+
end
|
|
1256
|
+
|
|
1257
|
+
# ユリウス日の剰余
|
|
1258
|
+
#
|
|
1259
|
+
# @param [When::Coordinates::Residue] other
|
|
1260
|
+
#
|
|
1261
|
+
# @return [Numeric]
|
|
1262
|
+
#
|
|
1263
|
+
def %(other)
|
|
1264
|
+
raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
|
|
1265
|
+
raise ArgumentError,"The right operand should have a unit 'day'" unless other.event == 'day'
|
|
1266
|
+
other % to_i
|
|
1267
|
+
end
|
|
1268
|
+
|
|
1269
|
+
private
|
|
1270
|
+
|
|
1271
|
+
# オブジェクトの生成
|
|
1272
|
+
#
|
|
1273
|
+
# @param [Numeric] universal_time 内部時間による時間座標値
|
|
1274
|
+
#
|
|
1275
|
+
# @param [Hash] options 以下の通り
|
|
1276
|
+
# @option options [When::TM::Clock] :frame
|
|
1277
|
+
# @option options [Integer] :precision
|
|
1278
|
+
#
|
|
1279
|
+
def initialize(universal_time, options={})
|
|
1280
|
+
@frame = options.delete(:frame)
|
|
1281
|
+
@frame = When.Clock(@frame) if (@frame.kind_of?(String))
|
|
1282
|
+
@frame = @frame._daylight(universal_time) if @frame && @frame._need_validate
|
|
1283
|
+
precision = options.delete(:precision)
|
|
1284
|
+
precision ||= DAY unless @frame.kind_of?(Clock)
|
|
1285
|
+
@precision = Index.precision(precision)
|
|
1286
|
+
super
|
|
1287
|
+
end
|
|
1288
|
+
end
|
|
1289
|
+
|
|
1290
|
+
#
|
|
1291
|
+
# 順序時間参照系で参照する位置
|
|
1292
|
+
#
|
|
1293
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#TimeOrdinalPositionType gml schema}
|
|
1294
|
+
#
|
|
1295
|
+
class OrdinalPosition < TemporalPosition
|
|
1296
|
+
|
|
1297
|
+
# この順序位置と関連付けられた順序年代 (relation - Reference)
|
|
1298
|
+
#
|
|
1299
|
+
# The ordinal era associated with the ordinal position being described
|
|
1300
|
+
#
|
|
1301
|
+
# @return [When::TM::OrdinalEra]
|
|
1302
|
+
#
|
|
1303
|
+
attr_reader :ordinal_position
|
|
1304
|
+
alias :ordinalPosition :ordinal_position
|
|
1305
|
+
|
|
1306
|
+
# オブジェクトの生成
|
|
1307
|
+
#
|
|
1308
|
+
# @param [When::TM::OrdinalEra] ordinal_position この順序位置と関連付けられた順序年代
|
|
1309
|
+
# @param [Hash] options see {When::TM::TemporalPosition._instance}
|
|
1310
|
+
#
|
|
1311
|
+
def initialize(ordinal_position, options={})
|
|
1312
|
+
super(options)
|
|
1313
|
+
@ordinal_position = ordinal_position
|
|
1314
|
+
end
|
|
1315
|
+
end
|
|
1316
|
+
|
|
1317
|
+
#
|
|
1318
|
+
# 時刻
|
|
1319
|
+
#
|
|
1320
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#ClockTimeType gml schema}
|
|
1321
|
+
#
|
|
1322
|
+
class ClockTime < TemporalPosition
|
|
1323
|
+
|
|
1324
|
+
# 時刻要素
|
|
1325
|
+
#
|
|
1326
|
+
# @return [Array<Numeric>]
|
|
1327
|
+
#
|
|
1328
|
+
# @note ISO19108 では sequence<Integer> だが、閏時・閏秒などが表現可能なよう Numeric としている。
|
|
1329
|
+
#
|
|
1330
|
+
attr_reader :clk_time
|
|
1331
|
+
alias :clkTime :clk_time
|
|
1332
|
+
|
|
1333
|
+
# この時間位置と関連付けられた時間参照系 (relation - Reference)
|
|
1334
|
+
#
|
|
1335
|
+
# The time reference system associated with the temporal position being described
|
|
1336
|
+
#
|
|
1337
|
+
# @return [When::TM::ReferenceSystem]
|
|
1338
|
+
#
|
|
1339
|
+
alias :clock :frame
|
|
1340
|
+
|
|
1341
|
+
# 内部時間
|
|
1342
|
+
#
|
|
1343
|
+
# @return [Numeric]
|
|
1344
|
+
#
|
|
1345
|
+
# T00:00:00Z からの Universal Coordinated Time の経過時間 / 128秒
|
|
1346
|
+
#
|
|
1347
|
+
# 時法によっては、異なる意味を持つことがある
|
|
1348
|
+
#
|
|
1349
|
+
def universal_time
|
|
1350
|
+
raise NameError, "Temporal Reference System is not defined" unless @frame
|
|
1351
|
+
@universal_time ||= @frame.to_universal_time(@clk_time)
|
|
1352
|
+
end
|
|
1353
|
+
|
|
1354
|
+
# 繰り上がり
|
|
1355
|
+
#
|
|
1356
|
+
# @return [Numeric]
|
|
1357
|
+
#
|
|
1358
|
+
# 日付の境界が午前0時でない場合、clk_time の最上位桁に 0 以外が入ることがある
|
|
1359
|
+
#
|
|
1360
|
+
def carry
|
|
1361
|
+
return @clk_time[0]
|
|
1362
|
+
end
|
|
1363
|
+
|
|
1364
|
+
# 要素の参照
|
|
1365
|
+
#
|
|
1366
|
+
# @param [Integer, String] index 参照する要素の指定
|
|
1367
|
+
#
|
|
1368
|
+
# @return [Numeric]
|
|
1369
|
+
#
|
|
1370
|
+
def value(index)
|
|
1371
|
+
@clk_time[_digit(index) {|digit| digit >= DAY}]
|
|
1372
|
+
end
|
|
1373
|
+
|
|
1374
|
+
#protected
|
|
1375
|
+
# 属性のコピー
|
|
1376
|
+
# @private
|
|
1377
|
+
def _copy(options={})
|
|
1378
|
+
@clk_time = options[:time] if (options.key?(:time))
|
|
1379
|
+
@frame = options[:clock] if (options.key?(:clock))
|
|
1380
|
+
if (options.key?(:tz_prop))
|
|
1381
|
+
@frame = @frame.dup
|
|
1382
|
+
@frame.tz_prop = options[:tz_prop]
|
|
1383
|
+
end
|
|
1384
|
+
return super
|
|
1385
|
+
end
|
|
1386
|
+
|
|
1387
|
+
# オブジェクトの生成
|
|
1388
|
+
#
|
|
1389
|
+
# @param [String] time ISO8601形式の時刻表現
|
|
1390
|
+
# @param [Array<Numeric>] time (日, 時, 分, 秒)
|
|
1391
|
+
#
|
|
1392
|
+
#
|
|
1393
|
+
# @param [Hash] options 以下の通り
|
|
1394
|
+
# @option options [When::TM::Clock] :frame
|
|
1395
|
+
# @option options [Integer] :precision
|
|
1396
|
+
#
|
|
1397
|
+
def initialize(time, options={})
|
|
1398
|
+
# 参照系の取得
|
|
1399
|
+
@frame = options[:frame] || Clock.local_time
|
|
1400
|
+
@frame = When.Clock(@frame) if (@frame.kind_of?(String))
|
|
1401
|
+
options.delete(:frame)
|
|
1402
|
+
|
|
1403
|
+
# 時刻表現の解読 ( Time Zone の解釈 )
|
|
1404
|
+
if (time.kind_of?(String))
|
|
1405
|
+
case time
|
|
1406
|
+
when /\A([-+])?(\d{2,}?):?(\d{2})?:?(\d{2}(\.\d+)?)?\z/
|
|
1407
|
+
sign, hh, mm, ss = $~[1..4]
|
|
1408
|
+
time = @frame._validate([0,0,0,0],
|
|
1409
|
+
[0,
|
|
1410
|
+
-(sign.to_s + "0" + hh.to_s).to_i,
|
|
1411
|
+
-(sign.to_s + "0" + mm.to_s).to_i,
|
|
1412
|
+
Pair._en_number(-(sign.to_s + "0" + ss.to_s).to_f)])
|
|
1413
|
+
time[0] = Pair.new(0, time[0].to_i) if (time[0] != 0)
|
|
1414
|
+
when /\AZ\z/
|
|
1415
|
+
time = [0,0,0,0]
|
|
1416
|
+
else
|
|
1417
|
+
raise ArgumentError, "Invalid Time Format"
|
|
1418
|
+
end
|
|
1419
|
+
end
|
|
1420
|
+
@clk_time = time
|
|
1421
|
+
|
|
1422
|
+
# 分解能
|
|
1423
|
+
@precision = @frame._precision(time, options.delete(:precision))
|
|
1424
|
+
|
|
1425
|
+
super(options)
|
|
1426
|
+
end
|
|
1427
|
+
|
|
1428
|
+
private
|
|
1429
|
+
|
|
1430
|
+
# オブジェクトの正規化
|
|
1431
|
+
def _normalize(options={})
|
|
1432
|
+
# strftime で使用する locale
|
|
1433
|
+
@keys |= @frame.keys
|
|
1434
|
+
|
|
1435
|
+
# 時刻の正規化
|
|
1436
|
+
@clk_time = @frame._validate(@clk_time) unless options[:validate]
|
|
1437
|
+
end
|
|
1438
|
+
|
|
1439
|
+
# 加減算共通処理
|
|
1440
|
+
def _plus(period)
|
|
1441
|
+
self.dup._copy({:time=>@frame._validate(@clk_time, @frame._arrange_length(period.time)),
|
|
1442
|
+
:events=>nil, :query=>nil, :validate=>:done})
|
|
1443
|
+
end
|
|
1444
|
+
end
|
|
1445
|
+
|
|
1446
|
+
#
|
|
1447
|
+
# 暦日
|
|
1448
|
+
#
|
|
1449
|
+
# see {gml schema}[link:http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#CalDateType]
|
|
1450
|
+
#
|
|
1451
|
+
class CalDate < TemporalPosition
|
|
1452
|
+
|
|
1453
|
+
# 検索オプション
|
|
1454
|
+
# @private
|
|
1455
|
+
SearchOption = {After=>[0, -2, Before], Before=>[-2, 0, After]}
|
|
1456
|
+
|
|
1457
|
+
# 日付要素
|
|
1458
|
+
#
|
|
1459
|
+
# @return [Array<Numeric>]
|
|
1460
|
+
#
|
|
1461
|
+
# @note ISO19108 では sequence<Integer> だが、閏月などが表現可能なよう Numeric としている。
|
|
1462
|
+
#
|
|
1463
|
+
attr_reader :cal_date
|
|
1464
|
+
alias :calDate :cal_date
|
|
1465
|
+
|
|
1466
|
+
# この時間位置と関連付けられた時間参照系 (relation - Reference)
|
|
1467
|
+
#
|
|
1468
|
+
# The time reference system associated with the temporal position being described
|
|
1469
|
+
#
|
|
1470
|
+
# @return [When::TM::ReferenceSystem]
|
|
1471
|
+
#
|
|
1472
|
+
alias :calendar :frame
|
|
1473
|
+
|
|
1474
|
+
# 暦年代名
|
|
1475
|
+
#
|
|
1476
|
+
# @return [Array] ( name, epoch, reverse, go back )
|
|
1477
|
+
# - name [String] 暦年代名
|
|
1478
|
+
# - epoch [Integer] 使用する When::TM::Calendar で暦元に対応する年
|
|
1479
|
+
# - reverse [Boolean] 年数が昇順(false,nil)か降順(true)か
|
|
1480
|
+
# - go back [Boolean] 参照イベントより前の暦日か(true)、否か(false,nil)
|
|
1481
|
+
#
|
|
1482
|
+
attr_accessor :calendar_era_name
|
|
1483
|
+
private :calendar_era_name=
|
|
1484
|
+
alias :calendarEraName :calendar_era_name
|
|
1485
|
+
|
|
1486
|
+
# 暦年代
|
|
1487
|
+
#
|
|
1488
|
+
# @return [When::TM::CalendarEra]
|
|
1489
|
+
#
|
|
1490
|
+
attr_accessor :calendar_era
|
|
1491
|
+
private :calendar_era=
|
|
1492
|
+
alias :calendarEra :calendar_era
|
|
1493
|
+
|
|
1494
|
+
# 時法の取得 - ダミー
|
|
1495
|
+
def clock
|
|
1496
|
+
nil
|
|
1497
|
+
end
|
|
1498
|
+
|
|
1499
|
+
# 内部時間
|
|
1500
|
+
#
|
|
1501
|
+
# @return [Numeric]
|
|
1502
|
+
#
|
|
1503
|
+
# 当日正午の 1970-01-01T00:00:00Z からの Universal Coordinated Time の経過時間 / 128秒
|
|
1504
|
+
#
|
|
1505
|
+
def universal_time
|
|
1506
|
+
return super if [Now, Max, Min].include?(@indeterminated_position)
|
|
1507
|
+
@universal_time ||= JulianDate._d_to_t(to_i)
|
|
1508
|
+
end
|
|
1509
|
+
|
|
1510
|
+
# ユリウス日
|
|
1511
|
+
#
|
|
1512
|
+
# @return [Integer]
|
|
1513
|
+
#
|
|
1514
|
+
# -4712-01-01からの経過日数に対応する通番
|
|
1515
|
+
#
|
|
1516
|
+
def to_i
|
|
1517
|
+
@sdn ||= _to_i
|
|
1518
|
+
end
|
|
1519
|
+
|
|
1520
|
+
#
|
|
1521
|
+
# 暦法上の通日
|
|
1522
|
+
#
|
|
1523
|
+
def _to_i
|
|
1524
|
+
name, base = @calendar_era_name
|
|
1525
|
+
if base
|
|
1526
|
+
date = @cal_date.dup
|
|
1527
|
+
date[0] += base
|
|
1528
|
+
else
|
|
1529
|
+
date = @cal_date
|
|
1530
|
+
end
|
|
1531
|
+
@frame.to_julian_date(date)
|
|
1532
|
+
end
|
|
1533
|
+
private :_to_i
|
|
1534
|
+
|
|
1535
|
+
# 剰余類化
|
|
1536
|
+
#
|
|
1537
|
+
# @param [Numeric] remainder 剰余
|
|
1538
|
+
# @param [Integer] divisor 法(>0)
|
|
1539
|
+
#
|
|
1540
|
+
# @return [When::Coordinates::Residue] 当日、当年を基準とする剰余類
|
|
1541
|
+
#
|
|
1542
|
+
def to_residue(remainder, divisor)
|
|
1543
|
+
When::Coordinates::Residue.new(remainder, divisor, {'day' => least_significant_coordinate,
|
|
1544
|
+
'year' => most_significant_coordinate})
|
|
1545
|
+
end
|
|
1546
|
+
|
|
1547
|
+
# 要素の参照
|
|
1548
|
+
#
|
|
1549
|
+
# @param [Integer, String] index 参照する要素の指定
|
|
1550
|
+
#
|
|
1551
|
+
# @return [Numeric]
|
|
1552
|
+
#
|
|
1553
|
+
def value(index)
|
|
1554
|
+
@cal_date[(_digit(index) {|digit| digit <= DAY})-1]
|
|
1555
|
+
end
|
|
1556
|
+
|
|
1557
|
+
#
|
|
1558
|
+
# 最上位の要素
|
|
1559
|
+
#
|
|
1560
|
+
# @return [Numeric] 暦年代の epoch に関わらず暦法に従った年の通し番号を返す
|
|
1561
|
+
#
|
|
1562
|
+
def most_significant_coordinate
|
|
1563
|
+
coordinate = @cal_date[0]
|
|
1564
|
+
coordinate += @calendar_era_name[1] if @calendar_era_name
|
|
1565
|
+
@frame.index_of_MSC.times do |i|
|
|
1566
|
+
coordinate = +coordinate * @frame.indices[i].unit + @cal_date[i+1] - @frame.indices[i].base
|
|
1567
|
+
end
|
|
1568
|
+
coordinate
|
|
1569
|
+
end
|
|
1570
|
+
|
|
1571
|
+
#
|
|
1572
|
+
# 最下位の要素
|
|
1573
|
+
#
|
|
1574
|
+
# @return [Numeric] 剰余類の演算に用いる日の通し番号を返す
|
|
1575
|
+
#
|
|
1576
|
+
def least_significant_coordinate
|
|
1577
|
+
return to_i + @frame.indices[-1].shift
|
|
1578
|
+
end
|
|
1579
|
+
|
|
1580
|
+
# ユリウス日または通年が指定の剰余となる日
|
|
1581
|
+
#
|
|
1582
|
+
# @param [When::Coordinates::Residue] other
|
|
1583
|
+
#
|
|
1584
|
+
# @return [When::TM::CalDate]
|
|
1585
|
+
#
|
|
1586
|
+
def &(other)
|
|
1587
|
+
raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
|
|
1588
|
+
case other.event
|
|
1589
|
+
when 'day'
|
|
1590
|
+
# 指定の剰余となる日
|
|
1591
|
+
sdn = other & to_i
|
|
1592
|
+
date = @frame.to_cal_date(sdn)
|
|
1593
|
+
date[0] -= @calendar_era_name[1] if @calendar_era_name
|
|
1594
|
+
result = self.dup._copy({:events=>nil, :query=>@query, :validate=>:done, :date=>date})
|
|
1595
|
+
result.send(:_force_euqal_day, sdn-result.to_i)
|
|
1596
|
+
|
|
1597
|
+
when 'year'
|
|
1598
|
+
# 指定の剰余となる年
|
|
1599
|
+
date = @cal_date.dup
|
|
1600
|
+
date[0] = (other & (most_significant_coordinate + @frame._diff_to_CE)) - @frame._diff_to_CE
|
|
1601
|
+
date[0] -= @calendar_era_name[1] if @calendar_era_name
|
|
1602
|
+
return self.dup._copy({:date=>date, :events=>nil, :query=>@query})
|
|
1603
|
+
|
|
1604
|
+
else
|
|
1605
|
+
raise ArgumentError,"The right operand should have a unit 'day' or 'year'"
|
|
1606
|
+
end
|
|
1607
|
+
end
|
|
1608
|
+
|
|
1609
|
+
# ユリウス日または通年の剰余
|
|
1610
|
+
#
|
|
1611
|
+
# @param [When::Coordinates::Residue] other
|
|
1612
|
+
#
|
|
1613
|
+
# @return [Numeric]
|
|
1614
|
+
#
|
|
1615
|
+
def %(other)
|
|
1616
|
+
raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
|
|
1617
|
+
if precision <= When::YEAR && other.units['year'] && other.event != 'year'
|
|
1618
|
+
other.to('year') % (most_significant_coordinate + @frame._diff_to_CE)
|
|
1619
|
+
else
|
|
1620
|
+
case other.event
|
|
1621
|
+
when 'day' ; other % least_significant_coordinate
|
|
1622
|
+
when 'year' ; other % (most_significant_coordinate + @frame._diff_to_CE)
|
|
1623
|
+
else ; raise ArgumentError,"The right operand should have a unit 'day' or 'year'"
|
|
1624
|
+
end
|
|
1625
|
+
end
|
|
1626
|
+
end
|
|
1627
|
+
|
|
1628
|
+
# 下位桁の切り捨て
|
|
1629
|
+
#
|
|
1630
|
+
# @param [Integer] digit 切り捨てずに残す、最下位の桁
|
|
1631
|
+
#
|
|
1632
|
+
# @param [Integer] precision 切り捨て結果の分解能
|
|
1633
|
+
#
|
|
1634
|
+
# @return [When::TM::CalDate]
|
|
1635
|
+
#
|
|
1636
|
+
def floor(digit=DAY, precision=digit)
|
|
1637
|
+
options = {:date=>@cal_date[0..(digit-1)], :events=>nil, :query=>nil}
|
|
1638
|
+
options[:precision] = precision if precision
|
|
1639
|
+
self.dup._copy(options)
|
|
1640
|
+
end
|
|
1641
|
+
|
|
1642
|
+
# 下位桁の切り上げ
|
|
1643
|
+
#
|
|
1644
|
+
# @param [Integer] digit 切り上げずに残す、最下位の桁
|
|
1645
|
+
#
|
|
1646
|
+
# @param [Integer] precision 切り上げ結果の分解能
|
|
1647
|
+
#
|
|
1648
|
+
# @return [When::TM::CalDate]
|
|
1649
|
+
#
|
|
1650
|
+
def ceil(digit=DAY, precision=digit)
|
|
1651
|
+
(self + PeriodDuration.new(1, digit, (-@frame.indices.length)..0)).floor(digit, precision)
|
|
1652
|
+
end
|
|
1653
|
+
|
|
1654
|
+
# 要素数 ― 上位要素に含まれる下位要素の数
|
|
1655
|
+
#
|
|
1656
|
+
# @param [Integer] upper 上位要素のインデックス
|
|
1657
|
+
# @param [Integer] lower 下位要素のインデックス(DAY または MONTH)
|
|
1658
|
+
#
|
|
1659
|
+
# @return [Integer]
|
|
1660
|
+
#
|
|
1661
|
+
def length(upper, lower=DAY)
|
|
1662
|
+
range = [floor(upper).to_i, ceil(upper).to_i]
|
|
1663
|
+
range = range.map {|d| (Residue.mod(d) {|m| frame._new_month(m)})[0]} if lower == MONTH
|
|
1664
|
+
range[1] - range[0]
|
|
1665
|
+
end
|
|
1666
|
+
|
|
1667
|
+
# 時刻情報のない When::TM::CalDate を返す
|
|
1668
|
+
#
|
|
1669
|
+
# @return [When::TM::CalDate]
|
|
1670
|
+
#
|
|
1671
|
+
alias :to_cal_date :dup
|
|
1672
|
+
alias :to_CalDate :to_cal_date
|
|
1673
|
+
|
|
1674
|
+
# 暦年代が末端の参照であるか?
|
|
1675
|
+
#
|
|
1676
|
+
# @return [Boolean]
|
|
1677
|
+
#
|
|
1678
|
+
def leaf?
|
|
1679
|
+
name, = @calendar_era_name
|
|
1680
|
+
return true unless name.respond_to?(:_pool)
|
|
1681
|
+
era = name._pool['..']
|
|
1682
|
+
return true unless era.respond_to?(:leaf?)
|
|
1683
|
+
return era.leaf?
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1686
|
+
# 属性の Hash
|
|
1687
|
+
# @private
|
|
1688
|
+
def _attr
|
|
1689
|
+
super.merge({:era_name=>@calendar_era_name, :era=>@calendar_era})
|
|
1690
|
+
end
|
|
1691
|
+
protected
|
|
1692
|
+
|
|
1693
|
+
# 属性のコピー
|
|
1694
|
+
# @private
|
|
1695
|
+
def _copy(options={})
|
|
1696
|
+
@cal_date = options[:date] if (options.key?(:date))
|
|
1697
|
+
return super
|
|
1698
|
+
end
|
|
1699
|
+
|
|
1700
|
+
# オブジェクトの生成
|
|
1701
|
+
#
|
|
1702
|
+
# @param [Array<Numeric>] date 日付表現
|
|
1703
|
+
#
|
|
1704
|
+
# @param [Hash] options 下記の通り (see also {When::TM::TemporalPosition._instance})
|
|
1705
|
+
# @option options [When::TM::Calendar] :frame
|
|
1706
|
+
# @option options [When::TM::CalendarEra, When::BasicTypes::M17n, Array<When::BasicTypes::M17n, Integer>] :era_name
|
|
1707
|
+
# (Integer は 当該年号の 0 年に相当する通年)
|
|
1708
|
+
# @option options [Integer] :precision
|
|
1709
|
+
#
|
|
1710
|
+
def initialize(date, options={})
|
|
1711
|
+
# 年号 & 日付
|
|
1712
|
+
@calendar_era_name = options[:era_name]
|
|
1713
|
+
@calendar_era = options[:era]
|
|
1714
|
+
@cal_date = date
|
|
1715
|
+
|
|
1716
|
+
super(options)
|
|
1717
|
+
end
|
|
1718
|
+
|
|
1719
|
+
private
|
|
1720
|
+
|
|
1721
|
+
# オブジェクトの正規化
|
|
1722
|
+
def _normalize(options={})
|
|
1723
|
+
|
|
1724
|
+
# 日付配列の長さ
|
|
1725
|
+
cal_date_index = @cal_date.index(nil) || @cal_date.length
|
|
1726
|
+
|
|
1727
|
+
# 日付の正規化
|
|
1728
|
+
if @calendar_era_name
|
|
1729
|
+
# Calendar Era がある場合
|
|
1730
|
+
trans_options = @trans || {} # TODO? 消す
|
|
1731
|
+
count = trans_options[:count] || 1
|
|
1732
|
+
query_options = (@query || {}).dup
|
|
1733
|
+
query_options[:label] = @calendar_era_name
|
|
1734
|
+
query_options[:count] = count
|
|
1735
|
+
era = date = nil
|
|
1736
|
+
if @calendar_era
|
|
1737
|
+
era, date = _search_era(@calendar_era, trans_options)
|
|
1738
|
+
else
|
|
1739
|
+
eras = CalendarEra._instance(query_options)
|
|
1740
|
+
raise ArgumentError, "CalendarEraName doesn't exist: #{query_options[:label]}" if (eras.size==0)
|
|
1741
|
+
eras.each do |e|
|
|
1742
|
+
era, date = _search_era(e, trans_options)
|
|
1743
|
+
next unless era
|
|
1744
|
+
count -= 1
|
|
1745
|
+
break unless count > 0
|
|
1746
|
+
end
|
|
1747
|
+
end
|
|
1748
|
+
raise RangeError, "Out of CalendarEra Range" unless era
|
|
1749
|
+
@calendar_era_name = date.calendar_era_name
|
|
1750
|
+
@calendar_era = era
|
|
1751
|
+
@cal_date = date.cal_date
|
|
1752
|
+
@frame = date.frame
|
|
1753
|
+
@query = (@query||{}).merge(date.query)
|
|
1754
|
+
@trans = (@trans||{}).merge(date.trans)
|
|
1755
|
+
@keys |= @calendar_era_name[0].keys | @frame.keys
|
|
1756
|
+
else
|
|
1757
|
+
# Calendar Era がない場合
|
|
1758
|
+
@frame = When.Resource(options[:frame] || @frame || 'Gregorian', '_c:')
|
|
1759
|
+
@cal_date = @frame._validate(@cal_date) unless options[:validate] == :done
|
|
1760
|
+
@keys |= @frame.keys
|
|
1761
|
+
end
|
|
1762
|
+
|
|
1763
|
+
# 分解能
|
|
1764
|
+
precision = options.delete(:precision) || @precision
|
|
1765
|
+
cal_date_index =
|
|
1766
|
+
case options.delete(:_format)
|
|
1767
|
+
when :century ; CENTURY
|
|
1768
|
+
when :week, :day ; DAY
|
|
1769
|
+
else ; cal_date_index - (@frame.indices.length + 1)
|
|
1770
|
+
end
|
|
1771
|
+
precision ||= cal_date_index if cal_date_index < DAY
|
|
1772
|
+
precision ||= @clk_time.precision if @clk_time
|
|
1773
|
+
@precision = Index.precision(precision || DAY)
|
|
1774
|
+
end
|
|
1775
|
+
|
|
1776
|
+
# 暦年代を探す
|
|
1777
|
+
def _search_era(era, trans_options)
|
|
1778
|
+
cal_date = @cal_date.dup
|
|
1779
|
+
cal_date[0] = -cal_date[0] if era.reverse?
|
|
1780
|
+
cal_date[0] += era.epoch_year
|
|
1781
|
+
date = era.trans(cal_date, trans_options)
|
|
1782
|
+
loop do
|
|
1783
|
+
case date
|
|
1784
|
+
when Before, After
|
|
1785
|
+
i0, i1, reverse = SearchOption[date]
|
|
1786
|
+
new_era = (date == Before) ? era.prev : era.succ
|
|
1787
|
+
break unless new_era
|
|
1788
|
+
date = new_era.trans(cal_date, trans_options)
|
|
1789
|
+
if date == reverse
|
|
1790
|
+
cal_date = new_era.epoch[i0].frame.to_cal_date(era.epoch[i1].frame.to_julian_date(cal_date))
|
|
1791
|
+
date = new_era.trans(cal_date, trans_options)
|
|
1792
|
+
break if date == reverse
|
|
1793
|
+
end
|
|
1794
|
+
era = new_era
|
|
1795
|
+
when TimeValue
|
|
1796
|
+
return era, date
|
|
1797
|
+
else
|
|
1798
|
+
break
|
|
1799
|
+
end
|
|
1800
|
+
end
|
|
1801
|
+
return nil
|
|
1802
|
+
end
|
|
1803
|
+
|
|
1804
|
+
# 加減算共通処理
|
|
1805
|
+
def _plus(period)
|
|
1806
|
+
_frame_adjust(period, self.dup._copy({:date=>_date_with_era(@frame._validate(_date_without_era,
|
|
1807
|
+
@frame._arrange_length(period.date))),
|
|
1808
|
+
:events=>nil, :query=>nil, :validate=>:done}))
|
|
1809
|
+
end
|
|
1810
|
+
|
|
1811
|
+
# 年号を除外した @frame の暦法に対応する日付
|
|
1812
|
+
def _date_without_era
|
|
1813
|
+
date = @cal_date.dup
|
|
1814
|
+
date[0] += @calendar_era_name[1] if @calendar_era_name
|
|
1815
|
+
date
|
|
1816
|
+
end
|
|
1817
|
+
|
|
1818
|
+
# 年号に続く日付
|
|
1819
|
+
def _date_with_era(date)
|
|
1820
|
+
date[0] -= @calendar_era_name[1] if @calendar_era_name
|
|
1821
|
+
date
|
|
1822
|
+
end
|
|
1823
|
+
|
|
1824
|
+
# 暦法が変わった場合の補正
|
|
1825
|
+
def _frame_adjust(period, date)
|
|
1826
|
+
return date if @frame.equal?(date.frame) || (period.to_day||0) == 0
|
|
1827
|
+
diff = period.to_day - (date.to_i - to_i)
|
|
1828
|
+
return date if diff == 0
|
|
1829
|
+
date.send(:_force_euqal_day, diff)
|
|
1830
|
+
end
|
|
1831
|
+
end
|
|
1832
|
+
|
|
1833
|
+
#
|
|
1834
|
+
# 時刻を伴った日付
|
|
1835
|
+
#
|
|
1836
|
+
# see {http://schemas.opengis.net/gml/3.1.1/base/temporalAppendix.xsd#DateAndTimeType gml schema}
|
|
1837
|
+
#
|
|
1838
|
+
class DateAndTime < CalDate
|
|
1839
|
+
|
|
1840
|
+
# 時刻要素
|
|
1841
|
+
#
|
|
1842
|
+
# @return [When::TM::ClockTime]
|
|
1843
|
+
#
|
|
1844
|
+
attr_reader :clk_time
|
|
1845
|
+
alias :clkTime :clk_time
|
|
1846
|
+
|
|
1847
|
+
# 時法の取得
|
|
1848
|
+
#
|
|
1849
|
+
# @return [When::TM::Clock]
|
|
1850
|
+
#
|
|
1851
|
+
def clock
|
|
1852
|
+
@clk_time.frame
|
|
1853
|
+
end
|
|
1854
|
+
|
|
1855
|
+
# 内部時間
|
|
1856
|
+
#
|
|
1857
|
+
# @return [Numeric]
|
|
1858
|
+
#
|
|
1859
|
+
# 1970-01-01T00:00:00Z からの Universal Coordinated Time の経過時間 / 128秒
|
|
1860
|
+
#
|
|
1861
|
+
# 暦法によっては、異なる意味を持つことがある
|
|
1862
|
+
#
|
|
1863
|
+
def universal_time
|
|
1864
|
+
return super if [Now, Max, Min].include?(@indeterminated_position)
|
|
1865
|
+
raise NameError, "Temporal Reference System is not defined" unless (@frame && clock)
|
|
1866
|
+
@universal_time ||= (to_i - JulianDate::JD19700101) * Duration::DAY + @clk_time.universal_time
|
|
1867
|
+
end
|
|
1868
|
+
|
|
1869
|
+
# 要素の参照
|
|
1870
|
+
#
|
|
1871
|
+
# @param [Integer] index 参照する要素の指定
|
|
1872
|
+
#
|
|
1873
|
+
# @return [Numeric]
|
|
1874
|
+
#
|
|
1875
|
+
def value(index)
|
|
1876
|
+
digit = _digit(index)
|
|
1877
|
+
return (digit <= DAY) ? @cal_date[digit-1] : @clk_time.clk_time[digit]
|
|
1878
|
+
end
|
|
1879
|
+
|
|
1880
|
+
# ユリウス日または通年が指定の剰余となる日
|
|
1881
|
+
#
|
|
1882
|
+
# @param [When::Coordinates::Residue] other
|
|
1883
|
+
#
|
|
1884
|
+
# @return [When::TM::DateAndTime]
|
|
1885
|
+
#
|
|
1886
|
+
def &(other)
|
|
1887
|
+
raise TypeError,"The right operand should be When::Coordinates::Residue" unless other.kind_of?(Residue)
|
|
1888
|
+
case other.event
|
|
1889
|
+
when 'day'
|
|
1890
|
+
# 指定の剰余となる日
|
|
1891
|
+
sdn = other & to_i
|
|
1892
|
+
result = self.dup._copy({:events=>nil, :query=>@query, :validate=>:done,
|
|
1893
|
+
:date=>_date_with_era(@frame.to_cal_date(sdn)),
|
|
1894
|
+
:time=>@clk_time.clk_time.dup})
|
|
1895
|
+
result.send(:_force_euqal_day, sdn-result.to_i)
|
|
1896
|
+
|
|
1897
|
+
when 'year'
|
|
1898
|
+
# 指定の剰余となる年
|
|
1899
|
+
date = @cal_date.dup
|
|
1900
|
+
date[0] = (other & (most_significant_coordinate + @frame._diff_to_CE)) - @frame._diff_to_CE
|
|
1901
|
+
return self.dup._copy({:events=>nil, :query=>@query,
|
|
1902
|
+
:date=>_date_with_era(date),
|
|
1903
|
+
:time=>@clk_time.clk_time.dup})
|
|
1904
|
+
|
|
1905
|
+
else
|
|
1906
|
+
raise ArgumentError,"The right operand should have a unit 'day' or 'year'"
|
|
1907
|
+
end
|
|
1908
|
+
end
|
|
1909
|
+
|
|
1910
|
+
# 下位桁の切り捨て
|
|
1911
|
+
#
|
|
1912
|
+
# @param [Integer] digit 切り捨てずに残す、最下位の桁
|
|
1913
|
+
#
|
|
1914
|
+
# @param [Integer] precision 切り捨て結果の分解能
|
|
1915
|
+
#
|
|
1916
|
+
# @return [When::TM::DateAndTime]
|
|
1917
|
+
#
|
|
1918
|
+
def floor(digit=DAY, precision=digit)
|
|
1919
|
+
count = digit - clock.indices.length
|
|
1920
|
+
date = (digit>=DAY) ? @cal_date.dup : @frame._validate(@cal_date[0..(digit-1)])
|
|
1921
|
+
time = @clk_time.clk_time[0..((digit<=DAY) ? 0 : ((count>=0) ? -1 : digit))]
|
|
1922
|
+
time[0] += to_i
|
|
1923
|
+
time = clock._validate(time)
|
|
1924
|
+
time[0] -= to_i
|
|
1925
|
+
|
|
1926
|
+
if (count >= 0)
|
|
1927
|
+
factor = 10**count
|
|
1928
|
+
time[-1] = (time[-1] * factor).floor.to_f / factor
|
|
1929
|
+
end
|
|
1930
|
+
|
|
1931
|
+
# オブジェクトの生成
|
|
1932
|
+
options = {:date=>date, :validate=>:done, :events=>nil, :query=>nil,
|
|
1933
|
+
:time=>(digit<=DAY) ? time : @clk_time.dup._copy({:time=>time})}
|
|
1934
|
+
options[:precision] = precision if precision
|
|
1935
|
+
return self.dup._copy(options)
|
|
1936
|
+
end
|
|
1937
|
+
|
|
1938
|
+
# 下位桁の切り上げ
|
|
1939
|
+
#
|
|
1940
|
+
# @param [Integer] digit 切り上げずに残す、最下位の桁
|
|
1941
|
+
#
|
|
1942
|
+
# @param [Integer] precision 切り上げ結果の分解能
|
|
1943
|
+
#
|
|
1944
|
+
# @return [When::TM::DateAndTime]
|
|
1945
|
+
#
|
|
1946
|
+
def ceil(digit=DAY, precision=digit)
|
|
1947
|
+
length = clock.indices.length
|
|
1948
|
+
count = digit - length
|
|
1949
|
+
period = PeriodDuration.new((count<=0) ? 1 : 0.1**count, digit, (-@frame.indices.length)..length)
|
|
1950
|
+
result = floor(digit, precision) + period
|
|
1951
|
+
result += clock.tz_difference if (result.universal_time <= self.universal_time)
|
|
1952
|
+
return result
|
|
1953
|
+
end
|
|
1954
|
+
|
|
1955
|
+
# 位置情報
|
|
1956
|
+
#
|
|
1957
|
+
# @return [When::Coordinates::Spatial]
|
|
1958
|
+
#
|
|
1959
|
+
def location
|
|
1960
|
+
@location ||= @clk_time.frame.location
|
|
1961
|
+
end
|
|
1962
|
+
|
|
1963
|
+
# 時刻情報のない When::TM::CalDate を返す
|
|
1964
|
+
#
|
|
1965
|
+
# @return [When::TM::CalDate]
|
|
1966
|
+
#
|
|
1967
|
+
def to_cal_date
|
|
1968
|
+
options = _attr
|
|
1969
|
+
options.delete(:clock)
|
|
1970
|
+
options[:precision] = [When::DAY, options[:precision]].min
|
|
1971
|
+
CalDate.new(@cal_date, options)
|
|
1972
|
+
end
|
|
1973
|
+
alias :to_CalDate :to_cal_date
|
|
1974
|
+
|
|
1975
|
+
#protected
|
|
1976
|
+
|
|
1977
|
+
# 属性の Hash
|
|
1978
|
+
# @private
|
|
1979
|
+
def _attr
|
|
1980
|
+
super.merge({:clock=>clock})
|
|
1981
|
+
end
|
|
1982
|
+
|
|
1983
|
+
# 属性のコピー
|
|
1984
|
+
# @private
|
|
1985
|
+
def _copy(options={})
|
|
1986
|
+
# 夏時間の調整
|
|
1987
|
+
case options[:time]
|
|
1988
|
+
when Array
|
|
1989
|
+
if clock._need_validate
|
|
1990
|
+
new_clock = clock._daylight([@frame, options[:date], options[:time]])
|
|
1991
|
+
options[:time] = options[:time].map {|t| t * 1}
|
|
1992
|
+
else
|
|
1993
|
+
new_clock = clock
|
|
1994
|
+
end
|
|
1995
|
+
options[:time] = @clk_time.dup._copy(options.merge({:clock=>new_clock}))
|
|
1996
|
+
when nil
|
|
1997
|
+
options[:time] = @clk_time.dup._copy(options)
|
|
1998
|
+
end
|
|
1999
|
+
|
|
2000
|
+
return super(options)
|
|
2001
|
+
end
|
|
2002
|
+
|
|
2003
|
+
# オブジェクトの生成
|
|
2004
|
+
#
|
|
2005
|
+
# @param [Array<Numeric>] date 日付表現
|
|
2006
|
+
# @param [Array<Numeric>] time 時刻表現
|
|
2007
|
+
# @param [Hash] options 下記の通り (see also {When::TM::TemporalPosition._instance})
|
|
2008
|
+
# @option options [When::TM::Calendar] :frame
|
|
2009
|
+
# @option options [When::TM::Clock] :clock
|
|
2010
|
+
# @option options [When::TM::CalendarEra, When::BasicTypes::M17n, Array<When::BasicTypes::M17n, Integer>] :era_name
|
|
2011
|
+
# (Integer は 当該年号の 0 年に相当する通年)
|
|
2012
|
+
# @option options [Integer] :precision
|
|
2013
|
+
#
|
|
2014
|
+
def initialize(date, time, options={})
|
|
2015
|
+
options[:time] = time
|
|
2016
|
+
super(date, options)
|
|
2017
|
+
end
|
|
2018
|
+
|
|
2019
|
+
private
|
|
2020
|
+
|
|
2021
|
+
# オブジェクトの正規化
|
|
2022
|
+
def _normalize(options={})
|
|
2023
|
+
|
|
2024
|
+
# Clock
|
|
2025
|
+
unless options[:validate]
|
|
2026
|
+
clock = Clock.get_clock_option(options)
|
|
2027
|
+
clock ||= options[:time].frame if options[:time].kind_of?(ClockTime)
|
|
2028
|
+
clock ||= Clock.local_time
|
|
2029
|
+
end
|
|
2030
|
+
clock = When.Clock(clock) if clock.kind_of?(String)
|
|
2031
|
+
clock_is_timezone = clock && !clock.kind_of?(When::TM::Clock)
|
|
2032
|
+
clock = clock.daylight if clock_is_timezone
|
|
2033
|
+
|
|
2034
|
+
# ClockTime
|
|
2035
|
+
@clk_time =
|
|
2036
|
+
case options[:time]
|
|
2037
|
+
when ClockTime ; options[:time]
|
|
2038
|
+
when Array ; ClockTime.new(options[:time], {:frame=>clock, :precision=>options[:precision], :validate=>:done})
|
|
2039
|
+
else ; clock.to_clk_time(options[:time], {:precision=>options[:precision]})
|
|
2040
|
+
end
|
|
2041
|
+
|
|
2042
|
+
super
|
|
2043
|
+
|
|
2044
|
+
# 日付と時刻の正規化
|
|
2045
|
+
unless options[:validate]
|
|
2046
|
+
time = @clk_time.clk_time
|
|
2047
|
+
precision = @clk_time.precision
|
|
2048
|
+
second = time[clock.base.length-1]
|
|
2049
|
+
second -= clock.base[-1] if second
|
|
2050
|
+
if second && second != 0 && time_standard.has_leap?
|
|
2051
|
+
zero = DateAndTime.new(@cal_date, time[0..-2],
|
|
2052
|
+
{:frame=>@frame, :clock=>clock, :precision=>precision,
|
|
2053
|
+
:era_name=>@calendar_era_name, :era=>options[:era],
|
|
2054
|
+
:time_standard=>time_standard, :location=>@location})
|
|
2055
|
+
end
|
|
2056
|
+
|
|
2057
|
+
# 日付と時刻の関係の調整
|
|
2058
|
+
@cal_date = _date_with_era(@frame._validate(_date_without_era) {|jdn|
|
|
2059
|
+
time[0] += jdn
|
|
2060
|
+
time[0..-1] = clock._validate(time)
|
|
2061
|
+
jdn = time[0] * 1
|
|
2062
|
+
time[0] -= jdn
|
|
2063
|
+
jdn
|
|
2064
|
+
})
|
|
2065
|
+
|
|
2066
|
+
# 夏時間の調整
|
|
2067
|
+
if clock._need_validate
|
|
2068
|
+
if @calendar_era_name
|
|
2069
|
+
cal_date = @cal_date.dup
|
|
2070
|
+
cal_date[0] += @calendar_era_name[1]
|
|
2071
|
+
else
|
|
2072
|
+
cal_date = @cal_date
|
|
2073
|
+
end
|
|
2074
|
+
clock = clock._daylight([@frame, cal_date, time])
|
|
2075
|
+
end
|
|
2076
|
+
time = [time[0]] + time[1..-1].map {|t| t * 1}
|
|
2077
|
+
@clk_time = ClockTime.new(time, {:frame=>clock, :precision=>precision, :validate=>:done}) if clock_is_timezone
|
|
2078
|
+
|
|
2079
|
+
# 閏秒
|
|
2080
|
+
if zero
|
|
2081
|
+
leap = ((dynamical_time - zero.dynamical_time) * clock.second - second).to_i
|
|
2082
|
+
if leap != 0 && leap.abs < clock.second
|
|
2083
|
+
@cal_date = zero.cal_date
|
|
2084
|
+
@clk_time = zero.clk_time
|
|
2085
|
+
@clk_time.clk_time[-1] += second
|
|
2086
|
+
leap /= clock.second
|
|
2087
|
+
@universal_time = When::Coordinates::LeapSeconds.new(@universal_time-leap, leap, 1/clock.second)
|
|
2088
|
+
@dynamical_time -= leap
|
|
2089
|
+
end
|
|
2090
|
+
end
|
|
2091
|
+
end
|
|
2092
|
+
|
|
2093
|
+
# 後処理
|
|
2094
|
+
@keys |= @clk_time.keys
|
|
2095
|
+
end
|
|
2096
|
+
|
|
2097
|
+
# 加減算共通処理
|
|
2098
|
+
def _plus(period)
|
|
2099
|
+
# 日時の加算
|
|
2100
|
+
time = @clk_time.clk_time.dup
|
|
2101
|
+
pdate = @frame._arrange_length(period.date)
|
|
2102
|
+
ptime = clock._arrange_length(period.time)
|
|
2103
|
+
date = _date_with_era(@frame._validate(_date_without_era, pdate) {|jdn|
|
|
2104
|
+
time[0] += jdn
|
|
2105
|
+
time = clock._validate(time, ptime)
|
|
2106
|
+
jdn = time[0] * 1
|
|
2107
|
+
time[0] -= jdn
|
|
2108
|
+
jdn
|
|
2109
|
+
})
|
|
2110
|
+
|
|
2111
|
+
# オブジェクトの生成
|
|
2112
|
+
_frame_adjust(period, self.dup._copy({:date=>date, :time=>time, :validate=>:done, :events=>nil, :query=>nil}))
|
|
2113
|
+
end
|
|
2114
|
+
end
|
|
2115
|
+
end
|