when_exe 0.3.2 → 0.3.3

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.
Files changed (93) hide show
  1. data/LICENSE.ja.txt +25 -25
  2. data/LICENSE.txt +31 -31
  3. data/bin/locales.rb +2 -1
  4. data/bin/when.rb.config +1 -1
  5. data/lib/when_exe.rb +70 -48
  6. data/lib/when_exe/basictypes.rb +99 -65
  7. data/lib/when_exe/calendartypes.rb +40 -178
  8. data/lib/when_exe/coordinates.rb +156 -62
  9. data/lib/when_exe/core/compatibility.rb +10 -0
  10. data/lib/when_exe/core/extension.rb +40 -0
  11. data/lib/when_exe/ephemeris.rb +112 -50
  12. data/lib/when_exe/icalendar.rb +125 -91
  13. data/lib/when_exe/inspect.rb +100 -48
  14. data/lib/when_exe/locales/ar.rb +48 -48
  15. data/lib/when_exe/locales/bg.rb +1 -1
  16. data/lib/when_exe/locales/bs.rb +4 -2
  17. data/lib/when_exe/locales/ca.rb +1 -1
  18. data/lib/when_exe/locales/en_CA.rb +3 -4
  19. data/lib/when_exe/locales/en_IE.rb +88 -0
  20. data/lib/when_exe/locales/en_US.rb +87 -0
  21. data/lib/when_exe/locales/es_CR.rb +84 -0
  22. data/lib/when_exe/locales/es_EC.rb +85 -0
  23. data/lib/when_exe/locales/es_PA.rb +85 -0
  24. data/lib/when_exe/locales/fr.rb +39 -39
  25. data/lib/when_exe/locales/hu.rb +15 -14
  26. data/lib/when_exe/locales/it.rb +1 -1
  27. data/lib/when_exe/locales/ja.rb +2 -2
  28. data/lib/when_exe/locales/locales.rb +7 -0
  29. data/lib/when_exe/locales/lt.rb +21 -19
  30. data/lib/when_exe/locales/ms.rb +84 -0
  31. data/lib/when_exe/locales/nl.rb +2 -2
  32. data/lib/when_exe/locales/ru.rb +1 -1
  33. data/lib/when_exe/locales/uk.rb +1 -1
  34. data/lib/when_exe/locales/ur.rb +84 -0
  35. data/lib/when_exe/mini_application.rb +44 -43
  36. data/lib/when_exe/parts/enumerator.rb +3 -3
  37. data/lib/when_exe/parts/geometric_complex.rb +6 -1
  38. data/lib/when_exe/parts/locale.rb +49 -18
  39. data/lib/when_exe/parts/method_cash.rb +61 -0
  40. data/lib/when_exe/parts/resource.rb +221 -106
  41. data/lib/when_exe/parts/timezone.rb +70 -33
  42. data/lib/when_exe/region/bahai.rb +2 -2
  43. data/lib/when_exe/region/balinese.rb +40 -43
  44. data/lib/when_exe/region/chinese.rb +93 -33
  45. data/lib/when_exe/region/chinese_calendar.rb +117 -1
  46. data/lib/when_exe/region/chinese_epoch.rb +65 -10
  47. data/lib/when_exe/region/christian.rb +97 -2
  48. data/lib/when_exe/region/ephemeric_notes.rb +353 -0
  49. data/lib/when_exe/region/french.rb +1 -1
  50. data/lib/when_exe/region/geologicalage.rb +171 -171
  51. data/lib/when_exe/region/indian.rb +18 -14
  52. data/lib/when_exe/region/iranian.rb +1 -1
  53. data/lib/when_exe/region/japanese.rb +49 -12
  54. data/lib/when_exe/region/japanese_notes.rb +838 -507
  55. data/lib/when_exe/region/japanese_residues.rb +724 -662
  56. data/lib/when_exe/region/javanese.rb +7 -7
  57. data/lib/when_exe/region/mayan.rb +19 -17
  58. data/lib/when_exe/region/nihon_shoki.rb +3 -3
  59. data/lib/when_exe/region/residue.rb +29 -28
  60. data/lib/when_exe/region/shire.rb +2 -2
  61. data/lib/when_exe/region/tibetan.rb +87 -5
  62. data/lib/when_exe/region/world.rb +1 -1
  63. data/lib/when_exe/timestandard.rb +85 -7
  64. data/lib/when_exe/tmobjects.rb +32 -4
  65. data/lib/when_exe/tmposition.rb +104 -55
  66. data/lib/when_exe/tmreference.rb +157 -60
  67. data/lib/when_exe/version.rb +2 -2
  68. data/test/examples/JapanHolidays.ics +3 -3
  69. data/test/examples/JapanHolidaysRFC6350.ics +499 -0
  70. data/test/examples/Residue.m17n +3 -2
  71. data/test/examples/Spatial.m17n +3 -3
  72. data/test/examples/USA-DST.ics +27 -27
  73. data/test/examples/today.rb +1 -1
  74. data/test/test.rb +4 -2
  75. data/test/test/basictypes.rb +40 -15
  76. data/test/test/coordinates.rb +9 -4
  77. data/test/test/icalendar.rb +24 -14
  78. data/test/test/inspect.rb +5 -3
  79. data/test/test/parts.rb +11 -2
  80. data/test/test/region/chinese.rb +4 -4
  81. data/test/test/region/civil.rb +124 -0
  82. data/test/test/region/geologicalage.rb +5 -2
  83. data/test/test/region/indian.rb +2 -0
  84. data/test/test/region/japanese.rb +156 -1
  85. data/test/test/region/jewish.rb +3 -3
  86. data/test/test/region/m17n.rb +9 -9
  87. data/test/test/region/mayan.rb +122 -5
  88. data/test/test/region/residue.rb +1 -1
  89. data/test/test/tmobjects.rb +27 -64
  90. data/test/test/tmposition.rb +48 -1
  91. data/test/test/tmreference.rb +66 -4
  92. data/when_exe.gemspec +1 -1
  93. metadata +15 -6
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  =begin
3
- Copyright (C) 2011-2013 Takashi SUGA
3
+ Copyright (C) 2011-2014 Takashi SUGA
4
4
 
