when_exe 0.3.4 → 0.3.5

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 (168) hide show
  1. data/bin/locales.rb +2 -2
  2. data/bin/when.rb +2 -2
  3. data/lib/when_exe.rb +161 -55
  4. data/lib/when_exe/basictypes.rb +34 -26
  5. data/lib/when_exe/calendarnote.rb +654 -0
  6. data/lib/when_exe/calendartypes.rb +49 -474
  7. data/lib/when_exe/coordinates.rb +141 -34
  8. data/lib/when_exe/core/compatibility.rb +22 -2
  9. data/lib/when_exe/core/extension.rb +47 -3
  10. data/lib/when_exe/ephemeris.rb +82 -109
  11. data/lib/when_exe/googlecalendar.rb +1 -1
  12. data/lib/when_exe/icalendar.rb +26 -14
  13. data/lib/when_exe/inspect.rb +82 -68
  14. data/lib/when_exe/locales/af.rb +1 -1
  15. data/lib/when_exe/locales/ar.rb +1 -1
  16. data/lib/when_exe/locales/az.rb +1 -1
  17. data/lib/when_exe/locales/bg.rb +1 -1
  18. data/lib/when_exe/locales/bn.rb +1 -1
  19. data/lib/when_exe/locales/bs.rb +1 -1
  20. data/lib/when_exe/locales/ca.rb +1 -1
  21. data/lib/when_exe/locales/cs.rb +1 -1
  22. data/lib/when_exe/locales/cy.rb +1 -1
  23. data/lib/when_exe/locales/da.rb +1 -1
  24. data/lib/when_exe/locales/de.rb +1 -1
  25. data/lib/when_exe/locales/de_AT.rb +1 -1
  26. data/lib/when_exe/locales/de_CH.rb +1 -1
  27. data/lib/when_exe/locales/el.rb +1 -1
  28. data/lib/when_exe/locales/en.rb +1 -1
  29. data/lib/when_exe/locales/en_AU.rb +1 -1
  30. data/lib/when_exe/locales/en_CA.rb +1 -1
  31. data/lib/when_exe/locales/en_GB.rb +1 -1
  32. data/lib/when_exe/locales/en_IE.rb +1 -1
  33. data/lib/when_exe/locales/en_IN.rb +1 -1
  34. data/lib/when_exe/locales/en_NZ.rb +1 -1
  35. data/lib/when_exe/locales/en_US.rb +1 -1
  36. data/lib/when_exe/locales/eo.rb +1 -1
  37. data/lib/when_exe/locales/es.rb +1 -1
  38. data/lib/when_exe/locales/es_419.rb +1 -1
  39. data/lib/when_exe/locales/es_AR.rb +1 -1
  40. data/lib/when_exe/locales/es_CL.rb +1 -1
  41. data/lib/when_exe/locales/es_CO.rb +1 -1
  42. data/lib/when_exe/locales/es_CR.rb +1 -1
  43. data/lib/when_exe/locales/es_EC.rb +1 -1
  44. data/lib/when_exe/locales/es_MX.rb +1 -1
  45. data/lib/when_exe/locales/es_PA.rb +1 -1
  46. data/lib/when_exe/locales/es_PE.rb +1 -1
  47. data/lib/when_exe/locales/es_VE.rb +1 -1
  48. data/lib/when_exe/locales/et.rb +1 -1
  49. data/lib/when_exe/locales/eu.rb +1 -1
  50. data/lib/when_exe/locales/fa.rb +1 -1
  51. data/lib/when_exe/locales/fi.rb +1 -1
  52. data/lib/when_exe/locales/fr.rb +1 -1
  53. data/lib/when_exe/locales/fr_CA.rb +1 -1
  54. data/lib/when_exe/locales/fr_CH.rb +1 -1
  55. data/lib/when_exe/locales/gl.rb +1 -1
  56. data/lib/when_exe/locales/he.rb +1 -1
  57. data/lib/when_exe/locales/hi.rb +1 -1
  58. data/lib/when_exe/locales/hi_IN.rb +1 -1
  59. data/lib/when_exe/locales/hr.rb +1 -1
  60. data/lib/when_exe/locales/hu.rb +1 -1
  61. data/lib/when_exe/locales/id.rb +1 -1
  62. data/lib/when_exe/locales/is.rb +1 -1
  63. data/lib/when_exe/locales/it.rb +1 -1
  64. data/lib/when_exe/locales/it_CH.rb +1 -1
  65. data/lib/when_exe/locales/ja.rb +1 -1
  66. data/lib/when_exe/locales/kn.rb +1 -1
  67. data/lib/when_exe/locales/ko.rb +1 -1
  68. data/lib/when_exe/locales/lo.rb +1 -1
  69. data/lib/when_exe/locales/locales.rb +1 -1
  70. data/lib/when_exe/locales/lt.rb +1 -1
  71. data/lib/when_exe/locales/lv.rb +1 -1
  72. data/lib/when_exe/locales/mk.rb +1 -1
  73. data/lib/when_exe/locales/mn.rb +1 -1
  74. data/lib/when_exe/locales/ms.rb +1 -1
  75. data/lib/when_exe/locales/nb.rb +1 -1
  76. data/lib/when_exe/locales/ne.rb +1 -1
  77. data/lib/when_exe/locales/nl.rb +1 -1
  78. data/lib/when_exe/locales/nn.rb +1 -1
  79. data/lib/when_exe/locales/or.rb +1 -1
  80. data/lib/when_exe/locales/pl.rb +1 -1
  81. data/lib/when_exe/locales/pt.rb +1 -1
  82. data/lib/when_exe/locales/pt_BR.rb +1 -1
  83. data/lib/when_exe/locales/rm.rb +1 -1
  84. data/lib/when_exe/locales/ro.rb +1 -1
  85. data/lib/when_exe/locales/ru.rb +1 -1
  86. data/lib/when_exe/locales/sk.rb +1 -1
  87. data/lib/when_exe/locales/sl.rb +1 -1
  88. data/lib/when_exe/locales/sr.rb +1 -1
  89. data/lib/when_exe/locales/sv.rb +1 -1
  90. data/lib/when_exe/locales/sw.rb +1 -1
  91. data/lib/when_exe/locales/th.rb +1 -1
  92. data/lib/when_exe/locales/tl.rb +1 -1
  93. data/lib/when_exe/locales/tr.rb +1 -1
  94. data/lib/when_exe/locales/uk.rb +1 -1
  95. data/lib/when_exe/locales/ur.rb +1 -1
  96. data/lib/when_exe/locales/uz.rb +1 -1
  97. data/lib/when_exe/locales/vi.rb +1 -1
  98. data/lib/when_exe/locales/wo.rb +1 -1
  99. data/lib/when_exe/locales/zh_CN.rb +1 -1
  100. data/lib/when_exe/locales/zh_HK.rb +1 -1
  101. data/lib/when_exe/locales/zh_TW.rb +1 -1
  102. data/lib/when_exe/mini_application.rb +6 -2
  103. data/lib/when_exe/parts/enumerator.rb +13 -8
  104. data/lib/when_exe/parts/geometric_complex.rb +3 -5
  105. data/lib/when_exe/parts/locale.rb +185 -28
  106. data/lib/when_exe/parts/method_cash.rb +20 -10
  107. data/lib/when_exe/parts/resource.rb +154 -76
  108. data/lib/when_exe/parts/timezone.rb +11 -6
  109. data/lib/when_exe/region/bahai.rb +2 -2
  110. data/lib/when_exe/region/balinese.rb +296 -296
  111. data/lib/when_exe/region/chinese.rb +564 -564
  112. data/lib/when_exe/region/chinese_calendar.rb +5 -1
  113. data/lib/when_exe/region/chinese_epoch.rb +47 -102
  114. data/lib/when_exe/region/chinese_twin.rb +798 -0
  115. data/lib/when_exe/region/christian.rb +314 -338
  116. data/lib/when_exe/region/coptic.rb +88 -0
  117. data/lib/when_exe/region/ephemeric_notes.rb +322 -307
  118. data/lib/when_exe/region/french.rb +2 -2
  119. data/lib/when_exe/region/indian.rb +361 -272
  120. data/lib/when_exe/region/iranian.rb +2 -2
  121. data/lib/when_exe/region/islamic.rb +3 -3
  122. data/lib/when_exe/region/japanese.rb +1 -1
  123. data/lib/when_exe/region/japanese_notes.rb +165 -103
  124. data/lib/when_exe/region/japanese_residues.rb +56 -55
  125. data/lib/when_exe/region/japanese_twin.rb +228 -0
  126. data/lib/when_exe/region/javanese.rb +2 -2
  127. data/lib/when_exe/region/jewish.rb +2 -2
  128. data/lib/when_exe/region/korean.rb +4 -4
  129. data/lib/when_exe/region/m17n.rb +19 -19
  130. data/lib/when_exe/region/martian.rb +21 -9
  131. data/lib/when_exe/region/mayan.rb +19 -11
  132. data/lib/when_exe/region/moon.rb +7 -7
  133. data/lib/when_exe/region/nihon_shoki.rb +7 -7
  134. data/lib/when_exe/region/roman.rb +100 -100
  135. data/lib/when_exe/region/shire.rb +130 -147
  136. data/lib/when_exe/region/thai.rb +2 -2
  137. data/lib/when_exe/region/tibetan.rb +2 -2
  138. data/lib/when_exe/region/vietnamese.rb +383 -114
  139. data/lib/when_exe/region/world.rb +112 -129
  140. data/lib/when_exe/timestandard.rb +12 -1
  141. data/lib/when_exe/tmposition.rb +28 -14
  142. data/lib/when_exe/tmreference.rb +96 -93
  143. data/lib/when_exe/version.rb +1 -1
  144. data/test/examples/Terms.m17n +2 -2
  145. data/test/examples/sample.json +16 -0
  146. data/test/examples/sample.xml +1 -1
  147. data/test/test.rb +4 -0
  148. data/test/test/basictypes.rb +2 -2
  149. data/test/test/calendarnote.rb +69 -0
  150. data/test/test/calendartypes.rb +41 -1
  151. data/test/test/coordinates.rb +12 -1
  152. data/test/test/ephemeris.rb +13 -66
  153. data/test/test/icalendar.rb +3 -3
  154. data/test/test/inspect.rb +1 -1
  155. data/test/test/parts.rb +7 -4
  156. data/test/test/region/chinese.rb +45 -0
  157. data/test/test/region/coptic.rb +27 -0
  158. data/test/test/region/indian.rb +1 -1
  159. data/test/test/region/japanese.rb +4 -4
  160. data/test/test/region/jewish.rb +1 -1
  161. data/test/test/region/m17n.rb +7 -5
  162. data/test/test/region/residue.rb +2 -2
  163. data/test/test/region/vietnamese.rb +102 -0
  164. data/test/test/timestandard.rb +81 -0
  165. data/test/test/tmposition.rb +1 -1
  166. data/test/test/tmreference.rb +1 -1
  167. data/when_exe.gemspec +2 -2
  168. metadata +16 -7
