Module: When

Included in:
TM::CalendarEra, TM::PeriodDuration, TM::TemporalPosition, TM::TemporalPosition, V::Event::Enumerator
Defined in:
lib/when_exe.rb,
lib/when_exe/inspect.rb,
lib/when_exe/version.rb,
lib/when_exe/basictypes.rb,
lib/when_exe/region/sun.rb,
lib/when_exe/tmduration.rb,
lib/when_exe/region/m17n.rb,
lib/when_exe/region/moon.rb,
lib/when_exe/region/pope.rb,
lib/when_exe/region/thai.rb,
lib/when_exe/region/bahai.rb,
lib/when_exe/region/mayan.rb,
lib/when_exe/region/roman.rb,
lib/when_exe/region/shire.rb,
lib/when_exe/region/world.rb,
lib/when_exe/region/french.rb,
lib/when_exe/region/indian.rb,
lib/when_exe/region/jewish.rb,
lib/when_exe/region/korean.rb,
lib/when_exe/region/ryukyu.rb,
lib/when_exe/region/chinese.rb,
lib/when_exe/region/iranian.rb,
lib/when_exe/region/islamic.rb,
lib/when_exe/region/martian.rb,
lib/when_exe/region/planets.rb,
lib/when_exe/region/tibetan.rb,
lib/when_exe/region/balinese.rb,
lib/when_exe/region/far_east.rb,
lib/when_exe/region/japanese.rb,
lib/when_exe/region/javanese.rb,
lib/when_exe/mini_application.rb,
lib/when_exe/region/christian.rb,
lib/when_exe/region/vietnamese.rb,
lib/when_exe/region/chinese_epoch.rb,
lib/when_exe/region/chinese_calendar.rb

Overview

ベトナム王位年号一覧表

(参考文献) コンサイス世界年表(三省堂) 歴代紀元編(台湾中華書局)

Defined Under Namespace

Modules: BasicTypes, CalendarTypes, Coordinates, EX, Ephemeris, Parts, RS, TM, TimeStandard, V

Constant Summary collapse

SourceURI =
"http://hosi.org/When/"
DurationP1D =

Module Constants

TM::PeriodDuration.new([0,0,1])
DurationP1W =
TM::PeriodDuration.new([0,0,7])
DurationP1M =
TM::PeriodDuration.new([0,1,0])
DurationP1Y =
TM::PeriodDuration.new([1,0,0])
TimeValue =
TM::IndeterminateValue
PlusInfinity =
TM::TemporalPosition.new({:indeterminated_position=>TimeValue::Max})
MinusInfinity =
TM::TemporalPosition.new({:indeterminated_position=>TimeValue::Min})
UTF8 =
'.UTF-8'
W31J =
'.Windows-31J'
EUCJP =
'.eucJP'
VERSION =
"0.3.4"
CENTURY =

分解能定数

-4
DECADE =
-3
YEAR =
-2
MONTH =
-1
WEEK =
-0.5
DAY =
0
HOUR =
1
MINUTE =
2
SECOND =
3
STRING =
5
SYSTEM =
(Float::MANT_DIG*0.3).to_i

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.multi_threadBoolean (readonly)

マルチスレッド対応の場合 true


45
46
47
# File 'lib/when_exe.rb', line 45

def multi_thread
  @multi_thread
end

Class Method Details

._setup_(options = {}) ⇒ void

Note:

本メソッドでマルチスレッド対応の管理変数の初期化を行っている。 このため、本メソッド自体および本メソッドから呼んでいる各クラスの setup メソッドはスレッドセーフでない。

This method returns an undefined value.

Initializations