5
5
  You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
6
  =end
@@ -59,25 +59,48 @@ module When::CalendarTypes
59
59
  @label ||= m17n('Z')
60
60
  @indices ||= When::Coordinates::DefaultTimeIndices
61
61
  @note ||= 'JulianDayNotes'
62
+ _normalize_spatial
62
63
  _normalize_temporal
63
- @second = (@second||128).to_f
64
+ @second = (@second||1/When::TM::Duration::SECOND).to_f
64
65
  @zone = '+00:00'
65
66
  @time_standard ||= When.Resource('_t:UniversalTime')
66
67
  @utc_reference = When::TM::ClockTime.new([0,0,0,0], {:frame=>self})
67
68
  end
68
69
  end
69
70
 
71
+ #
72
+ # Abstract Local Time
73
+ #
74
+ class LocalTime < UTC
75
+
76
+ # 128秒単位の実数による参照事象の時刻
77
+ #
78
+ # Fraction time of the reference event
79
+ #
80
+ # @param [Integer] sdn 参照事象の通し番号
81
+ #
82
+ # @return [Numeric]
83
+ #
84
+ # T00:00:00Z からの参照事象の経過時間 / 128秒
85
+ #
86
+ def universal_time(sdn=nil)
87
+ return super unless sdn
88
+ time = When::TM::JulianDate._d_to_t(sdn-0.5)
89
+ @time_standard.to_dynamical_time(time) - When::TimeStandard.to_dynamical_time(time)
90
+ end
91
+ end
92
+
70
93
  #
71
94
  # Local Mean Time
72
95
  #
73
- class LMT < UTC
96
+ class LMT < LocalTime
74
97
 
75
98
  private
76
99
 
77
100
  # オブジェクトの正規化
78
101
  def _normalize(args=[], options={})
79
102
  @label = m17n('LMT')
80
- @time_standard = When.Resource("_t:LocalMeanTime?location=_l:long=#{@long||0}%26lat=0")
103
+ @time_standard = When.Resource("_t:LocalMeanTime?location=_l:long=#{@long||0}")
81
104
  super
82
105
  end
83
106
  end
@@ -85,14 +108,14 @@ module When::CalendarTypes
85
108
  #
86
109
  # Local Apparent Time
87
110
  #
88
- class LAT < UTC
111
+ class LAT < LocalTime
89
112
 
90
113
  private
91
114
 
92
115
  # オブジェクトの正規化
93
116
  def _normalize(args=[], options={})
94
117
  @label = m17n('LAT')
95
- @time_standard = When.Resource("_t:LocalApparentTime?location=_l:long=#{@long||0}%26lat=0")
118
+ @time_standard = When.Resource("_t:LocalApparentTime?location=_l:long=#{@long||0}")
96
119
  super
97
120
  end
98
121
  end
@@ -100,14 +123,14 @@ module When::CalendarTypes
100
123
  #
101
124
  # Temporal Hour System
102
125
  #
103
- class THS < UTC
126
+ class THS < LocalTime
104
127
 
105
128
  private
106
129
 
107
130
  # オブジェクトの正規化
108
131
  def _normalize(args=[], options={})
109
132
  @label = m17n('THS')
110
- @time_standard = When.Resource("_t:TemporalHourSystem?location=_l:long=#{@long||0}%26lat=#{@lat||0}")
133
+ @time_standard = When.Resource("_t:TemporalHourSystem?location=(_l:long=#{@long||0}&lat=#{@lat||0}&alt=#{@alt||0})")
111
134
  super
112
135
  end
113
136
  end
@@ -572,12 +595,6 @@ module When::CalendarTypes
572
595
  #
573
596
  class YearLengthTableBased < TableBased
574
597
 
575
- # 時間帯
576
- #
577
- # @return [Array<Numeric>]
578
- #
579
- attr_reader :timezone
580
-
581
598
  # 天体暦アルゴリズム
582
599
  #
583
600
  # @return [Array<When::Ephemeris::Formula>]
@@ -599,7 +616,7 @@ module When::CalendarTypes
599
616
  def _sdn_(date)
600
617
  y = +date[0]
601
618
  t = @formula[0].cn_to_time(y.to_f + @cycle_offset)