@@ -0,0 +1,88 @@
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
9
+
10
+ class BasicTypes::M17n
11
+
12
+ CopticTerms = [self, [
13
+ "namespace:[en=http://en.wikipedia.org/wiki/, ja=http://ja.wikipedia.org/wiki/]",
14
+ "locale:[=en:, ja=ja:, alias]",
15
+ "names:[CopticTerms=]",
16
+ "[Coptic=en:Coptic_calendar, コプト暦 ]",
17
+ "[Ethiopian=en:Ethiopian_calendar, エチオピア暦=en:Ethiopian_calendar]",
18
+
19
+ [self,
20
+ "names:[EgyptianMonth=, 月=ja:%%<月_(暦)>]",
21
+ "[tut=, トート= ]",
22
+ "[baba=, バーバ= ]",
23
+ "[hatur=, ハートール= ]",
24
+ "[kiyahak=, キヤハーク= ]",
25
+ "[tuba=, トーバ= ]",
26
+ "[amshir=, アムシール= ]",
27
+ "[baramhat=, バラムハート=]",
28
+ "[barmuda=, バルムーダ= ]",
29
+ "[bashans=, バシャンス= ]",
30
+ "[ba'una=, バウーナ= ]",
31
+ "[abib=, アビーブ= ]",
32
+ "[misra=, ミスラー= ]",
33
+ "[epagomen=, エパゴメネ= ]"
34
+ ],
35
+
36
+ [self,
37
+ "names:[EthiopianMonth=, 月=ja:%%<月_(暦)>]",
38
+ "[Mäskäräm=, マスカラム= ]",
39
+ "[Ṭəqəmt=, テケルト= ]",
40
+ "[Ḫədar=, ヘダル= ]",
41
+ "[Taḫśaś=, ターサス= ]",
42
+ "[Ṭərr=, テル= ]",
43
+ "[Yäkatit=, イェカティト=]",
44
+ "[Mägabit=, メガビト= ]",
45
+ "[Miyazya=, ミアジア= ]",
46
+ "[Gənbot=, ゲエンポト= ]",
47
+ "[Säne=, セネ= ]",
48
+ "[Ḥamle=, ハムレ= ]",
49
+ "[Nähase=, ネハッセ= ]",
50
+ "[Ṗagʷəmen=, パゴウメン= ]"
51
+ ]
52
+ ]]
53
+ end
54
+
55
+ module CalendarTypes
56
+
57
+ _egyptian_month_indices = [
58
+ When::Coordinates::Index.new({:unit =>13, :trunk=>When::Parts::Resource._instance('_m:CopticTerms::EgyptianMonth::*')}),
59
+ When::Coordinates::Index.new
60
+ ]
61
+
62
+ _ethiopian_month_indices = [
63
+ When::Coordinates::Index.new({:unit =>13, :trunk=>When::Parts::Resource._instance('_m:CopticTerms::EthiopianMonth::*')}),
64
+ When::Coordinates::Index.new
65
+ ]
66
+
67
+ #
68
+ # Coptic Calendar in Egypt and Ethiopia
69
+ #
70
+ Coptic = [{'Epoch'=>{'284Y'=>{'origin_of_MSC' => 1,
71
+ 'label' => Parts::Resource._instance('_m:CopticTerms::Coptic'),
72
+ 'indices' => _egyptian_month_indices},
73
+ '8Y'=>{'origin_of_MSC' => 277,
74
+ 'label' => Parts::Resource._instance('_m:CopticTerms::Ethiopian'),
75
+ 'indices' => _ethiopian_month_indices}}}, CyclicTableBased, {
76
+ 'label' => Parts::Resource._instance('_m:CopticTerms::Coptic'),
77
+ 'origin_of_LSC' => 1825030,
78
+ 'origin_of_MSC' => 1,
79
+ 'epoch_in_CE' => 285,
80
+ 'indices' => _egyptian_month_indices,
81
+ 'rule_table' => {
82
+ 'T' => {'Rule' =>[365,365,366,365]},
83
+ 365 => {'Length'=>[30]*12+[5]},
84
+ 366 => {'Length'=>[30]*12+[6]}
85
+ }
86
+ }]
87
+ end
88
+ end
@@ -8,346 +8,361 @@
8
8
  #
