::Object
「時間位置」の基底クラス
see gml schema
Temporal Objetct の生成
* specification : When Standard Representation
* options : Hash
* :frame => 暦法の指定
* :clock => 時法の指定
* :abbreviation => ISO8601 上位省略形式のためのデフォルト日付(省略時 指定なし)
* :wkst => ISO8601 週日形式のための暦週開始曜日(省略時 'MO')
* :precision => 生成するオブジェクトの分解能
* :era_name => 暦年代の指定
* :trans => Hash
* :lower => 暦年代適用の下限
* true - epoch_of_use の始め(省略時)
* :reference_date - 参照事象の日付
* :upper => 暦年代適用の上限
* true - epoch_of_use の終わり(省略時)
* :reference_date - 参照事象の日付
* :count => 条件に合致する暦年代のうち何番目を採用するか
* :query => Hash
* :area => area による暦年代絞込み
* :period => period による暦年代絞込み
* (:name => name による暦年代絞込み(epoch の attribute使用可))
* :time_standard => 時刻系の指定(省略時 When::Ephemeris::UnversalTime)
* returns
* ISO8601 time point - When::TM::TemporalPosition
* ISO8601 duration - When::TM::Duration
* ISO8601 repeating interval - When::Parts::GeometricComplex
# File when/tmposition.rb, line 214
214: def _instance(specification, options={})
215:
216: # Suffix - Frame specification
217: rfc5545form, frame = specification.split(/\^{1,2}/, 2)
218: if (frame)
219: options[:frame] = When.IRI(frame, '_c:')
220: end
221:
222: # Prefix - RFC 5545 Options
223: if (rfc5545form =~ /^([^:]+[^-:\d]):(.+)$/)
224: rfc5545option, iso8601form = $~[1..2]
225: rfc5545option.split(/;/).each do |eq|
226: key, value = eq.split(/=/, 2)
227: case key
228: when 'VALUE' ; options[:precision] = value
229: when 'TZID' ; options[:clock] = When::V::Timezone[value].kind_of?(Array) ? When::V::Timezone[value][1] :
230: When::V::Timezone[value]
231: else ; options[key] = value
232: end
233: end
234: else
235: iso8601form = rfc5545form
236: end
237: options = options.dup
238:
239: # IndeterminateValue
240: if (iso8601form.sub!(/\/After$|^Before\/|^Now$|^Unknown$|^[-+]Infinity$/, ''))
241: options[:indeterminated_position] = S[$&.sub(/\//,'')]
242: case options[:indeterminated_position]
243: when Now,
244: Unknown,
245: Max,
246: Min
247: return self.new(self._options(options))
248: end
249: end
250:
251: # each specification
252: splitted = iso8601form.split(/\//)
253: if (splitted[0] =~ /^R(\d+)?$/)
254: repeat = $1 ? $1.to_i : true
255: splitted.shift
256: end
257: case splitted.length
258: when 1
259: when 2
260: if (splitted[0] !~ /^[-+]?P/ && splitted[1] =~ /^\d/ && splitted[1].length < splitted[0].length)
261: splitted[1] = splitted[0][0..(splitted[0].length-splitted[1].length-1)] + splitted[1]
262: end
263: else
264: raise ArgumentError, "Irregal ISO8601 Format: #{iso8601form}"
265: end
266: options = self._options(options)
267: element = splitted.map { |v| _date_time_or_duration(v, options.dup) }
268:
269: # total result
270: case repeat
271: when nil
272: case element[1]
273: when nil
274: return element[0]
275: when Duration
276: case element[0]
277: when Duration ; raise TypeError, "Duplicate Duration: #{element[0]} and #{element[1]}"
278: when self ; return When::Parts::GeometricComplex.new(*element)
279: else ; return When::Parts::GeometricComplex.new(element[0].first, element[1])
280: end
281: when self
282: case element[0]
283: when Duration ; return When::Parts::GeometricComplex.new([[element[1]-element[0],false], [element[1],true ]])
284: when self ; return When::Parts::GeometricComplex.new(element[0]..element[1])
285: else ; return When::Parts::GeometricComplex.new(element[0].first..element[1])
286: end
287: else
288: case element[0]
289: when Duration ; return When::Parts::GeometricComplex.new([[element[1].first-element[0],false],
290: [element[1].last-element[0]-1,true ]])
291: when self ; return When::Parts::GeometricComplex.new(element[0]...element[1].last)
292: else ; return When::Parts::GeometricComplex.new(element[0].first...element[1].last)
293: end
294: end
295: when 0 ; return []
296: when Integer ; return [element[0]] * repeat unless element[1]
297: end
298:
299: case element[1]
300: when Duration
301: case element[0]
302: when Duration ; raise TypeError, "Duplicate Duration: #{element[0]} and #{element[1]}"
303: else ; duration = element[1]
304: end
305: when self
306: case element[0]
307: when Duration ; duration = -element[0]
308: when self ; duration = element[1] - element[0]
309: else ; duration = element[1] - element[0].first
310: end
311: else
312: case element[0]
313: when Duration ; duration = -element[0]
314: when self ; duration = element[1].first - element[0]
315: else ; duration = element[1].first - element[0].first
316: end
317: end
318: base = element[0].kind_of?(Duration) ? element[1] : element[0]
319:
320: if repeat.kind_of?(Integer)
321: result = case base
322: when self ; (1..repeat-1).inject([base]) {|a,i| a << (a[1] + duration) }
323: else ; (1..repeat-1).inject([base]) {|a,i| a << When::Parts::GeometricComplex.new(
324: a[1].first+duration...a[1].last+duration)}
325: end
326: result.reverse! if duration.sign < 0
327: return result
328:
329: else
330: duration = -duration if duration.sign < 0
331: return case base
332: when self ; When::V::Event.new({'rrule'=>{'FREQ'=>duration}, 'dtstart'=>base})
333: else ; When::V::Event.new({'rrule'=>{'FREQ'=>duration}, 'dtstart'=>base.first,
334: 'dtend' =>base.last})
335: end
336: end
337: end
When::TM::TemporalPosition Class のグローバルな設定を行う
format : Hash
strftime で用いる記号の定義
format の指定がない場合、format は Format(モジュール定数)と解釈する
# File when/region/m17n.rb, line 42
42: def setup(format=nil)
43: @format = format ? Format.merge(format) : Format
44: end
加算
other : Numeric or When::TM::IntervalLength returns : When::TM::TemporalPosition
# File when/tmposition.rb, line 502
502: def +(other)
503: case other
504: when Numeric, IntervalLength ; @frame.jul_trans(JulianDate.dynamical_time(dynamical_time + +other), self._attr)
505: when PeriodDuration ; _plus(other)
506: else ; raise TypeError, "The right operand should be Duration"
507: end
508: end
ユリウス日時(実数)
returns : Float dynamical time での経過日数を, ユリウス日と1970-01-01T00:00:00TTで時計あわせしたもの
# File when/tmposition.rb, line 480
480: def +@
481: dynamical_time / IntervalLength::DAY + JulianDate::JD19700101 - 0.5
482: end
減算
other : When::TM::(Temporal)Position, Numeric or When::TM::IntervalLength
returns : When::TM::TemporalPosition if other is a Numeric or When::TM::IntervalLength
When::TM::IntervalLength if other is a When::TM::TemporalPosition
# File when/tmposition.rb, line 517
517: def -(other)
518: case other
519: when TemporalPosition, Position ; [@precision, other.precision].min > When::Coordinates::DAY ?
520: IntervalLength.new(self.dynamical_time - other.dynamical_time) :
521: IntervalLength.new(self.to_i - other.to_i, 'day')
522: when Numeric, IntervalLength ; @frame.jul_trans(JulianDate.dynamical_time(dynamical_time - +other), self._attr)
523: when PeriodDuration ; _plus(-other)
524: else ; raise TypeError, "The right operand should be Duration or (Temporal)Position"
525: end
526: end
大小比較
returns : Integer(-1, 0, 1)
分解能の低い方にあわせて比較を行う
Ex. when?('2011-03') <=> when?('2011-03-10') ---> 0
# File when/tmposition.rb, line 590
590: def <=>(other)
591: other = other.first if other.kind_of?(When::Parts::GeometricComplex)
592: [self.indeterminated_position, other.indeterminated_position].each do |position|
593: prec = SYSTEM if [IndeterminateValue::Min, IndeterminateValue::Max].include?(position)
594: end
595: prec = [self.precision, other.precision].min unless prec
596: case prec
597: when DAY ; return self.to_i <=> other.to_i
598: when SYSTEM ; src, dst = self, other
599: else ; src, dst =
600: [(prec >= self.precision ) ? self : self.floor(prec),
601: (prec >= other.precision) ? other : other.floor(prec)]
602: end
603: return src.to_i <=> dst.to_i if prec <= DAY
604: return src.universal_time <=> dst.universal_time if src.time_standard.equal?(dst.time_standard)
605: return src.dynamical_time <=> dst.dynamical_time
606: end
要素の参照
index : Integer or String of When::Coordinates::PRECISION
参照する要素の指定
returns : Numeric
# File when/tmposition.rb, line 491
491: def [](index)
492: return value(index) if index.kind_of?(String) || !index.respond_to?(:inject)
493: index.inject([]) {|list, i| list << value(i) }
494: end
条件を満たすオブジェクトの抽出
other : Module, When::Coordinates::Residue,
When::TM::Duration, When::TM::Calendar, When::TM::CalendarEra
block : If block is given, the specified block is yield.
returns : The following objects are returned if other is a ...
Module : Array of (element^self) for all When::Parts::IRI registered elements
Array : Array of (self^element) for elemnt of other which belong to the specified module or class.
When::TM::Duration : Enumerator which generates temporal position sequence begins from self with the specified duration.
When::TM::Calendar : Array of temporal position using the specified calendar as a frame.
When::TM::CalendarEra : Array of temporal position using the specified calendar era as a calendarEraName. If the specified calendar era has hierarchies , these all hierarchies are applied.
# File when/tmposition.rb, line 624
624: def ^(other, &block)
625: list = []
626: case other
627: when Numeric, TemporalPosition, Position
628: raise TypeError, "Operand should not be Numeric or (Temporal)Position"
629:
630: when Module
631: objects = []
632: ObjectSpace.each_object(other) do |object|
633: objects << object if object.registered?
634: end
635: objects.each do |object|
636: element = (object ^ self)
637: if element
638: list << element
639: yield(element) if block_given?
640: end
641: end
642: return list
643:
644: when Array
645: return other.map {|v| self.^(v, &block)}
646:
647: else
648: if other.respond_to?(:_enumerator)
649: enumerator = other._enumerator(self)
650: return enumerator unless block_given?
651: return enumerator.each(&block)
652: end
653:
654: element = (other ^ self)
655: if element
656: list << element
657: yield(element) if block_given?
658: end
659: if (other.respond_to?(:child) && other.child)
660: other.child.each do |object|
661: list += self.^(object, &block)
662: end
663: end
664: return list
665: end
666: end
外部時間
returns : Numeric 1970-01-01T00:00:00TT からの terrestrial time の経過時間 / 128秒
# File when/tmposition.rb, line 464
464: def dynamical_time
465: return @dynamical_time if @dynamical_time && @indeterminated_position != Now
466: @dynamical_time =
467: case @indeterminated_position
468: when Max ; +Float::MAX/4
469: when Min ; -Float::MAX/4
470: else ; @time_standard.to_dynamical_time(universal_time)
471: end
472: end
下位桁の切り捨て
digit : Integer
これより下の桁を切り捨てる(省略すると When::Coordinates::DAY)
precision : Integer (Enumerated in the When::Coordinates Module)
切り捨て結果の分解能(省略すると切り捨てずに残した最下位の桁)
returns : When::TM::TemporalPosition(本 Class では、実際には切り捨てない)
# File when/tmposition.rb, line 570
570: def floor(digit=DAY, precision=digit)
571: self
572: end
分解能が時刻を持つか
type : Boolean
# File when/tmposition.rb, line 578
578: def has_time?
579: (@precision > 0)
580: end
所属する月
ord : 月の番号 (default: 今月)
今月を 0 とする月番号(Integer) または月番号の範囲(Range)
-1 - 先月
0 - 今月
+1 - 来月
wkst : 週の開始曜日(default: なし)
returns : 月の情報
ブロックなし - 所属する月を範囲として表現する Range
ブロックあり
wkst なし - 所属する月の各日をブロックに渡した結果の Array
wkst あり - 所属する月の各日をブロックに渡した結果の七曜表
# File when/region/m17n.rb, line 161
161: def month(*args, &block)
162: first, length, wkst = _range(args)
163: if wkst
164: (first...(first+length)).map {|i|
165: begun = self.floor(MONTH,DAY) + When::TM::PeriodDuration.new([0,i,0])
166: ended = begun + When::TM::PeriodDuration.new([0,1,0])
167: ended = ended.prev
168: dates = [begun]
169: loop do
170: current = dates[1].week(wkst)
171: if current.include?(ended)
172: dates[1] = ended
173: break (dates.map {|date| date.week(wkst, &block)}).unshift(yield(begun, MONTH)).compact
174: else
175: dates << dates[1] + When::TM::PeriodDuration.new([0,0,7])
176: end
177: end
178: }
179: else
180: begun = self.floor(MONTH,DAY) + When::TM::PeriodDuration.new([0, first, 0])
181: ended = begun + When::TM::PeriodDuration.new([0, length, 0])
182: if block_given?
183: (begun...ended).map do |date|
184: yield(date)
185: end
186: else
187: When::Parts::GeometricComplex.new(begun...ended)
188: end
189: end
190: end
次の日時
returns : When::TM::TemporalPosition 分解能に対応する Duration だけ,日時を進める
# File when/tmposition.rb, line 555
555: def next
556: self + period
557: end
分解能に対応する Duration
returns : When::TM::PeriodDuration
# File when/tmposition.rb, line 532
532: def period
533: return @period if @period
534: period_name = When::Coordinates::PERIOD_NAME[@precision]
535: raise ArgumentError, "Presicion not defined" unless period_name
536: @period = When.Duration(period_name)
537: end
前の日時
returns : When::TM::TemporalPosition 分解能に対応する Duration だけ,日時を戻す
# File when/tmposition.rb, line 545
545: def prev
546: self - period
547: end
指定の書式による多言語対応文字列化
pattern : When::BasicTypes::M17n
書式
locale : [String]
文字列化を行う locale の指定(デフォルト : すべて)
returns : When::BasicTypes::M17n
pattern で指定した書式で多言語対応文字列化する
# File when/region/m17n.rb, line 58
58: def strftime(pattern, locale=nil)
59: pattern = m17n([pattern]*self.keys.length, {:locale=>self.keys}) if pattern.instance_of?(String)
60: pattern._printf([], locale) do |k, *t|
61: _strftime(k, pattern, [''])
62: end
63: end
strftime で扱う項の値を取得する
designator : String
項目名
locale : String
文字列化を行う場合の locale の指定
d : Integer
日付が'年月日'、時刻が'時分秒'でない表現のための桁位置変更指示
年月に付く場合 - 大きいほうに位置をずらす
分秒に付く場合 - 小さいほうに位置をずらす
returns : designator に依存
# File when/region/m17n.rb, line 78
78: def term(designator, locale=nil, d=0, e=3)
79: case designator
80: # 現在のロケールにおける曜日の省略名
81: when 'a' ; (When.IRI('_co:CommonResidue::Week')[to_i % 7].label/locale)[/^.{1,#{e}}/]
82: # 現在のロケールにおける曜日の完全な名前
83: when 'A' ; (When.IRI('_co:CommonResidue::Week')[to_i % 7].label/locale)
84: when 'b' ; (name(MONTH-d)/locale)[/^.{1,#{e}}/] # 現在のロケールにおける月の省略名
85: when 'B' ; (name(MONTH-d)/locale) # 現在のロケールにおける月の完全な名前
86: when 'c' ; to_m17n/locale # 現在のロケールにおいて一般的な日付・時刻の表記
87: when 'C' ; self[YEAR-d].to_i.div(100) # 世紀 (西暦年の上 2 桁)
88: when 'd' ; (floor(DAY) - floor(MONTH-d)).day + 1 # 月内通算日
89: when 'E' ; Array(calendar_era_name)[0]/locale # 年号
90: when 'F' ; floor(DAY).to_m17n/locale # ISO 8601 形式の日付フォーマット
91: # ISO 8601 週単位表記の年
92: when 'G' ; ((floor(YEAR-d,DAY) + 4*IntervalLength::DAY) & Residue.new(0,7,1))[YEAR-d]
93: # ISO 8601 週単位表記の年の下2桁
94: when 'g' ; ((floor(YEAR-d,DAY) + 4*IntervalLength::DAY) & Residue.new(0,7,1))[YEAR-d] % 100
95: when 'H' ; self[HOUR] # 24 時間表記での時
96: when 'I' ; (self[HOUR]-1) % 12 + 1 # 12 時間表記での時
97: when 'j' ; (floor(DAY) - floor(YEAR-d)).day + 1 # 年の初めから通算の日数
98: when 'm' ; self[MONTH-d] # 月
99: when 'M' ; self[MINUTE+d] # 分
100: when 'p' ; (AMPM[self[HOUR].to_i.div(12)]/locale).upcase # 現在のロケールにおける「午前」「午後」に相当する文字列
101: when 'P' ; (AMPM[self[HOUR].to_i.div(12)]/locale).downcase # 前項を小文字で表記
102: when 's' ; universal_time / IntervalLength::SECOND # 紀元 (1970-01-01T00:00:00Z) からの秒数
103: when 'S' ; self[SECOND+d] # 秒 (10 進数表記)
104: when 'u' ; (to_i % 7) + 1 # 週の何番目の日か(月曜日を 1 とする)
105: # 年の初めからの通算の週番号(日曜日始まり)
106: when 'U' ; (floor(DAY) - (floor(YEAR-d,DAY) & Residue.new(6,7))).week.floor + 1
107: # ISO 8601 形式での年の始めからの週番号
108: when 'V' ; (floor(DAY) - ((floor(YEAR-d,DAY) + 4*IntervalLength::DAY) & Residue.new(0,7,1))).week.floor + 1
109: when 'w' ; (to_i + 1) % 7 # 週の何番目の日 か(日曜日を 0 とする)
110: # 年の初めからの通算の週番号(月曜日始まり)
111: when 'W' ; (floor(DAY) - (floor(YEAR-d,DAY) & Residue.new(0,7))).week.floor + 1
112: when 'X' ; clk_time._time_to_s # 現在のロケールで一般的な時刻表記
113: when 'y' ; self[YEAR-d] % 100 # 西暦の下2桁 (世紀部分を含まない年)
114: when 'Y' ; self[YEAR-d] # 世紀部分を含めた ( 4 桁の) 西暦年
115: when 'z' ; clock.to_basic # +hhmm や -hhmm の形式のタイムゾーン
116: when 'Z' ; clock.tzname/locale # タイムゾーンまたはゾーン名または省略名
117: else ; raise ArgumentError, "Invalid designator"
118: end
119: end
ユリウス日時(実数)
returns : Float universal time での経過日数を, ユリウス日と1970-01-01T00:00:00Zで時計あわせしたもの
# File when/tmposition.rb, line 454
454: def to_f
455: universal_time / IntervalLength::DAY + JulianDate::JD19700101 - 0.5
456: end
ユリウス日(整数)
returns : Integer -4712-01-01T12:00:00Z からの経過日数に対応する通番(当該時間帯での午前0時に1進める)
# File when/tmposition.rb, line 441
441: def to_i
442: sd = universal_time
443: sd -= @frame.universal_time if @frame.kind_of?(Clock)
444: div, mod = sd.divmod(IntervalLength::DAY)
445: div + JulianDate::JD19700101
446: end
多言語対応文字列化
returns : When::BasicTypes::M17n When Standard Representation により多言語対応文字列化する
# File when/tmposition.rb, line 674
674: def to_m17n(*args)
675: return m17n(I[@indeterminated_position]) if [Unknown, Max, Min].include?(@indeterminated_position)
676: return m17n(_to_s)
677: end
文字列化
returns : String When Standard Representation により文字列化する
# File when/tmposition.rb, line 688
688: def to_s(*args)
689: to_m17n(*args).to_s
690: end
内部時間
returns : Numeric 1970-01-01T00:00:00Z からの Universal Time, Coordinated の経過時間 / 128秒 暦法によっては、異なる意味を持つことがある
# File when/tmposition.rb, line 426
426: def universal_time
427: case @indeterminated_position
428: when Now ; @time_standard.now
429: when Max ; +Float::MAX/4
430: when Min ; -Float::MAX/4
431: else ; raise NameError, "Temporal Reference System is not defined"
432: end
433: end
所属する週
ord : 週の番号 (default: 今週)
今週を 0 とする週番号(Integer) または週番号の範囲(Range)
-1 - 先週
0 - 今週
+1 - 来週
wkst : 週の開始曜日(default: 月曜)
returns : 週の情報
ブロックなし - 所属する週を範囲として表現する Range
ブロックあり - 所属する週の各日をブロックに渡した結果の Array
# File when/region/m17n.rb, line 134
134: def week(*args)
135: first, length, wkst = _range(args)
136: wkst ||= 'MO'
137: wkst = When::Coordinates::Residue.day_of_week(wkst) if wkst.kind_of?(String)
138: begun = self.floor.succ & When::Coordinates::Residue.new(wkst, 7, first-1)
139: ended = begun + When::TM::PeriodDuration.new([0,0,length * 7])
140: return When::Parts::GeometricComplex.new(begun...ended) unless block_given?
141: ((begun...ended).map { |date|
142: yield(date, self)
143: }).unshift(yield(begun, WEEK)).compact
144: end
所属する年
ord : 年の番号 (default: 今年)
今月を 0 とする年番号(Integer) または年番号の範囲(Range)
-1 - 昨年
0 - 今年
+1 - 来年
wkst : 週の開始曜日(default: なし)
returns : 年の情報
ブロックなし - 所属する年を範囲として表現する Range
ブロックあり
wkst なし - 所属する年の各日をブロックに渡した結果の Array
wkst あり - 所属する年の各日をブロックに渡した結果の七曜表
# File when/region/m17n.rb, line 207
207: def year(*args, &block)
208: first, length, wkst = _range(args)
209: if wkst
210: (first...(first+length)).map {|i|
211: begun = self.floor(YEAR,DAY) + When::TM::PeriodDuration.new([i,0,0])
212: ended = begun + When::TM::PeriodDuration.new([1,0,0])
213: current = begun
214: result = [yield(begun, YEAR)]
215: while current < ended do
216: result << current.month(wkst, &block)
217: current += When::TM::PeriodDuration.new([0,1,0])
218: end
219: result.compact
220: }
221: else
222: begun = self.floor(YEAR,DAY) + When::TM::PeriodDuration.new([first, 0, 0])
223: ended = begun + When::TM::PeriodDuration.new([length, 0, 0])
224: if block_given?
225: (begun...ended).map do |date|
226: yield(date)
227: end
228: else
229: When::Parts::GeometricComplex.new(begun...ended)
230: end
231: end
232: end
その他のメソッド
When::TM::TemporalPosition で定義されていないメソッドは 処理を @frame (type: When::TM::Calendar or When::TM::Clock) に委譲する
# File when/tmposition.rb, line 752
752: def method_missing(name, *args, &block)
753: @frame.send(name.to_sym, self, *args, &block)
754: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.