602
- return (t + 0.5 + @day_offset + @timezone[0]).floor
619
+ return solar_sdn(t + @day_offset)
603
620
  end
604
621
 
605
622
  # オブジェクトの正規化
@@ -611,7 +628,6 @@ module When::CalendarTypes
611
628
  Rational
612
629
  @cycle_offset = (@cycle_offset||0).to_r
613
630
  @day_offset = (@day_offset||0).to_r
614
- @timezone = (@timezone||0).to_r
615
631
  @formula = 'Formula?formula=1S'
616
632
 
617
633
  super
@@ -721,12 +737,6 @@ module When::CalendarTypes
721
737
  #
722
738
  class EphemerisBasedSolar < EphemerisBased
723
739
 
724
- # 時間帯
725
- #
726
- # @return [Array<Numeric>]
727
- #
728
- attr_reader :timezone
729
-
730
740
  #protected
731
741
 
732
742
  # 月初の通日
@@ -736,7 +746,7 @@ module When::CalendarTypes
736
746
  # @return [Integer] 月初の通日
737
747
  #
738
748
  def _new_month_(m)
739
- return (@formula[0].cn_to_time(m + @cycle_offset) + 0.5 + @timezone[0]).floor
749
+ return solar_sdn(@formula[0].cn_to_time(m + @cycle_offset))
740
750
  end
741
751
 
742
752
  private
@@ -758,12 +768,6 @@ module When::CalendarTypes
758
768
  #
759
769
  class EphemerisBasedLunar < EphemerisBased
760
770
 
761
- # 時間帯
762
- #
763
- # @return [Array<Numeric, (Numeric)>]
764
- #
765
- attr_reader :timezone
766
-
767
771
  #protected
768
772
 
769
773
  # 月初の通日
@@ -773,7 +777,7 @@ module When::CalendarTypes
773
777
  # @return [Integer] 月初の通日
774
778
  #
775
779
  def _new_month_(m)
776
- return (@formula[-1].cn_to_time(m + @cycle_offset) + 0.5 + @timezone[-1]).floor
780
+ return lunar_sdn(@formula[-1].cn_to_time(m + @cycle_offset))
777
781
  end
778
782
 
779
783
  private
@@ -876,7 +880,7 @@ module When::CalendarTypes
876
880
  # @return [Integer] 月初の通日
877
881
  #
878
882
  def _new_month_(m)
879
- (@formula[-1].cn_to_time(m) + 0.5 + @timezone[-1]).floor
883
+ lunar_sdn(@formula[-1].cn_to_time(m))
880
884
  end
881
885
 
882
886
  # 年初の通月
@@ -893,7 +897,6 @@ module When::CalendarTypes
893
897
  #
894
898
  # @cycle_offset = 雨水の場合 -1
895
899
  # @formula = 位相の計算に用いる太陽と月の Formula
896
- # @timezone[1] = 進朔量
897
900
  # @notes = to_a でデフォルトとして用いる暦注
898
901
  #
899
902
  def _normalize(args=[], options={})
@@ -1248,7 +1251,7 @@ module When::CalendarTypes
1248
1251
  # 暦注サブクラスの場合、暦注要素が増えたり、:note の暦注要素の型が変わったりすることがある。
1249
1252
  #
1250
1253
  def notes(date, options={})