9
9
  # Ephemeris を用いる暦注
10
10
  #
11
- module When::CalendarTypes
12
-
13
- class CalendarNote
14
- #
15
- # 太陽と月の位置によるイベント
16
- #
17
- class LuniSolarPositions < self
18
-
19
- # 座標の分子
20
- #
21
- # @return [Numeric]
22
- #
23
- attr_reader :num
24
-
25
- # 座標の分母
26
- #
27
- # @return [Numeric]
28
- #
29
- attr_reader :den
30
-
31
- # 計算アルゴリズム
32
- #
33
- # @return [When::Ephemeris::Formula]
34
- #
35
- attr_reader :formula
36
-
37
- # enumerator の周期
38
- #
39
- # @return [Numeric]
40
- #
41
- attr_reader :delta
42
-
43
- # 没滅計算用の補正
44
- #
45
- # @return [Numeric]
46
- #
47
- attr_reader :margin
48
-
49
- # イベントの日時
50
- #
51
- # @param [When::TM::TemporalPosition] date イベントを探す基準とする日時
52
- # @param [Array<Numeric>] parameter 座標の分子と分母( num, den)
53
- #
54
- # num 座標の分子 (デフォルト @num)
55
- #
56
- # den 座標の分母 (デフォルト @den)
57
- #
58
- # @param [String] parameter 座標の分子と分母("#{ num }/#{ den }" の形式)
59
- # @param [Integer] precision 取得したい時間位置の分解能(デフォルト date の分解能)
60
- #
61
- # @return [When::TM::CalDate] date またはその直後のイベントの日時
62
- #
63
- def term(date, parameter=nil, precision=date.precision)
64
- precision = nil if precision == When::SYSTEM
65
- num, den = parameter.kind_of?(String) ? parameter.split(/\//, 2) : parameter
66
- num = (num || @num).to_f
67
- den = (den || @den).to_f
68
- date = date.floor(precision) if precision
69
- options = date._attr
70
- quot, mod = (@formula.time_to_cn(date)*30.0).divmod(den)
71
- cycle = quot * den + num
72
- cycle += den if mod > (num % den)
73
- time = When::TM::JulianDate._d_to_t(@formula.cn_to_time(cycle/30.0))
74
- time = date.time_standard.from_dynamical_time(time) if @formula.is_dynamical
75
- date = date.frame.jul_trans(When::TM::JulianDate.universal_time(time), options)
76
- precision ? date.floor(precision) : date
77
- end
11
+ class When::CalendarNote
12
+ #
13
+ # 太陽と月の位置によるイベント
14
+ #
15
+ class LuniSolarPositions < self
78
16
 
79
- # 日付に対応する座標
80
- #
81
- # @param [When::TM::TemporalPosition] date 日付
82
- # @param [Numeric] delta 周期の補正(土用の時刻の補正に使用,デフォルト 0)
83
- #
84
- # @return [Array<Integer>] Array< Integer, 0 or 1 or 2 >
85
- #
86
- # [Integer] 対応する座標
87
- #
88
- # [0 or 1 or 2] 座標の進み(0 なら 没, 2 なら滅)
89
- #
90
- def position(date, delta=0)
91
- date = date.floor
92
- p0, p1 = [date, date.succ].map {|d| (30.0 * @formula.time_to_cn(d) - @margin + delta).floor}
93
- [p1 % @den, p1 - p0]
94
- end
17
+ # 座標の分子
18
+ #
19
+ # @return [Numeric]
20
+ #
21
+ attr_reader :num
95
22
 
96
- #
97
- # イベントの標準的な間隔を返す
98
- #
99
- # @param [String] parameter 座標の分子と分母("#{ num }/#{ den }" の形式)
100
- #
101
- # @return [When::TM::IntervalLength]
102
- def term_delta(parameter=nil)
103
- return @delta unless parameter
104
- num, den = parameter.split(/\//, 2)
105
- When::TM::IntervalLength.new([(den || @den).to_f-1,1].max, 'day')
106
- end
107
- end
23
+ # 座標の分母
24
+ #
25
+ # @return [Numeric]
26
+ #
27
+ attr_reader :den
108
28
 
29
+ # 計算アルゴリズム
109
30
  #
110
- # 二十四節気
31
+ # @return [When::Ephemeris::Formula]
111
32
  #
112
- class SolarTerms < LuniSolarPositions
33
+ attr_reader :formula
113
34
 
114
- private
35
+ # enumerator の周期
36
+ #
37
+ # @return [Numeric]
38
+ #
39
+ attr_reader :delta
115
40
 
116
- # オブジェクトの正規化
117
- # num - 太陽黄経/度の分子 (デフォルト 0 - 春分)
118
- # den - 太陽黄経/度の分母 (デフォルト 360 - 1年)
119
- # formula - 計算アルゴリズム(デフォルト '_ep:Formula?formula=12S')
120
- # delta - enumerator の周期 (デフォルト (den/360)年)
121
- # margin - 没滅計算用の補正 (デフォルト 1E-8)
122
- def _normalize(args=[], options={})
123
- num, den, formula, delta, margin = args
124
- @num = (num || @num || 0).to_f
125
- @den = (den || @den || 360).to_f
126
- @formula = When.Resource(formula || @formula ||'Formula?formula=12S', '_ep:')
127
- @delta = When.Duration(delta || @delta || When::TM::IntervalLength.new(@den/360, 'year'))
128
- @margin = (margin || @margin || 1E-8).to_f
129
- super
130
- end
131
- end
41
+ # 没滅計算用の補正
42
+ #
43
+ # @return [Numeric]
44
+ #
45
+ attr_reader :margin
132
46
 
47
+ # イベントの日時
48
+ #
49
+ # @param [When::TM::TemporalPosition] date イベントを探す基準とする日時
50
+ # @param [Array<Numeric>] parameter 座標の分子と分母( num, den)
51
+ #
52
+ # num 座標の分子 (デフォルト @num)
133
53
  #
134
- # 月の位相
54
+ # den 座標の分母 (デフォルト @den)
135
55
  #
136
- class LunarPhases < LuniSolarPositions
56
+ # @param [String] parameter 座標の分子と分母("#{ num }/#{ den }" の形式)
57
+ # @param [Integer] precision 取得したい時間位置の分解能(デフォルト date の分解能)
58
+ #
59
+ # @return [When::TM::CalDate] date またはその直後のイベントの日時
60
+ #
61
+ def event(date, parameter=nil, precision=date.precision)
62
+ num, den = parameter.kind_of?(String) ? parameter.split(/\//, 2) : parameter
63
+ num = (num || @num).to_f
64
+ den = (den || @den).to_f
65
+ date = date.floor(precision) if precision < date.precision
66
+ options = date._attr
67
+ is_date_and_time = options.key?(:clock) || precision > When::DAY
68
+ options[:precision] = precision
69
+ options[:clock] ||= date.frame.time_basis || When::TM::Clock.local_time
70
+ quot, mod = (@formula.time_to_cn(date)*30.0).divmod(den)
71
+ cycle = quot * den + num
72
+ cycle += den if mod > (num % den)
73
+ time = When::TM::JulianDate._d_to_t(@formula.cn_to_time(cycle/30.0))
74
+ time = date.time_standard.from_dynamical_time(time) if @formula.is_dynamical
75
+ event = date.frame.jul_trans(When::TM::JulianDate.universal_time(time), options)
76
+ is_date_and_time ? event : event.to_cal_date
77
+ end
137
78
 
138
- private
79
+ # 日付に対応する座標
80
+ #
81
+ # @param [When::TM::TemporalPosition] date 日付
82
+ # @param [Numeric] delta 周期の補正(土用の時刻の補正に使用,デフォルト 0)
83
+ #
84
+ # @return [Array<Integer>] Array< Integer, 0 or 1 or 2 >
85
+ #
86
+ # [Integer] 対応する座標
87
+ #
88
+ # [0 or 1 or 2] 座標の進み(0 なら 没, 2 なら滅)
89
+ #
90
+ def position(date, delta=0)
91
+ date = date.floor
92
+ p0, p1 = [date, date.succ].map {|d| (30.0 * @formula.time_to_cn(d) - @margin + delta).floor}
93
+ [p1 % @den, p1 - p0]
94
+ end
139
95
 
140
- # オブジェクトの正規化
141
- # num - 月の位相/12度の分子 (デフォルト 0 - 朔)
142
- # den - 月の位相/12度の分母 (デフォルト 30 - 1月)
143
- # formula - 計算アルゴリズム(デフォルト '_ep:Formula?formula=1L')
144
- # delta - enumerator の周期 (デフォルト (den/30)月)
145
- # margin - 没滅計算用の補正 (デフォルト 1E-8)
146
- def _normalize(args=[], options={})
147
- num, den, formula, delta, margin = args
148
- @num = (num || @num || 0).to_f
149
- @den = (den || @den || 30).to_f
150
- @formula = When.Resource(formula || @formula ||'Formula?formula=1L', '_ep:')
151
- @delta = When.Duration(delta || @delta || When::TM::IntervalLength.new(@den/30, 'month'))
152
- @margin = (margin || @margin || 1E-8).to_f
153
- super
154
- end
96
+ #
97
+ # イベントの標準的な間隔を返す
98
+ #
99
+ # @param [String] parameter 座標の分子と分母("#{ num }/#{ den }" の形式)
100
+ #
101
+ # @return [When::TM::IntervalLength]
102
+ def event_delta(parameter=nil)
103
+ return @delta unless parameter
104
+ num, den = parameter.split(/\//, 2)
105
+ When::TM::IntervalLength.new([(den || @den).to_f,1].max*0.9, 'day')
155
106
  end
107
+ end
108
+
109
+ #
110
+ # 二十四節気
111
+ #
112
+ class SolarTerms < LuniSolarPositions
156
113
 
114
+ # 二十四節気のための event の別名
157
115
  #
158
- # 天体暦の暦注
116
+ # @return [When::TM::CalDate] date またはその直後のイベントの日時
117
+ alias :term :event
118
+
119
+ private
120
+
121
+ # 二十四節気のための event_delta の別名
122
+ alias :term_delta :event_delta
123
+
124
+ # オブジェクトの正規化
125
+ # num - 太陽黄経/度の分子 (デフォルト 0 - 春分)
126
+ # den - 太陽黄経/度の分母 (デフォルト 360 - 1年)
127
+ # formula - 計算アルゴリズム(デフォルト '_ep:Formula?formula=12S')
128
+ # delta - enumerator の周期 (デフォルト (den/360)年)
129
+ # margin - 没滅計算用の補正 (デフォルト 1E-8)
130
+ def _normalize(args=[], options={})
131
+ num, den, formula, delta, margin = args
132
+ @num = (num || @num || 0).to_f
133
+ @den = (den || @den || 360).to_f
134
+ @formula = When.Resource(formula || @formula ||'Formula?formula=12S', '_ep:')
135
+ @delta = When.Duration(delta || @delta || When::TM::IntervalLength.new(@den/360, 'year'))
136
+ @margin = (margin || @margin || 1E-8).to_f
137
+ super
138
+ end
139
+ end
140
+
141
+ #
142
+ # 月の位相
143
+ #
144
+ class LunarPhases < LuniSolarPositions
145
+
146
+ # 月の位相のための event の別名
159
147
  #
160
- class EphemericNote < self
148
+ # @return [When::TM::CalDate] date またはその直後のイベントの日時
149
+ alias :phase :event
150
+
151
+ private
152
+
153
+ # 月の位相のための event_delta の別名
154
+ alias :phase_delta :event_delta
155
+
156
+ # オブジェクトの正規化
157
+ # num - 月の位相/12度の分子 (デフォルト 0 - 朔)
158
+ # den - 月の位相/12度の分母 (デフォルト 30 - 1月)
159
+ # formula - 計算アルゴリズム(デフォルト '_ep:Formula?formula=1L')
160
+ # delta - enumerator の周期 (デフォルト (den/30)月)
161
+ # margin - 没滅計算用の補正 (デフォルト 1E-8)
162
+ def _normalize(args=[], options={})
163
+ num, den, formula, delta, margin = args
164
+ @num = (num || @num || 0).to_f
165
+ @den = (den || @den || 30).to_f
166
+ @formula = When.Resource(formula || @formula ||'Formula?formula=1L', '_ep:')
167
+ @delta = When.Duration(delta || @delta || When::TM::IntervalLength.new(@den/30, 'month'))
168
+ @margin = (margin || @margin || 1E-8).to_f
169
+ super
170
+ end
171
+ end
161
172
 
162
- NoteObjects = [When::BasicTypes::M17n, [
163
- "namespace:[en=http://en.wikipedia.org/wiki/, ja=http://ja.wikipedia.org/wiki/]",
164
- "locale:[=en:, ja=ja:, alias=ja:]",
165
- "names:[Ephemeric]",
173
+ #
174
+ # 天体暦の暦注
175
+ #
176
+ class EphemericNote < self
166
177
 
167
- # 年の暦注 ----------------------------
168
- [When::BasicTypes::M17n,
169
- "names:[year]"
170
- ],
178
+ NoteObjects = [When::BasicTypes::M17n, [
179
+ "namespace:[en=http://en.wikipedia.org/wiki/, ja=http://ja.wikipedia.org/wiki/]",
180
+ "locale:[=en:, ja=ja:, alias=ja:]",
181
+ "names:[Ephemeric]",
182
+
183
+ # 年の暦注 ----------------------------
184
+ [When::BasicTypes::M17n,
185
+ "names:[year]"
186
+ ],
171
187
 
172
- # 月の暦注 ----------------------------
188
+ # 月の暦注 ----------------------------
189
+ [When::BasicTypes::M17n,
190
+ "names:[month]",
173
191
  [When::BasicTypes::M17n,
174
- "names:[month]",
192
+ "names:[Month]"
193
+ ]
194
+ ],
195
+
196
+ # 日の暦注 ----------------------------
197
+ [When::BasicTypes::M17n,
198
+ "names:[day]",
199
+ "[Sunrise, 日の出 ]", # 日の出
200
+ "[Sunset, 日の入り ]", # 日の入り
201
+ [When::Coordinates::Residue,
202
+ "label:[Moon_Age=, 正午月齢=ja:%%<月齢>]",
203
+ "divisor:60",
204
+ "format:[%s(%4.1f)]"
205
+ ],
206
+ "[Moonrise, 月の出 ]", # 月の出
207
+ "[Moonset=, 月の入り ]", # 月の入り
175
208
  [When::BasicTypes::M17n,
176
- "names:[Month]"
209
+ "names:[Tide, 潮汐]", # 満潮干潮日時
210
+ "[High_Tide=en:Tide, 満潮=ja:%%<潮汐>]",
211
+ "[Low_Tide=en:Tide, 干潮=ja:%%<潮汐>]"
177
212
  ]
178
- ],
213
+ ]
214
+ ]]
179
215
 
180
- # 日の暦注 ----------------------------
181
- [When::BasicTypes::M17n,
182
- "names:[day]",
183
- "[Sunrise, 日の出 ]", # 日の出
184
- "[Sunset, 日の入り ]", # 日の入り
185
- [When::Coordinates::Residue,
186
- "label:[Moon_Age=, 正午月齢=ja:%%<月齢>]",
187
- "divisor:60",
188
- "format:[%s(%4.1f)]"
189
- ],
190
- "[Moonrise, 月の出 ]", # 月の出
191
- "[Moonset=, 月の入り ]", # 月の入り
192
- [When::BasicTypes::M17n,
193
- "names:[Tide, 潮汐]", # 満潮干潮日時
194
- "[High_Tide=en:Tide, 満潮=ja:%%<潮汐>]",
195
- "[Low_Tide=en:Tide, 干潮=ja:%%<潮汐>]"
196
- ]
197
- ]
198
- ]]
199
-
200
- #
201
- # 日の出
202
- #
203
- # @param [When::TM::TemporalPosition] date
204
- # @param [Hash] options dummy
205
- #
206
- # @return [When::TM::TemporalPosition] 日の出の時刻をイベント時刻とする
207
- #
208
- def sunrise(date, options={})
209
- event = formula(date.location.iri).sunrise(date)
210
- event.events = [@root['Sunrise']]
211
- event
212
- rescue
213
- nil
214
- end
216
+ #
217
+ # 日の出
218
+ #
219
+ # @param [When::TM::TemporalPosition] date
220
+ # @param [Hash] options dummy
221
+ #
222
+ # @return [When::TM::TemporalPosition] 日の出の時刻をイベント時刻とする
223
+ #
224
+ def sunrise(date, options={})
225
+ event = formula(date.location.iri).sunrise(date)
226
+ event.events = [@root['Sunrise']]
227
+ event
228
+ rescue
229
+ nil
230
+ end
215
231
 
216
- #
217
- # 日の入り
218
- #
219
- # @param [When::TM::TemporalPosition] date
220
- # @param [Hash] options dummy
221
- #
222
- # @return [When::TM::TemporalPosition] 日の入りの時刻をイベント時刻とする
223
- #
224
- def sunset(date, options={})
225
- event = formula(date.location.iri).sunset(date)
226
- event.events = [@root['Sunset']]
227
- event
228
- rescue
229
- nil
230
- end
232
+ #
233
+ # 日の入り
234
+ #
235
+ # @param [When::TM::TemporalPosition] date
236
+ # @param [Hash] options dummy
237
+ #
238
+ # @return [When::TM::TemporalPosition] 日の入りの時刻をイベント時刻とする
239
+ #
240
+ def sunset(date, options={})
241
+ event = formula(date.location.iri).sunset(date)
242
+ event.events = [@root['Sunset']]
243
+ event
244
+ rescue
245
+ nil
246
+ end
231
247
 
232
- #
233
- # 正午月齢
234
- #
235
- # @param [When::TM::TemporalPosition] date
236
- # @param [Hash] options dummy
237
- #
238
- # @return [Numeric] 正午における朔からの経過日数
239
- #
240
- def moon_age(date, options={})
241
- @phase ||= When.CalendarNote('LunarPhases')
242
- noon = date.floor(When::DAY,When::SYSTEM) + 0.5
243
- @root['Moon_Age'][noon.to_f - @phase.term(noon, [-30.0,30.0]).to_f]
244
- end
248
+ #
249
+ # 正午月齢
250
+ #
251
+ # @param [When::TM::TemporalPosition] date
252
+ # @param [Hash] options dummy
253
+ #
254
+ # @return [Numeric] 正午における朔からの経過日数
255
+ #
256
+ def moon_age(date, options={})
257
+ @phase ||= When.CalendarNote('LunarPhases')
258
+ noon = date.floor(When::DAY,When::SYSTEM) + 0.5
259
+ @root['Moon_Age'][noon.to_f - @phase.phase(noon, [-30.0,30.0]).to_f]
260
+ end
245
261
 
246
- #
247
- # 月の出
248
- #
249
- # @param [When::TM::TemporalPosition] date
250
- # @param [Hash] options dummy
251
- #
252
- # @return [When::TM::TemporalPosition] 月の出の時刻をイベント時刻とする
253
- #
254
- def moonrise(date, options={})
255
- event = formula(date.location.iri).moonrise(date)
256
- event.events = [@root['Moonrise']]
257
- event
258
- rescue
259
- nil
260
- end
262
+ #
263
+ # 月の出
264
+ #
265
+ # @param [When::TM::TemporalPosition] date
266
+ # @param [Hash] options dummy
267
+ #
268
+ # @return [When::TM::TemporalPosition] 月の出の時刻をイベント時刻とする
269
+ #
270
+ def moonrise(date, options={})
271
+ event = formula(date.location.iri).moonrise(date)
272
+ event.events = [@root['Moonrise']]
273
+ event
274
+ rescue
275
+ nil
276
+ end
261
277
 
262
- #
263
- # 月の入り
264
- #
265
- # @param [When::TM::TemporalPosition] date
266
- # @param [Hash] options dummy
267
- #
268
- # @return [When::TM::TemporalPosition] 月の入りの時刻をイベント時刻とする
269
- #
270
- def moonset(date, options={})
271
- event = formula(date.location.iri).moonset(date)
272
- event.events = [@root['Moonset']]
273
- event
274
- rescue
275
- nil
276
- end
278
+ #
279
+ # 月の入り
280
+ #
281
+ # @param [When::TM::TemporalPosition] date
282
+ # @param [Hash] options dummy
283
+ #
284
+ # @return [When::TM::TemporalPosition] 月の入りの時刻をイベント時刻とする
285
+ #
286
+ def moonset(date, options={})
287
+ event = formula(date.location.iri).moonset(date)
288
+ event.events = [@root['Moonset']]
289
+ event
290
+ rescue
291
+ nil
292
+ end
277
293
 
278
- # 干潮・満潮の日時
279
- #
280
- # @param [When::TM::TemporalPosition] date
281
- # @param [Hash] options
282
- # @option options [String] tide 潮汐計算方式 'Horizontal' - 地平高度基準, 'Equatorial' - 子午線通過基準(デフォルト)
283
- #
284
- # @return [Array<Array<Integer, When::TM::TemporalPosotion>>] 干潮・満潮の日時の Array
285
- #
286
- # [Integer] +1:満潮, -1:干潮
287
- #
288
- # [When::TM::TemporalPosotion] 干潮・満潮の日時
289
- #
290
- #
291
- def tide(date, options={})
292
- return nil unless @interval
293
- @target ||= When.Resource('_ep:Moon')
294
- events = @root['Tide']
295
- form = formula(date.location.iri)
296
- type = options[:tide] =~ /^horizon/i ? nil : 0
297
-
298
- now = +date
299
- high_tides = []
300
- 5.times do |i|
301
- high_tide = form.day_event(now + i - 2, type, @target) + @interval
302
- high_tides << high_tide if high_tides.size == 0 || high_tide > high_tides[-1] + 0.5
303
- end
304
- tides = []
305
-
306
- (high_tides.size-1).times do |i|
307
- tides << [0, high_tides[i]]
308
- tides << [1, 0.75*high_tides[i] + 0.25*high_tides[i+1]]
309
- tides << [0, 0.50*high_tides[i] + 0.50*high_tides[i+1]]
310
- tides << [1, 0.25*high_tides[i] + 0.75*high_tides[i+1]]
311
- end
312
- tides << [0, high_tides[-1]]
313
-
314
- today = +date.floor(When::DAY)...+date.ceil(When::DAY)
315
- seed = date._attr
316
- seed[:clock] ||= When::TM::Clock.local_time
317
- tides.select {|x| today.include?(x[1])}.map {|x|
318
- d = form._to_seed_type(x[1], seed)
319
- d.events = [events[x[0]]]
320
- d
321
- }
322
- rescue
323
- nil
294
+ # 干潮・満潮の日時
295
+ #
296
+ # @param [When::TM::TemporalPosition] date
297
+ # @param [Hash] options 以下の通り
298
+ # @option options [String] tide 潮汐計算方式 'Horizontal' - 地平高度基準, 'Equatorial' - 子午線通過基準(デフォルト)
299
+ #
300
+ # @return [Array<Array<Integer, When::TM::TemporalPosotion>>] 干潮・満潮の日時の Array
301
+ #
302
+ # [Integer] +1:満潮, -1:干潮
303
+ #
304
+ # [When::TM::TemporalPosotion] 干潮・満潮の日時
305
+ #
306
+ #
307
+ def tide(date, options={})
308
+ return nil unless @interval
309
+ @target ||= When.Resource('_ep:Moon')
310
+ events = @root['Tide']
311
+ form = formula(date.location.iri)
312
+ type = options[:tide] =~ /^horizon/i ? nil : 0
313
+
314
+ now = +date
315
+ high_tides = []
316
+ 5.times do |i|
317
+ high_tide = form.day_event(now + i - 2, type, @target) + @interval
318
+ high_tides << high_tide if high_tides.size == 0 || high_tide > high_tides[-1] + 0.5
324
319
  end
320
+ tides = []
325
321
 
326
- private
327
-
328
- # オブジェクトの正規化
329
- # long - 計算に用いる経度 /
330
- # lat - 計算に用いる緯度 /
331
- # alt - 計算に用いる高度 / m
332
- # interval - 高潮間隔(月の子午線通過から満潮までの時間) / 時間
333
- def _normalize(args=[], options={})
334
- if @location
335
- @location = When.Resource(@location)
336
- @formula = When.Resource(@formula || "Formula?location=(#{@location.iri})", '_ep:')
337
- else
338
- @formula = {}
339
- end
340
- @interval = @interval.sub('@','.').to_f / 24 if @interval
341
- @root = When.CalendarNote('EphemericNote/NoteObjects::day')
342
- @prime ||= [%w(Month), %w(Sunrise Sunset Moon_Age)]
343
- super
322
+ (high_tides.size-1).times do |i|
323
+ tides << [0, high_tides[i]]
324
+ tides << [1, 0.75*high_tides[i] + 0.25*high_tides[i+1]]
325
+ tides << [0, 0.50*high_tides[i] + 0.50*high_tides[i+1]]
326
+ tides << [1, 0.25*high_tides[i] + 0.75*high_tides[i+1]]
344
327
  end
328
+ tides << [0, high_tides[-1]]
329
+
330
+ today = +date.floor(When::DAY)...+date.ceil(When::DAY)
331
+ seed = date._attr
332
+ seed[:clock] ||= When::TM::Clock.local_time
333
+ tides.select {|x| today.include?(x[1])}.map {|x|
334
+ d = form._to_seed_type(x[1], seed)
335
+ d.events = [events[x[0]]]
336
+ d
337
+ }
338
+ rescue
339
+ nil
340
+ end
345
341
 
346
- # 計算に用いる Ephemeris
347
- def formula(location)
348
- return @formula unless @formula.kind_of?(Hash)
349
- @formula[location] ||= When.Resource("Formula?location=(#{location})", '_ep:')
342
+ private
343
+
344
+ # オブジェクトの正規化
345
+ # long - 計算に用いる経度 /
346
+ # lat - 計算に用いる緯度 / 度
347
+ # alt - 計算に用いる高度 / m
348
+ # interval - 高潮間隔(月の子午線通過から満潮までの時間) / 時間
349
+ def _normalize(args=[], options={})
350
+ if @location
351
+ @location = When.Resource(@location)
352
+ @formula = When.Resource(@formula || "Formula?location=(#{@location.iri})", '_ep:')
353
+ else
354
+ @formula = {}
350
355
  end
356
+ @interval = @interval.sub('@','.').to_f / 24 if @interval
357
+ @root = When.CalendarNote('EphemericNote/NoteObjects::day')
358
+ @prime ||= [%w(Month), %w(Sunrise Sunset Moon_Age)]
359
+ super
360
+ end
361
+
362
+ # 計算に用いる Ephemeris
363
+ def formula(location)
364
+ return @formula unless @formula.kind_of?(Hash)
365
+ @formula[location] ||= When.Resource("Formula?location=(#{location})", '_ep:')
351
366
  end
352
367
  end
353
368
  end