Options Hash (options):

  • :local (When::TM::Clock, When::V::Timezone, When::Parts::Timezone)

    デフォルトの地方時

  • :location (When::Coordinates::Spatial)

    デフォルトの空間位置

  • :until (When::TM::IntervalLength)

    V::Event::Enumerator の until

  • :alias (Hash{String=>String})

    Locale の読替パターン ({ 読替前のlocale=>読替後のlocale })

  • :unification (Hash{String=>String})

    漢字の包摂パターン ({ 包摂前の文字列=>包摂後の文字列 })

  • :order (Array<String>)

    CalendarEra の検索順序 ([ IRI of When::TM::CalendarEra ])

  • :format (Hash{String=>Array, String})

    strftime で用いる記号の定義 ({ 記号=>[ 書式,項目名 ] or 記号列 })

  • :leap_seconds (Array<Array>)

    閏秒の挿入記録 ([ [JD, TAI-UTC, (MJD, OFFSET)] ])

  • :multi_thread (Boolean)

    マルチスレッド対応 (true: 対応, false/nil: 非対応)

  • :direct (Boolean)

    '_' で終わるメソッドをキャッシュせずに毎回計算するか否か

  • :escape (Hash{Symbol=>boolean})

    毎回 method_missing を発生させるメソッドを true にする


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/when_exe.rb', line 68

def _setup_(options={})
  @multi_thread = options[:multi_thread]
  Parts::MethodCash._setup_(options[:direct], options[:escape])
  Parts::Resource._setup_
  Parts::Locale._setup_(options)
  Coordinates::Spatial._setup_(options[:location])
  TM::CalendarEra._setup_(options[:order])
  TM::Calendar._setup_
  TM::Clock._setup_(options[:local])
  TM::TemporalPosition._setup_(options[:format])
  V::Event._setup_(options[:until])
  V::Timezone._setup_
  Parts::Timezone._setup_
  TimeStandard._setup_(options[:leap_seconds])
end

.at(time, options = {}) ⇒ When::TM::DateAndTime

指定日時に対応する When::TM::TemporalPosition の生成 (When::TM::DateAndTime of specified Time)


419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/when_exe.rb', line 419

def at(time, options={})
  options = options._attr if options.kind_of?(TM::TemporalPosition)
  options[:frame] ||= 'Gregorian'
  options[:frame]   = Resource(options[:frame], '_c:') if options[:frame].kind_of?(String)
  options[:clock] ||= Clock(time.utc_offset) if time.kind_of?(::Time)
  jdt  = TM::JulianDate.universal_time(time.to_f * TM::IntervalLength::SECOND, {:frame=>TM::Clock.get_clock(options)})
  options[:clock]   = jdt.frame
  date = options[:frame].jul_trans(jdt, options)
  date = TM::CalDate.new(date.cal_date, options) if options[:precision] &&
                                                    options[:precision] <= DAY
  return date
end

.Calendar(calendar) ⇒ When::TM::Calendar

When::TM::Calendar の生成/参照


511
512
513
# File 'lib/when_exe.rb', line 511

def Calendar(calendar)
  Parts::Resource._instance(calendar, '_c:')
end

.CalendarEra(era) ⇒ When::TM::CalendarEra

When::TM::CalendarEra の生成/参照


531
532
533
# File 'lib/when_exe.rb', line 531

def CalendarEra(era)
  Parts::Resource._instance(era, '_e:')
end

.CalendarNote(notes) ⇒ When::CalendarTypes::CalendarNote

When::CalendarTypes::CalendarNote の生成/参照


521
522
523
# File 'lib/when_exe.rb', line 521

def CalendarNote(notes)
  Parts::Resource._instance(notes, '_n:')
end

.client(server, port, query) ⇒ JSON

Note:

mini_application

マイクロ・クライアントを実行する


96
97
98
99
100
101
102
103
# File 'lib/when_exe/mini_application.rb', line 96

def client(server, port, query)
  TCPSocket.open(server, port.to_i) do |socket|
    socket.puts(query)
    results = JSON.parse(socket.gets.force_encoding("UTF-8"))
    results = Hash[*results.flatten(1)] if results[0].kind_of?(Array)
    _to_symbol(results)
  end
end

.Clock(clock) ⇒ When::TM::Clock

When::TM::Clock の生成/参照


563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
# File 'lib/when_exe.rb', line 563