1251
- dates, indices, notes, conditions, options = _parse(date, options)
1254
+ dates, indices, notes, conditions, options = _parse_note(date, options)
1252
1255
  _result(indices.map {|i|
1253
1256
  next [] unless i <= date.precision
1254
1257
  _note_values(dates, notes[i-1], _all_keys[i-1], _elements[i-1]) do |dates, focused_notes, notes_hash|
@@ -1256,6 +1259,7 @@ module When::CalendarTypes
1256
1259
  unless notes_hash[note]
1257
1260
  void, event, *parameter = note.split(/^([^\d]+)/)
1258
1261
  method = event.downcase
1262
+ parameter << conditions unless conditions.empty?
1259
1263
  notes_hash[note] =
1260
1264
  if respond_to?(method)
1261
1265
  send(method, dates, *parameter)
@@ -1375,7 +1379,7 @@ module When::CalendarTypes
1375
1379
  #
1376
1380
  # @return [Array] dates, indices, notes
1377
1381
  #
1378
- def _parse(date, options)
1382
+ def _parse_note(date, options)
1379
1383
  options =
1380
1384
  case options
1381
1385
  when Hash ; options
@@ -1452,13 +1456,14 @@ module When::CalendarTypes
1452
1456
  # prepare focused notes
1453
1457
  case focused_notes
1454
1458
  when Integer
1455
- bits = focused_notes << 1
1459
+ bits = ~focused_notes << 1
1456
1460
  focused_notes = all_notes.dup.delete_if { (bits>>=1)[0] == 1 }
1457
1461
  when []
1458
1462
  focused_notes = all_notes
1459
1463
  when nil
1460
1464
  focused_notes = []
1461
1465
  end
1466
+ focused_notes = focused_notes.dup
1462
1467
  not_focused_notes = all_notes - focused_notes
1463
1468
  notes = {}
1464
1469
  not_focused_notes.each do |note|
@@ -1557,147 +1562,4 @@ module When::CalendarTypes
1557
1562
  end
1558
1563
  end
1559
1564
  end
1560
-
1561
- class CalendarNote
1562
- #
1563
- # 太陽と月の位置によるイベント
1564
- #
1565
- class LuniSolarPositions < self
1566
-
1567
- # 座標の分子
1568
- #
1569
- # @return [Numeric]
1570
- #
1571
- attr_reader :num
1572
-
1573
- # 座標の分母
1574
- #
1575
- # @return [Numeric]
1576
- #
1577
- attr_reader :den
1578
-
1579
- # 計算アルゴリズム
1580
- #
1581
- # @return [When::Ephemeris::Formula]
1582
- #
1583
- attr_reader :formula
1584
-
1585
- # enumerator の周期
1586
- #
1587
- # @return [Numeric]
1588
- #
1589
- attr_reader :delta
1590
-
1591
- # 没滅計算用の補正
1592
- #
1593
- # @return [Numeric]
1594
- #
1595
- attr_reader :margin
1596
-
1597
- # イベントの日時
1598
- #
1599
- # @param [When::TM::TemporalPosition] date イベントを探す基準とする日時
1600
- # @param [Array<Numeric>] parameter 座標の分子と分母( num, den)
1601
- #
1602
- # num 座標の分子 (デフォルト @num)
1603
- #
1604
- # den 座標の分母 (デフォルト @den)
1605
- #
1606
- # @param [String] parameter 座標の分子と分母("#{ num }/#{ den }" の形式)
1607
- # @param [Integer] precision 取得したい時間位置の分解能(デフォルト date の分解能)
1608
- #
1609
- # @return [When::TM::CalDate] date またはその直後のイベントの日時
1610
- #
1611
- def term(date, parameter=nil, precision=date.precision)
1612
- precision = nil if precision == When::SYSTEM
1613
- num, den = parameter.kind_of?(String) ? parameter.split(/\//, 2) : parameter
1614
- num = (num || @num).to_f
1615
- den = (den || @den).to_f
1616
- date = date.floor(precision) if precision
1617
- options = date._attr
1618
- quot, mod = (@formula.time_to_cn(date)*30.0).divmod(den)
1619
- cycle = quot * den + num
1620
- cycle += den if mod > num
1621
- time = When::TM::JulianDate._d_to_t(@formula.cn_to_time(cycle/30.0))
1622
- time = date.time_standard.from_dynamical_time(time) if @formula.is_dynamical
1623
- date = date.frame.jul_trans(When::TM::JulianDate.universal_time(time), options)
1624
- precision ? date.floor(precision) : date
1625
- end
1626
-
1627
- # 日付に対応する座標
1628
- #
1629
- # @param [When::TM::TemporalPosition] date 日付
1630
- # @param [Numeric] delta 周期の補正(下弦,上弦の場合 0.5, その他は0(デフォルト))
1631
- #
1632
- # @return [Array<Integer>] Array< Integer, 0 or 1 or 2 >
1633
- #
1634
- # [Integer] 対応する座標
1635
- #
1636
- # [0 or 1 or 2] 座標の進み(0 なら 没日, 2 なら滅)
1637
- #
1638
- def position(date, delta=0)
1639
- date = date.floor
1640
- p0, p1 = [date, date.succ].map {|d| (@formula.time_to_cn(d)*30.0-@margin+delta).floor}
1641
- [p1 % @den, p1-p0]
1642
- end
1643
-
1644
- #
1645
- # イベントの標準的な間隔を返す
1646
- #
1647
- # @param [String] parameter 座標の分子と分母("#{ num }/#{ den }" の形式)
1648
- #
1649
- # @return [When::TM::IntervalLength]
1650
- def term_delta(parameter=nil)
1651
- return @delta unless parameter
1652
- num, den = parameter.split(/\//, 2)
1653
- When::TM::IntervalLength.new([(den || @den).to_f-1,1].max, 'day')
1654
- end
1655
- end
1656
-
1657
- #
1658
- # 二十四節気
1659
- #
1660
- class SolarTerms < LuniSolarPositions
1661
-
1662
- private
1663
-
1664
- # オブジェクトの正規化
1665
- # num - 太陽黄経/度の分子 (デフォルト 0 - 春分)
1666
- # den - 太陽黄経/度の分母 (デフォルト 360 - 1年)
1667
- # formula - 計算アルゴリズム(デフォルト '_ep:Formula?formula=12S')
1668
- # delta - enumerator の周期 (デフォルト (den/360)年)
1669
- # margin - 没滅計算用の補正 (デフォルト 1E-8)
1670
- def _normalize(args=[], options={})
1671
- num, den, formula, delta, margin = args
1672
- @num = (num || @num || 0).to_f
1673
- @den = (den || @den || 360).to_f
1674
- @formula = When.Resource(formula || @formula ||'Formula?formula=12S', '_ep:')
1675
- @delta = When.Duration(delta || @delta || When::TM::IntervalLength.new(@den/360, 'year'))
1676
- @margin = (margin || @margin || 1E-8).to_f
1677
- end
1678
- end
1679
-
1680
- #
1681
- # 月の位相
1682
- #
1683
- class LunarPhases < LuniSolarPositions
1684
-
1685
- private
1686
-
1687
- # オブジェクトの正規化
1688
- # num - 月の位相/12度の分子 (デフォルト 0 - 朔)
1689
- # den - 月の位相/12度の分母 (デフォルト 30 - 1月)
1690
- # formula - 計算アルゴリズム(デフォルト '_ep:Formula?formula=1L')
1691
- # delta - enumerator の周期 (デフォルト (den/30)月)
1692
- # margin - 没滅計算用の補正 (デフォルト 1E-8)
1693
- def _normalize(args=[], options={})
1694
- num, den, formula, delta, margin = args
1695
- @num = (num || @num || 0).to_f
1696
- @den = (den || @den || 30).to_f
1697
- @formula = When.Resource(formula || @formula ||'Formula?formula=1L', '_ep:')
1698
- @delta = When.Duration(delta || @delta || When::TM::IntervalLength.new(@den/30, 'month'))
1699
- @margin = (margin || @margin || 1E-8).to_f
1700
- end
1701
- end
1702
- end
1703
1565
  end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  =begin
3
- Copyright (C) 2011-2013 Takashi SUGA
3
+ Copyright (C) 2011-2014 Takashi SUGA
4
4
 
5
5
  You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
6
  =end
@@ -449,12 +449,21 @@ module When::Coordinates
449
449
 
450
450
  private
451
451
 
452
+ alias :_method_missing :method_missing
453
+
452
454
  # その他のメソッド
453
455
  #
454
456
  # When::Coordinate::Residue で定義されていないメソッドは
455
457
  # 指定の桁での剰余算とみなす
456
458
  #
457
459
  def method_missing(name, *args, &block)
460
+ return _method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name) ||
461
+ !@units.key?(name.to_s.downcase)
462
+ instance_eval %Q{
463
+ def #{name}(*args, &block)
464
+ self[args[0] % self.to("#{name.to_s.downcase}")]
465
+ end
466
+ } unless When::Parts::MethodCash.escape(name)
458
467
  self[args[0] % self.to(name.to_s.downcase)]
459
468
  end
460
469
 
@@ -948,7 +957,7 @@ module When::Coordinates
948
957
  # @return [When::Coordinates::Pair] Pair.new(-@trunk, @branch)
949
958
  #
950
959
  def -@
951
- return self.class.new(-(@trunk||0), @branch)
960
+ return self.class.new(-@trunk, @branch)
952
961
  end
953
962
 
954
963
  # @trunk, @branch を取得する
@@ -983,8 +992,8 @@ module When::Coordinates
983
992
  # other が When::Coordinates::Pair でない場合、trunk に対する加算となる
984
993
  #
985
994
  def +(other)
986
- return self.class.new((@trunk||0) + other, @branch) unless other.kind_of?(self.class)
987
- return self.class.new((@trunk||0) + (other.trunk||0), (@branch||0) + (other.branch||0))
995
+ return self.class.new(@trunk + other, @branch) unless other.kind_of?(self.class)
996
+ return self.class.new(@trunk + other.trunk, @branch + other.branch)
988
997
  end
989
998
 
990
999
  # 減算
@@ -995,8 +1004,8 @@ module When::Coordinates
995
1004
  # other が When::Coordinates::Pair でない場合、trunk に対する減算となる
996
1005
  #
997
1006
  def -(other)
998
- return self.class.new((@trunk||0) - other, @branch) unless other.kind_of?(self.class)
999
- return self.class.new((@trunk||0) - (other.trunk||0), (@branch||0) - (other.branch||0))
1007
+ return self.class.new(@trunk - other, @branch) unless other.kind_of?(self.class)
1008
+ return self.class.new(@trunk - other.trunk, @branch - other.branch)
1000
1009
  end
1001
1010
 
1002
1011
  # 商と剰余
@@ -1007,7 +1016,7 @@ module When::Coordinates
1007
1016
  # trunk に対する divmod となる
1008
1017
  #
1009
1018
  def divmod(other)
1010
- div, mod = (@trunk||0).divmod(other)
1019
+ div, mod = @trunk.divmod(other)
1011
1020
  return div, self.class.new(mod, @branch)
1012
1021
  end
1013
1022
 
@@ -1019,7 +1028,7 @@ module When::Coordinates
1019
1028
  # trunk に対する % となる
1020
1029
  #
1021
1030
  def %(other)
1022
- self.class.new((@trunk||0) % other, @branch)
1031
+ self.class.new(@trunk % other, @branch)
1023
1032
  end
1024
1033
 
1025
1034
  # 比較
@@ -1031,7 +1040,7 @@ module When::Coordinates
1031
1040
  #
1032
1041
  def <=>(other)
1033
1042
  other = self.class._force_pair(other)
1034
- (@trunk <=> other.trunk).nonzero? || ((@branch||0) <=> (other.branch||0))
1043
+ (@trunk <=> other.trunk).nonzero? || (@branch <=> other.branch)
1035
1044
  end
1036
1045
 
1037
1046
  # 文字列化
@@ -1041,7 +1050,7 @@ module When::Coordinates
1041
1050
  # @return [String]
1042
1051
  #
1043
1052
  def to_s(zero='')
1044
- return @trunk.to_s + (((@branch||0)==0) ? zero : DL2[@branch])
1053
+ return @trunk.to_s + (@branch==0 ? zero : DL2[@branch])
1045
1054
  end
1046
1055
 
1047
1056
  # 強制型変換
@@ -1058,8 +1067,8 @@ module When::Coordinates
1058
1067
  # @param [Numeric] branch 枝
1059
1068
  #
1060
1069
  def initialize(trunk, branch=nil)
1061
- @trunk = trunk
1062
- @branch = branch
1070
+ @trunk = trunk || 0
1071
+ @branch = branch || 0
1063
1072
  _normalize
1064
1073
  end
1065
1074
 
@@ -1077,7 +1086,12 @@ module When::Coordinates
1077
1086
  # 処理を @sum (type:Numeric) に委譲する
1078
1087
  #
1079
1088
  def method_missing(name, *args, &block)
1080
- @sum.send(name.to_sym, *args, &block)
1089
+ self.class.module_eval %Q{
1090
+ def #{name}(*args, &block)
1091
+ @sum.send("#{name}", *args, &block)
1092
+ end
1093
+ } unless When::Parts::MethodCash.escape(name)
1094
+ @sum.send(name, *args, &block)
1081
1095
  end
1082
1096
  end
1083
1097
 
@@ -1195,6 +1209,74 @@ module When::Coordinates
1195
1209
 
1196
1210
  include When::Ephemeris
1197
1211
 
1212
+ class << self
1213
+ # When::Coordinates::Spatial のグローバルな設定を行う
1214
+ #
1215
+ # @param [When::Coordinates::Spatial, String] location デフォルトの空間位置を使用する場合、指定する
1216
+ #
1217
+ # @return [void]
1218
+ #
1219
+ # @note
1220
+ # 本メソッドでマルチスレッド対応の管理変数の初期化を行っている。
1221
+ # このため、本メソッド自体はスレッドセーフでない。
1222
+ #
1223
+ def _setup_(location=nil)
1224
+ @_lock_ = Mutex.new if When.multi_thread
1225
+ @_pool = {}
1226
+ @default_location = location
1227
+ end
1228
+
1229
+ # デフォルトの空間位置
1230
+ #
1231
+ # @param [When::Coordinates::Spatial, String] default_location デフォルトの空間位置
1232
+ #
1233
+ # @return [When::Coordinates::Spatial, String]
1234
+ #
1235
+ # @note
1236
+ # @default_locationは、原則、ライブラリ立ち上げ時に _setup_ で初期化する。
1237
+ # 以降、@default_locationに代入を行っても、すでに生成した When::TM::TemporalPosition 等には反映されない。
1238
+ #
1239
+ def default_location=(local)
1240
+ if @_pool
1241
+ @default_location = local
1242
+ else
1243
+ _setup_(local)
1244
+ end
1245
+ end
1246
+
1247
+ # デフォルトの空間位置を読みだす
1248
+ #
1249
+ # @return [When::Coordinates::Spatial]
1250
+ #
1251
+ def default_location
1252
+ _default_location[1]
1253
+ end
1254
+
1255
+ # デフォルトの空間位置が When::TM::Clock のローカルタイムから生成されたか?
1256
+ #
1257
+ # @return [true, false]
1258
+ #
1259
+ def is_default_location_derived?
1260
+ location = _default_location
1261
+ location[0] && location[1]
1262
+ end
1263
+
1264
+ private
1265
+
1266
+ # 共通処理
1267
+ def _default_location
1268
+ case @default_location
1269
+ when nil ;
1270
+ when Array ; return @default_location unless @default_location[0]
1271
+ when String ; return (@default_location = [false, When.Resource(@default_location)])
1272
+ else ; return (@default_location = [false, @default_location])
1273
+ end
1274
+ timezone = When::TM::Clock.local_time
1275
+ location = timezone.location if timezone.kind_of?(When::Parts::Timezone)
1276
+ return [true, location]
1277
+ end
1278
+ end
1279
+
1198
1280
  # Degree / Internal Location Unit(16")
1199
1281
  #
1200
1282
  # (3600 を 2 の因数で割りつくした値を単位とする)
@@ -1206,8 +1288,11 @@ module When::Coordinates
1206
1288
  # 赤道座標 (equatorial coordinate system)
1207
1289
  EQUATORIAL = 1
1208
1290
 
1291
+ # 赤道座標[時角] (equatorial coordinate system with hour angle)
1292
+ EQUATORIAL_HA = 2
1293
+
1209
1294
  # 地平座標 (horizontal coordinate system)
1210
- HORIZONTAL = 2
1295
+ HORIZONTAL = 3
1211
1296
 
1212
1297
  # 惑星中心の高度
1213
1298
  CENTER = :center
@@ -1310,20 +1395,25 @@ module When::Coordinates
1310
1395
 
1311
1396
  # 要素の正規化
1312
1397
  def _normalize(args=[], options={})
1313
- @lat = When::Coordinates.to_deg(@lat, 'NS') * DEGREE if @lat
1314
1398
  @long = When::Coordinates.to_deg(@long, 'EW') * DEGREE if @long
1315
- @alt = (@alt) ? @alt.to_f : 0.0
1399
+ @lat = When::Coordinates.to_deg(@lat, 'NS') * DEGREE if @lat
1316
1400
  @datum = When.Resource(@datum || 'Earth', '_ep:')
1317
1401
  if @tz.kind_of?(String)
1318
1402
  @label ||= @tz
1319
1403
  @tz = When::Parts::Timezone.tz_info[@tz]
1320
1404
  end
1321
1405
  if @tz
1322
- @lat ||= @tz.latitude * DEGREE
1323
1406
  @long ||= @tz.longitude * DEGREE
1407
+ @lat ||= @tz.latitude * DEGREE
1324
1408
  end
1325
- @lat ||= 0.0
1326
1409
  @long ||= 0.0
1410
+ @lat ||= 0.0
1411
+ @alt =
1412
+ case @alt
1413
+ when String ; @alt.gsub(/@/, '.').to_f
1414
+ when Numeric ; @alt.to_f
1415
+ else ; 0.0
1416
+ end
1327
1417
  end
1328
1418
 
1329
1419
  # 観測地の惑星中心を原点とする三次元座標
@@ -1331,9 +1421,10 @@ module When::Coordinates
1331
1421
  # @param [Numeric] t ユリウス日(Terrestrial Time)
1332
1422
  # @param [When::TM::TemporalPosition] t
1333
1423
  # @param [Integer] system : 座標系
1334
- # [ ECLIPTIC = 黄道座標 ]
1335
- # [ EQUATORIAL = 赤道座標 ]
1336
- # [ HORIZONTAL = 地平座標 ]
1424
+ # [ ECLIPTIC = 黄道座標 ]
1425
+ # [ EQUATORIAL = 赤道座標 ]
1426
+ # [ EQUATORIAL_HA = 赤道座標[時角] ]
1427
+ # [ HORIZONTAL = 地平座標 ]
1337
1428
  #
1338
1429
  def _coords_diff(t, system=ECLIPTIC)
1339
1430
  return Coords.polar(0,0,0) if alt == :Center
@@ -1342,11 +1433,12 @@ module When::Coordinates
1342
1433
  coords = Coords.polar(
1343
1434
  local_sidereal_time(t) / 24.0,
1344
1435
  (lat + @datum.shape[3] * sind(2*lat)) / 360.0,
1345
- (obserber_distance + @alt) / AU)
1436
+ (obserber_distance + @alt/1000.0) / AU)
1346
1437
  case system
1347
- when ECLIPTIC ; coords.r_to_y(t, @datum)
1348
- when EQUATORIAL ; coords
1349
- when HORIZONTAL ; coords.r_to_h(t, self)
1438
+ when ECLIPTIC ; coords.r_to_y(t, @datum)
1439
+ when EQUATORIAL ; coords
1440
+ when EQUATORIAL_HA ; coords.r_to_rh(t, self)
1441
+ when HORIZONTAL ; coords.r_to_h(t, self)
1350
1442
  end
1351
1443
  end
1352
1444
 
@@ -1355,9 +1447,15 @@ module When::Coordinates
1355
1447
  # 処理を @datum (type: When::Ephemeris::Datum) に委譲する
1356
1448
  #
1357
1449
  def method_missing(name, *args, &block)
1358
- @datum.send(name.to_sym, self, *args, &block)
1450
+ self.class.module_eval %Q{
1451
+ def #{name}(*args, &block)
1452
+ @datum.send("#{name}", *args, &block)
1453
+ end
1454
+ } unless When::Parts::MethodCash.escape(name)
1455
+ @datum.send(name, *args, &block)
1359
1456
  end
1360
1457
 
1458
+ # @private
1361
1459
  module Normalize
1362
1460
 
1363
1461
  private
@@ -1366,25 +1464,19 @@ module When::Coordinates
1366
1464
  #
1367
1465
  # @return [When::Coordinates::Spatial]
1368
1466
  #
1369
- attr_reader :location
1370
-
1371
- # 時差情報
1372
- #
1373
- # @return [Array<Numeric>]
1374
- #
1375
- attr_reader :timezone
1467
+ #attr_reader :location
1376
1468
 
1377
1469
  # 日時要素の境界オブジェクト
1378
1470
  #
1379
1471
  # @return [When::CalendarTypes::Border]
1380
1472
  #
1381
- attr_reader :border
1473
+ #attr_reader :border
1382
1474
 
1383
1475
  # 境界計算用の計算オブジェクト
1384
1476
  #
1385
1477
  # @return [When::Ephemeris::Formula]
1386
1478
  #
1387
- attr_reader :formula
1479
+ #attr_reader :formula
1388
1480
 
1389
1481
  #
1390
1482
  # Temporal Module の Spatial Parts の初期化
@@ -1392,26 +1484,11 @@ module When::Coordinates
1392
1484
  def _normalize_spatial
1393
1485
 
1394
1486
  # Location
1395
- if ((@location||@long||@lat).kind_of?(String))
1396
- @location ||= "_l:long=#{@long||0}&lat=#{@lat||0}"
1487
+ if ((@location||@long||@lat||@alt).kind_of?(String))
1488
+ @location ||= "_l:long=#{@long||0}&lat=#{@lat||0}&alt=#{@alt||0}"
1397
1489
  @location = When.Resource(@location)
1398
1490
  end
1399
1491
 
1400
- # Timezone
1401
- if respond_to?(:timezone)
1402
- @timezone ||= @location ? @location.long / (Spatial::DEGREE * 15) : 9.0
1403
- @timezone = @timezone.kind_of?(String) ? @timezone.split(/,/) : Array(@timezone)
1404
- @timezone = @timezone.map {|v|
1405
- d = v.split('/')[1] if v.kind_of?(String)
1406
- v = v.to_f / 24
1407
- v /= d.to_f if d
1408
- v
1409
- }
1410
- (1...@timezone.size).each do |i|
1411
- @timezone[i] += @timezone[i-1]
1412
- end
1413
- end
1414
-
1415
1492
  # Border
1416
1493
  if (@border.kind_of?(String))
1417
1494
  @border = When.Calendar(
@@ -1423,7 +1500,7 @@ module When::Coordinates
1423
1500
  end
1424
1501
 
1425
1502
  # Formula
1426
- instance_eval('class << self; attr_reader :formula; end') # if @location && @border
1503
+ instance_eval('class << self; attr_reader :formula; end') if @location && @border
1427
1504
  if respond_to?(:formula)
1428
1505
  instance_eval('class << self; include When::Ephemeris::Formula::Methods; end')
1429
1506
  @formula ||= When::Ephemeris::Formula.new({:location=>@location})
@@ -1444,13 +1521,12 @@ module When::Coordinates
1444
1521
  module Temporal
1445
1522
 
1446
1523
  include When::Parts::MethodCash
1447
- include When::Coordinates::Spatial::Normalize
1448
1524
 
1449
1525
  # @private
1450
1526
  HashProperty =
1451
1527
  [[:origin_of_MSC, 0], [:origin_of_LSC, 0], [:index_of_MSC, 0], [:_diff_to_CE, 0],
1452
1528
  :unit, :base, :pair, :note,
1453
- :location, :timezone, :border, :formula]
1529
+ :location, :time_basis, :border, :formula]
1454
1530
 
1455
1531
  # 年/日の原点(origin of most significant coordinate)
1456
1532
  #
@@ -1676,7 +1752,7 @@ module When::Coordinates
1676
1752
  if ((0...len) === digit)
1677
1753
  # 要素が範囲内
1678
1754
  date[i] = digit
1679
- elsif other && other[i] == 0
1755
+ elsif other && period[i] == 0
1680
1756
  # 要素が範囲外で、加算自体はあるが“日”の加算なし
1681
1757
  date[i] = len-1
1682
1758
  else
@@ -1778,9 +1854,6 @@ module When::Coordinates
1778
1854
  # method cash
1779
1855
  @_m_cash_lock_ = Mutex.new if When.multi_thread
1780
1856
 
1781
- # Spatial Parts
1782
- _normalize_spatial
1783
-
1784
1857
  # Origin and Upper Digits
1785
1858
  @origin_of_MSC ||= - +@border.behavior if @border
1786
1859
  @origin_of_MSC = Pair._en_number(@origin_of_MSC)
@@ -1840,6 +1913,8 @@ module When::Coordinates
1840
1913
  m = ids[date[-1]] if (ids)
1841
1914
  return Pair._force_pair(m) if (ids && m)
1842
1915
  return Pair.new(+date[-1]+@base[date.length-1], 0)
1916
+ rescue ArgumentError
1917
+ nil
1843
1918
  end
1844
1919
 
1845
1920
  #
@@ -1862,6 +1937,8 @@ module When::Coordinates
1862
1937
  return i + date[-1].branch - digit.branch if i
1863
1938
  end
1864
1939
  return nil
1940
+ rescue ArgumentError
1941
+ nil
1865
1942
  end
1866
1943
  end
1867
1944
 
@@ -1872,9 +1949,26 @@ module When::Coordinates
1872
1949
  # 処理を @note or @formula[0] (When::Ephemeris::Formula) に委譲する
1873
1950
  #
1874
1951
  def method_missing(name, *args, &block)
1875
- return @note.send(name.to_sym, *(args + [self]), &block) if note.respond_to?(name)
1876
- forward = forwarded_formula(name, args[0]) if self.respond_to?(:forwarded_formula, true)
1877
- return forward.send(name.to_sym, *args, &block) if forward
1952
+ unless When::Parts::MethodCash::Escape.key?(name)
1953
+ if note.respond_to?(name)
1954
+ instance_eval %Q{
1955
+ def #{name}(*args, &block)
1956
+ @note.send("#{name}", *(args + [self]), &block)
1957
+ end
1958
+ } unless When::Parts::MethodCash.escape(name)
1959
+ return @note.send(name, *(args + [self]), &block)
1960
+ elsif respond_to?(:forwarded_formula, true)
1961
+ instance_eval %Q{
1962
+ def #{name}(*args, &block)
1963
+ forward = forwarded_formula("#{name}", args[0])
1964
+ return forward.send("#{name}", *args, &block) if forward
1965
+ _method_missing("#{name}", *args, &block)
1966
+ end
1967
+ } unless When::Parts::MethodCash.escape(name)
1968
+ forward = forwarded_formula(name, args[0])
1969
+ return forward.send(name, *args, &block) if forward
1970
+ end
1971
+ end
1878
1972
  _method_missing(name, *args, &block)
1879
1973
  end
1880
1974