def Clock(clock)
  case clock
  when TM::Clock ; return clock
  when 'Z'       ; return utc
  when /^#{CalendarTypes::TimeSystems}/ ; return Parts::Resource._instance('_c:' + clock)
  when Numeric   ; return utc if clock==0
  when String
    c = TM::Clock[clock] || V::Timezone[clock]
    return c if c
    clock, options = clock.split('?')
  else           ; raise TypeError, "Invalid Type: #{clock.class}"
  end
  iri  = "_tm:Clock?label=" + TM::Clock.to_hms(clock)
  iri += "&" + options if options
  Parts::Resource._instance(iri)
end

.config(path = File.expand_path($0) + '.config') ⇒ Object

設定ファイルを読み込む


32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/when_exe/mini_application.rb', line 32

def config(path=File.expand_path($0) + '.config')
  config = {}
  open(path, 'r') do |file|
    while (line=file.gets)
      next if line =~ /^\s*#/
      key, *value = line.chomp.split(':')
      value = value[0] if value.size <= 1
      config[key] = value
    end
  end
  config
rescue
  {}
end

.Duration(period, options = {}) ⇒ When::TM::Duration or Array<them>

When::TM::Duration の生成


469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
# File 'lib/when_exe.rb', line 469

def Duration(period, options={})
  case period
  when Array
    period.map {|e| Duration(e, options)}

  when TM::Duration
    period

  when 0
    TM::IntervalLength.new(0, 'day')

  when Numeric
    [TM::Duration::YEAR, TM::Duration::MONTH,  TM::Duration::WEEK, TM::Duration::DAY,
     TM::Duration::HOUR, TM::Duration::MINUTE, TM::Duration::SECOND].each do |unit|
      div, mod = period.divmod(unit)
      return TM::IntervalLength.new(div, TM::Duration::Unit.invert[unit]) if mod == 0
    end
    TM::IntervalLength.new(period, 'system')

  when String
    # IntervalLength
    args = TM::IntervalLength._to_array(period)
    return TM::IntervalLength.new(*args) if args

    # PeriodDuration
    sign, *args = TM::PeriodDuration._to_array(period)
    raise TypeError, "Argument 'period' is not a Duration" unless (sign)
    args << options
    duration = TM::PeriodDuration.new(*args)
    return (sign >= 0) ? duration : -duration

  else
    nil
  end
end

.era(key, epoch = nil, reverse = nil, options = {}) ⇒ Array<When::TM::CalendarEra>

Note:

ヒット数が不足している場合は、setup で指定した順序で When::TM::CalendarEra オブジェクトを生成しつつ読み込んで検索する。

When::TM::CalendarEra の検索

Options Hash (options):

  • :area (String)

    暦年代の使用地域の指定(デフォルトは nil - 指定なし)

  • :period (String)

    暦年代の使用時代の指定(デフォルトは nil - 指定なし)

  • :count (Integer)

    何件ヒットするまで検索するかを指定(デフォルトは 1件)

  • the_others (String)

    例えば When::TM::CalendarEra オブジェクトの epoch_of_use に 'name' などの 指定がある場合、:name に指定しておけば、検索での絞り込みに使用できる。


551
552
553
# File 'lib/when_exe.rb', line 551

def era(*args)
  TM::CalendarEra._instance(*args)
end

.free_conv(*args, &block) ⇒ Array<Hash>, Array<Array<Numeric>>

Note:

暦法のIRI, When.exe Standard Expression, 最良近似分数列の分母分子などを文字列で指定

Note:

mini_application

日付の自由変換


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/when_exe/mini_application.rb', line 116

def free_conv(*args, &block)
  calendars, dates, numbers, methods, output, options = _parse_command(args)

  if numbers.size >= 2 && calendars.size == 0
    result = []
    When::Coordinates::Residue.new(numbers[0], numbers[1]).each { |v| result << v }
    return result
  end

  block ||= 
    if methods.size == 0
      lambda {|date| date.send(*output)}
    else
      lambda {|date, type|
        case type
        when When::YEAR  ; date.strftime("%Y")
        when When::MONTH ; date.strftime("%B %Y")
        when When::WEEK  ; nil
        when When::DAY   ; date[0]
        else             ; '-'
        end
      }
    end
  _free_conv(calendars, dates, methods, output, options, &block)
end

.m17n(source, namespace = nil, locale = nil, options = {}) ⇒ When::BasicTypes::M17n or Array<them>

When::BasicTypes::M17n の生成/参照


637
638
639
640
641
642
643
644
645
646
647
# File 'lib/when_exe.rb', line 637

def m17n(source, namespace=nil, locale=nil, options={})
  case source
  when Array            ; BasicTypes::M17n.new(source, namespace, locale, options)
  when BasicTypes::M17n ; source
  when String
    return self[$1] if source =~ /^\s*\[((\.{1,2}|::)+[^\]]+)\]/ && self.kind_of?(When::Parts::Resource)
    return Parts::Resource[$1] if source =~ /^\s*\[::([^\]]+)\]/
    BasicTypes::M17n.new(source, namespace, locale, options)
  else ; raise TypeError, "Invalid Type: #{source.class}"
  end
end

.M17n(source) ⇒ When::BasicTypes::M17n

When::BasicTypes::M17n の生成/参照


622
623
624
# File 'lib/when_exe.rb', line 622

def M17n(source)
  Parts::Resource._instance(source, '_m:')
end

.MonthName(name) ⇒ When::BasicTypes::M17n

月名


612
613
614
# File 'lib/when_exe.rb', line 612

def MonthName(name)
  When::BasicTypes::M17n.month_name(name)
end

.now(options = {}) ⇒ When::TM::DateAndTime

Note:

メソッド実行時の「現在日時」である。@indeterminated_position は設定しないので自動的に日時が進むことはない

現在日時に対応する When::TM::TemporalPosition の生成 (When::TM::DateAndTime of now)


441
442
443
# File 'lib/when_exe.rb', line 441

def now(options={})
  When.at(Time.now, options)
end

.Pair(trunk, branch = nil) ⇒ When::Coordinates::Pair

When::Coordinates::Pair の生成


669
670
671
# File 'lib/when_exe.rb', line 669

def Pair(trunk, branch=nil)
  Coordinates::Pair._force_pair(trunk, branch)
end

.Residue(day) ⇒ When::Coordinates::Residue Also known as: day_of_week

曜日(剰余類)


597
598
599
# File 'lib/when_exe.rb', line 597

def Residue(day)
  When::Coordinates::Residue.to_residue(day)
end

.Resource(iri, namespace = nil) ⇒ When::Parts::Resourc Also known as: IRI

When::Parts::Resource の生成/参照


656
657
658
# File 'lib/when_exe.rb', line 656

def Resource(iri, namespace=nil)
  Parts::Resource._instance(iri, namespace)
end

.server(port) ⇒ void

Note:

mini_application

This method returns an undefined value.

マイクロ・サーバーを起動する


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/when_exe/mini_application.rb', line 56

def server(port)
  config = When.config
  TCPServer.open(port.to_i) do |socket|
    puts Time.now._log_('%FT%X.%L') + ': Start'
    loop do
      Thread.start(socket.accept) do |client|
        query = client.gets.chomp.force_encoding("UTF-8")
        start = Time.now
        puts start._log_('%FT%X.%L') + ': Query - ' + When::Parts::Locale.translate(query, config['!'])
        begin
          result = free_conv(*query.split(/\s+/))
          result = When::Parts::Locale.translate(result, config['!'])
          client.puts JSON.generate(Array(_to_string(result))).to_s
          stop = Time.now
          puts stop._log_('%FT%X.%L') + ": Respond (%7.0f ms)" % (1000 * (stop.to_f - start.to_f))
        rescue => err
          puts Time.now._log_('%FT%X.%L') + ': error - ' + err.to_s
          client.puts JSON.generate({:error=>query}).to_s
        end
        client.close
      end
    end
  end
rescue Exception => e
  puts Time.now._log_('%FT%X.%L') + ': Exception - ' + e.to_s
ensure
  puts Time.now._log_('%FT%X.%L') + ': Done.'
end

.TemporalPosition(*args, options = {}) ⇒ When::TM::TemporalPosition

When::TM::TemporalPosition の生成

Options Hash (options):

  • :invalid (Symbol)
    :raise 日時が存在しない場合例外発生
    :check 日時が存在しない場合 nil を返す
    その他/nil 日時が存在することを確認しない(デフォルト)

See Also:

Raises:

  • (ArgumentError)

    options[ :invalid ] が :raise で、日時が存在しない場合


371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'lib/when_exe.rb', line 371

def TemporalPosition(*args)
  # 引数の解釈
  options  = args[-1].kind_of?(Hash) ? args.pop.dup : {}
  validate = options.delete(:invalid)
  options  = TM::TemporalPosition._options(options)
  options[:frame]  ||= 'Gregorian'
  options[:frame]    = Resource(options[:frame], '_c:') if options[:frame].kind_of?(String)
  options[:era_name] = args.shift if args[0].kind_of?(String) || args[0].kind_of?(Array)

  # 時間位置の生成
  date = Array.new(options[:frame].indices.length+1) {args.shift}
  if (args.length > 0)
    options[:clock] ||= TM::Clock.local_time
    time = Array.new(options[:clock].indices.length) {args.shift}
    position = TM::DateAndTime.new(date, time.unshift(0), options)
  else
    position = TM::CalDate.new(date, options)
  end
  return position unless [:raise, :check].include?(validate)

  # 時間位置の存在確認
  date[0] = -date[0] if position.calendar_era_name && position.calendar_era_name[2] # 紀元前
  date.each_index do |i|
    break unless date[i]
    next if Coordinates::Pair._force_pair(date[i]) == Coordinates::Pair._force_pair(position.cal_date[i])
    return nil if validate == :check
    raise ArgumentError, "Specified date not found: #{date}"
  end
  return position unless time
  time.each_index do |i|
    break unless time[i]
    next if Coordinates::Pair._force_pair(time[i]) == Coordinates::Pair._force_pair(position.clk_time.clk_time[i])
    return nil if validate == :check
    raise ArgumentError, "Specified time not found: #{time}"
  end
  return position
end

.today(options = {}) ⇒ When::TM::CalDate

Note:

メソッド実行時の「本日」である。@indeterminated_position は設定しないので自動的に日時が進むことはない

Note:

options で時間帯を指定しても「本日」の決定に使用するのみで、戻り値には反映されない

本日に対応する When::TM::CalDate の生成 (When::TM::CalDate of today)


455
456
457
# File 'lib/when_exe.rb', line 455

def today(options={})
  now(options.merge({:precision=>DAY}))
end

.utcWhen::CalendarTypes::UTC

When::CalendarTypes::UTC の生成/参照


584
585
586
# File 'lib/when_exe.rb', line 584

def utc
  Parts::Resource._instance("_c:UTC")
end

.when?(specification, options = {}) ⇒ When::TM::TemporalPosition, ...

Generation of Temporal Objetct, duration or When::Parts::GeometricComplex


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/when_exe.rb', line 337

def when?(specification, options={})

  # フォーマットごとの処理
  case specification
  when TM::TemporalPosition, Parts::GeometricComplex ; specification
  when TM::Position ; specification.any_other
  when Array        ; begin options = TM::TemporalPosition._options(options) ; specification.map {|e| when?(e, options)} end
  when /^today$/i   ; today(options)
  when /^now$/i     ; now(options)
  when /[\n\r]+/    ; when?(specification.split(/[\n\r]+/), options)
  when String       ; TM::TemporalPosition._instance(specification, options)
  when Numeric      ; TM::JulianDate.new(+specification, TM::TemporalPosition._options(options))
  else              ; Calendar(options[:frame] || 'Gregorian').jul_trans(specification, options)
  end
end