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
@@ -22,18 +22,18 @@ module When::Coordinates
22
22
  When::HOUR=>'PT1H', When::MINUTE=>'PT1M', When::SECOND=>'PT1S'}
23
23
  MATCH = {'NS'=>/(N|S|北緯|南緯)/, 'EW'=>/(E|W|東経|西経)/}
24
24
 
25
- # 60進->10進変換
25
+ # 60進->10進変換(1/225度単位)
26
26
  #
27
27
  # @param [String] src 60進法で表した方向付きの数値
28
28
  # @param [String] dir 方向 ('NS' または 'EW')
29
29
  #
30
- # @return [Numeric] 10進変換した数値 (src が nil なら0.0を、Numeric ならそのままsrcを返す)
30
+ # @return [Numeric] 10進変換した数値 (src が nil なら0.0を、Numeric なら 225*src を返す)
31
31
  #
32
- def self.to_deg(src, dir)
32
+ def self.to_deg_225(src, dir)
33
33
  case src
34
34
  when String
35
35
  src = src.gsub(/_+/,'').gsub(/@/, '.')
36
- return src.to_f unless (src =~ MATCH[dir])
36
+ return src.to_r * Spatial::DEGREE if (src =~ /E[-+]/ || src !~ MATCH[dir])
37
37
  sign = ($1 == dir[1..1]) ? -1 : +1
38
38
  value = src.gsub(MATCH[dir], '').strip
39
39
  if ((value + "00000") =~ /^(\d+)\.(\d{2})(\d{2})(\d+)$/)
@@ -42,29 +42,53 @@ module When::Coordinates
42
42
  else
43
43
  deg, min, sec = value.split(/[^\d.]+/)
44
44
  end
45
- return sign * (deg.to_i + (min||0).to_f/60 + (sec||0).to_f/3600)
45
+ return sign * (deg.to_i * Spatial::DEGREE +
46
+ (min||0).to_f * (Spatial::DEGREE/60.0) +
47
+ (sec||0).to_f * (Spatial::DEGREE/3600.0))
46
48
  when NilClass
47
49
  0.0
48
50
  when Numeric
49
- src
51
+ src * Spatial::DEGREE
50
52
  else
51
53
  raise TypeError, "Invalid Location Type"
52
54
  end
53
55
  end
54
56
 
57
+ # 60進->10進変換(度単位)
58
+ #
59
+ # @param [String] src 60進法で表した方向付きの数値
60
+ # @param [String] dir 方向 ('NS' または 'EW')
61
+ #
62
+ # @return [Numeric] 10進変換した数値 (src が nil なら0.0を、Numeric ならそのままsrcを返す)
63
+ #
64
+ def self.to_deg(src, dir)
65
+ to_deg_225(src, dir) / Spatial::DEGREE
66
+ end
67
+
55
68
  # 10進->60進変換
56
69
  #
57
70
  # @param [Numeric] src 数値
58
71
  # @param [String] dir 方向 ('NS' または 'EW')
72
+ # @param [Integer] round 秒の小数点以下最大桁数
59
73
  #
60
74
  # @return [String] 60進変換した数値
61
75
  #
62
- def self.to_dms(src, dir)
76
+ def self.to_dms(src, dir, round=6)
63
77
  dir = (src >= 0) ? dir[0..0] : dir[1..1]
64
- deg, min = src.abs.divmod(1)
65
- min, sec = (60*min).divmod(1)
66
- sec = (60*sec).floor
67
- (['N','S'].include?(dir) ? "%02d.%02d%02d%s" : "%03d.%02d%02d%s") % [deg, min, sec, dir]
78
+ deg, min = src.abs.divmod(1)
79
+ min, sec = (60*min).divmod(1)
80
+ sec = (60*10**round*sec).round
81
+ fig = round + 2
82
+ round.times do
83
+ div, mod = sec.divmod(10)
84
+ if mod == 0
85
+ fig -= 1
86
+ sec = div
87
+ else
88
+ break
89
+ end
90
+ end
91
+ (['N','S'].include?(dir) ? "%02d.%02d%0#{fig}d%s" : "%03d.%02d%0#{fig}d%s") % [deg, min, sec, dir]
68
92
  end
69
93
 
70
94
  #
@@ -503,17 +527,21 @@ module When::Coordinates
503
527
  #
504
528
  def succ
505
529
  value = @current
506
- if (@z==@k) ||
507
- (@count_limit.kind_of?(Numeric) && @count >= @count_limit) ||
530
+ if (@count_limit.kind_of?(Numeric) && @count >= @count_limit) ||
508
531
  (@error.kind_of?(Numeric) && @e && @error >= @e.abs)
509
532
  @current = nil
510
533
  else
511
- @z = 1.0/(@z-@k)
512
- @k = @z.floor
513
- @e = @p[1].to_f/@q[1]-@x.to_f/@y
514
- @current = [@p[1], @q[1], @e]
515
- @p = [@p[1], @p[1]*@k + @p[0]]
516
- @q = [@q[1], @q[1]*@k + @q[0]]
534
+ if @z==@k
535
+ @e = 0
536
+ @current = [@p[1], @q[1], 0]
537
+ else
538
+ @z = 1.0/(@z-@k)
539
+ @k = @z.floor
540
+ @e = @p[1].to_f/@q[1]-@x.to_f/@y
541
+ @current = [@p[1], @q[1], @e]
542
+ @p = [@p[1], @p[1]*@k + @p[0]]
543
+ @q = [@q[1], @q[1]*@k + @q[0]]
544
+ end
517
545
  @count += 1
518
546
  end
519
547
  return value
@@ -1244,6 +1272,14 @@ module When::Coordinates
1244
1272
  end
1245
1273
  end
1246
1274
 
1275
+ # 設定情報を取得する
1276
+ #
1277
+ # @return [Hash] 設定情報
1278
+ #
1279
+ def _setup_info
1280
+ {:location => @default_location}
1281
+ end
1282
+
1247
1283
  # デフォルトの空間位置を読みだす
1248
1284
  #
1249
1285
  # @return [When::Coordinates::Spatial]
@@ -1277,6 +1313,9 @@ module When::Coordinates
1277
1313
  end
1278
1314
  end
1279
1315
 
1316
+ # @private
1317
+ HashProperty = [:label, [:alt, 0.0], [:datum, When::Ephemeris::Earth], :ref]
1318
+
1280
1319
  # Degree / Internal Location Unit(16")
1281
1320
  #
1282
1321
  # (3600 を 2 の因数で割りつくした値を単位とする)
@@ -1336,6 +1375,32 @@ module When::Coordinates
1336
1375
  #
1337
1376
  attr_reader :tz
1338
1377
 
1378
+ # 緯度文字列
1379
+ #
1380
+ # @param [Integer] round 秒の小数点以下最大桁数
1381
+ #
1382
+ # @return [String] 緯度文字列(DD.MMSSsss[NS])
1383
+ #
1384
+ def lat_s
1385
+ When::Coordinates.to_dms(lat / When::Coordinates::Spatial::DEGREE, 'NS', round=6)
1386
+ end
1387
+
1388
+ # 経度文字列
1389
+ #
1390
+ # @param [Integer] round 秒の小数点以下最大桁数
1391
+ #
1392
+ # @return [String] 経度文字列(DDD.MMSSsss[EW])
1393
+ #
1394
+ def long_s
1395
+ When::Coordinates.to_dms(long / When::Coordinates::Spatial::DEGREE, 'EW', round=6)
1396
+ end
1397
+
1398
+ # 高度 / m
1399
+ #
1400
+ # @return [Numeric]
1401
+ # @return [:Center] 天体の中心の場合
1402
+ #
1403
+ attr_reader :alt
1339
1404
  # 観測地の地心距離 / kmを返します。
1340
1405
  #
1341
1406
  # @return [Numeric]
@@ -1395,17 +1460,20 @@ module When::Coordinates
1395
1460
 
1396
1461
  # 要素の正規化
1397
1462
  def _normalize(args=[], options={})
1398
- @long = When::Coordinates.to_deg(@long, 'EW') * DEGREE if @long
1399
- @lat = When::Coordinates.to_deg(@lat, 'NS') * DEGREE if @lat
1400
- @datum = When.Resource(@datum || 'Earth', '_ep:')
1401
- if @tz.kind_of?(String)
1402
- @label ||= @tz
1403
- @tz = When::Parts::Timezone.tz_info[@tz]
1404
- end
1463
+
1464
+ # 時間帯による指定
1465
+ @tz = When::Parts::Timezone.tz_info[@tz] if @tz.kind_of?(String)
1405
1466
  if @tz
1406
- @long ||= @tz.longitude * DEGREE
1407
- @lat ||= @tz.latitude * DEGREE
1467
+ @label ||= @tz.label
1468
+ @long ||= @tz.longitude
1469
+ @lat ||= @tz.latitude
1408
1470
  end
1471
+
1472
+ # データの整形
1473
+ @label = When::BasicTypes::M17n.new(@label) if @label.kind_of?(Hash)
1474
+ @long = When::Coordinates.to_deg_225(@long, 'EW') if @long
1475
+ @lat = When::Coordinates.to_deg_225(@lat, 'NS') if @lat
1476
+ @datum = When.Resource(@datum || 'Earth', '_ep:')
1409
1477
  @long ||= 0.0
1410
1478
  @lat ||= 0.0
1411
1479
  @alt =
@@ -1416,6 +1484,21 @@ module When::Coordinates
1416
1484
  end
1417
1485
  end
1418
1486
 
1487
+ #
1488
+ # 空間位置オブジェクトの内容を Hash 化
1489
+ #
1490
+ # @param [Object] options When::Parts::Resource#to_h を参照
1491
+ # @option options [Symbol] :method :to_h を label の内容の Hash 書き出しのために追加
1492
+ #
1493
+ # @return [Hash] Hash 化した空間位置オブジェクト
1494
+ #
1495
+ def _to_h(options={})
1496
+ hash = super
1497
+ hash[:long] = long_s
1498
+ hash[:lat] = lat_s
1499
+ hash
1500
+ end
1501
+
1419
1502
  # 観測地の惑星中心を原点とする三次元座標
1420
1503
  #
1421
1504
  # @param [Numeric] t ユリウス日(Terrestrial Time)
@@ -1502,7 +1585,7 @@ module When::Coordinates
1502
1585
  # Formula
1503
1586
  instance_eval('class << self; attr_reader :formula; end') if @location && @border
1504
1587
  if respond_to?(:formula)
1505
- instance_eval('class << self; include When::Ephemeris::Formula::Methods; end')
1588
+ instance_eval('class << self; include When::Ephemeris::Formula::ForwardedFormula; end')
1506
1589
  @formula ||= When::Ephemeris::Formula.new({:location=>@location})
1507
1590
  @formula = When.Resource(Array(@formula), '_ep:')
1508
1591
  end
@@ -1587,10 +1670,10 @@ module When::Coordinates
1587
1670
 
1588
1671
  # 代表暦注
1589
1672
  #
1590
- # @return [When::CalendarTypes::CalendarNote]
1673
+ # @return [When::CalendarNote]
1591
1674
  # @return [Array<Array<klass, Array<klass, method, block>>>] 最外側のArray要素は年・月・日に対応
1592
1675
  #
1593
- # klass [String, When::CalendarTypes::CalendarNote, When::Coordinates::Residue]
1676
+ # klass [String, When::CalendarNote, When::Coordinates::Residue]
1594
1677
  #
1595
1678
  # method [String, Symbol] (デフォルト 'day', 'month' or 'year' (対応する桁による))
1596
1679
  #
@@ -1644,6 +1727,13 @@ module When::Coordinates
1644
1727
  @_diff_to_CE ||= @epoch_in_CE ? @epoch_in_CE - @origin_of_MSC : 0
1645
1728
  end
1646
1729
 
1730
+ # @private
1731
+ #
1732
+ # 対応する ::Date の start 属性
1733
+ def _default_start
1734
+ ::Date::GREGORIAN
1735
+ end
1736
+
1647
1737
  # protected
1648
1738
 
1649
1739
  #
@@ -1946,7 +2036,13 @@ module When::Coordinates
1946
2036
 
1947
2037
  # その他のメソッド
1948
2038
  # When::Coordinates::Temporal で定義されていないメソッドは
1949
- # 処理を @note or @formula[0] (When::Ephemeris::Formula) に委譲する
2039
+ # 処理を下記に移譲する(番号は優先順位)
2040
+ # When::CalendarNote
2041
+ # (1) @note
2042
+ # (2) SolarTerms
2043
+ # (3) LunarPhases
2044
+ # When::Ephemeris::Formula
2045
+ # (4)@formula[0]
1950
2046
  #
1951
2047
  def method_missing(name, *args, &block)
1952
2048
  unless When::Parts::MethodCash::Escape.key?(name)
@@ -1957,9 +2053,20 @@ module When::Coordinates
1957
2053
  end
1958
2054
  } unless When::Parts::MethodCash.escape(name)
1959
2055
  return @note.send(name, *(args + [self]), &block)
1960
- elsif When::Ephemeris::Formula.method_defined?(name)
2056
+ end
2057
+ ['SolarTerms', 'LunarPhases'].each do |note|
2058
+ if When.CalendarNote(note).respond_to?(name)
2059
+ instance_eval %Q{
2060
+ def #{name}(*args, &block)
2061
+ When.CalendarNote("#{note}").send("#{name}", *args, &block)
2062
+ end
2063
+ } unless When::Parts::MethodCash.escape(name)
2064
+ return When.CalendarNote(note).send(name, *args, &block)
2065
+ end
2066
+ end
2067
+ if When::Ephemeris::Formula.method_defined?(name)
1961
2068
  unless respond_to?(:forwarded_formula, true)
1962
- instance_eval('class << self; include When::Ephemeris::Formula::Methods; end')
2069
+ instance_eval('class << self; include When::Ephemeris::Formula::ForwardedFormula; end')
1963
2070
  @formula ||= When::Ephemeris::Formula.new({:location=>@location})
1964
2071
  @formula = When.Resource(Array(@formula), '_ep:')
1965
2072
  end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  =begin
3
- Copyright (C) 2013 Takashi SUGA
3
+ Copyright (C) 2013-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
@@ -33,7 +33,7 @@ class String
33
33
  def to_r
34
34
  case self
35
35
  when /\.|E/i
36
- to_f
36
+ to_f.to_r
37
37
  when /\//
38
38
  Rational
39
39
  Rational(*split(/\//).map {|v| v.to_i})
@@ -54,6 +54,26 @@ class String
54
54
  end
55
55
  end
56
56
 
57
+ #
58
+ # 浮動小数点数
59
+ #
60
+ class Float
61
+ unless const_defined?(:INFINITY)
62
+ # @private
63
+ INFINITY = MAX
64
+ end
65
+
66
+ unless method_defined?(:to_r)
67
+ Rational
68
+ # @private
69
+ def to_r
70
+ it = When::Coordinates::Residue.new(self, 1).enum_for
71
+ res = it.succ while it.has_next?
72
+ Rational(*res[0..1])
73
+ end
74
+ end
75
+ end
76
+
57
77
  #
58
78
  # 例外クラス
59
79
  #
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  =begin
3
- Copyright (C) 2013 Takashi SUGA
3
+ Copyright (C) 2013-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
@@ -19,7 +19,7 @@ class Time
19
19
  #
20
20
  # 対応する When::TM::JulianDate を生成
21
21
  #
22
- # @param [Hash] options
22
+ # @param [Hash] options 以下の通り
23
23
  # @option options [When::TM::Clock] :clock
24
24
  # @option options [When::Parts::Timezone] :tz
25
25
  #
@@ -55,7 +55,27 @@ end
55
55
  #
56
56
  class Date
57
57
 
58
- include When::TM::TemporalPosition::Conversion if When::TM.const_defined?(:TemporalPosition)
58
+ if When::TM.const_defined?(:TemporalPosition)
59
+
60
+ include When::TM::TemporalPosition::Conversion
61
+
62
+ #
63
+ # 対応する When::TM::CalDate or DateAndTime を生成
64
+ #
65
+ # @param [Hash] options 暦法や時法などの指定
66
+ # see {When::TM::TemporalPosition._instance}
67
+ #
68
+ # @return [When::TM::CalDate, When::TM::DateAndTime]
69
+ #
70
+ # @note 暦法の指定がない場合、start メソッドの値によって
71
+ # Julian / Gregorian / Civil 暦法を選択する
72
+ #
73
+ def tm_position(options={})
74
+ options[:frame] ||= When::CalendarTypes::Christian._default_start(self)
75
+ super(options)
76
+ end
77
+ alias :to_tm_position :tm_position
78
+ end
59
79
 
60
80
  alias :__method_missing :method_missing
61
81
 
@@ -130,6 +150,18 @@ class Numeric
130
150
  end
131
151
  alias :pair :to_pair
132
152
 
153
+ #
154
+ # self を秒数とみなして When::Parts::Timezone::Base を取得
155
+ #
156
+ # @return [When::Parts::Timezone::Base]
157
+ #
158
+ # @note core/extension
159
+ #
160
+ def clock
161
+ When.Clock(self)
162
+ end
163
+ alias :to_clock :clock
164
+
133
165
  # メソッド名に相当する単位で表した When::TM::IntervalLength
134
166
  # @method unit_interval_length
135
167
  # @return [When::TM::IntervalLength]
@@ -233,6 +265,18 @@ class String
233
265
  end
234
266
  alias :to_calendar :calendar
235
267
 
268
+ #
269
+ # self を時間帯文字列とみなして When::Parts::Timezone::Base を取得
270
+ #
271
+ # @return [When::Parts::Timezone::Base]
272
+ #
273
+ # @note core/extension
274
+ #
275
+ def clock
276
+ When.Clock(self)
277
+ end
278
+ alias :to_clock :clock
279
+
236
280
  #
237
281
  # self をプレフィクス '_c:' を省略した IRI とみなして When::TM::CalendarNote を取得
238
282
  #
@@ -1147,35 +1147,7 @@ module When::Ephemeris
1147
1147
  #
1148
1148
  # 天体暦機能を When::TM::Calendar クラスに提供する
1149
1149
  #
1150
- module Methods
1151
-
1152
- # 月の位相が指定の周期番号パターンになる最も近い過去の日時
1153
- #
1154
- # @param [Numeric] date ユリウス日(Terrestrial Time)
1155
- # @param [When::TM::TemporalPosition] date
1156
- # @param [Numeric] n 相対周期番号(n=0 なら date または date の直前が基準)
1157
- # @param [Numeric] d 単位周期数
1158
- #
1159
- # @return [Numeric, When::TM::TemporalPosition] 周期番号が d で割って n になる日時
1160
- #
1161
- def nearest_past_from_lunar_phase(date, n=0, d=1)
1162
- @formula ||= When.Resource(['_ep:Formula?formula=12S', '_ep:Formula?formula=1L'])
1163
- @formula[-1].nearest_past(date, n, d)
1164
- end
1165
-
1166
- # 二十四節気が指定の周期番号パターンになる最も近い過去の日時
1167
- #
1168
- # @param [Numeric] date ユリウス日(Terrestrial Time)
1169
- # @param [When::TM::TemporalPosition] date
1170
- # @param [Numeric] n 相対周期番号(n=0 なら date または date の直前が基準)
1171
- # @param [Numeric] d 単位周期数
1172
- #
1173
- # @return [Numeric, When::TM::TemporalPosition] 周期番号が d で割って n になる日時
1174
- #
1175
- def nearest_past_from_solar_term(date, n=0, d=1)
1176
- @formula ||= When.Resource(['_ep:Formula?formula=12S', '_ep:Formula?formula=1L'])
1177
- @formula[0].nearest_past(date, n, d)
1178
- end
1150
+ module ForwardedFormula
1179
1151
 
1180
1152
  private
1181
1153
 
@@ -1262,18 +1234,17 @@ module When::Ephemeris
1262
1234
  root(time0, cn) {|t| time_to_cn(t)}
1263
1235
  end
1264
1236
 
1265
- # 当該日付のthiti の変化範囲
1237
+ # 当該日付の月の位相の変化範囲
1266
1238
  #
1267
1239
  # @param [When::TM::TemporalPosition] date 日付
1268
1240
  #
1269
- # @return [Range] 当該日付のthiti の変化範囲(朔を含む場合 nil)
1241
+ # @return [Array<Numeric>] 当該日付の月の位相の変化範囲
1270
1242
  #
1271
- def thiti_range(date)
1272
- date = date.floor
1273
- p0, p1 = [date, date.succ].map {|d|
1274
- (30.0 * time_to_cn(d)) % 30.0
1243
+ def phase_range(date)
1244
+ date = date.floor
1245
+ [date, date.succ].map {|d|
1246
+ time_to_cn(d)
1275
1247
  }
1276
- p0 >= p1 ? nil : p0...p1
1277
1248
  end
1278
1249
 
1279
1250
  # 指定の周期番号パターンになる最も近い過去の日時
@@ -1774,6 +1745,52 @@ module When::Ephemeris
1774
1745
  #
1775
1746
  class MeanLunation < Formula
1776
1747
 
1748
+ #
1749
+ # Lunar Calendar Formula
1750
+ #
1751
+ module LunarMethod
1752
+
1753
+ private
1754
+
1755
+ # 周期番号 -> 日時
1756
+ #
1757
+ # @param [Numeric] cn 周期番号
1758
+ # @param [Numeric] time0 日時の初期近似値
1759
+ #
1760
+ # @return [Numeric] ユリウス日
1761
+ #
1762
+ # @note 半ティティの日時の丸め誤差に配慮
1763
+ #
1764
+ def cn_to_time_(cn, time0=nil)
1765
+ time0 ||= (cn - @cycle_number_0m) / @cycle_number_1m
1766
+ return time0 if (cn * 60 - (cn * 60).round).abs > @cycle_precision
1767
+ ((time0 + 1.0/256 - @day_epoch) / @half_tithi).floor * @half_tithi + @day_epoch
1768
+ end
1769
+ end
1770
+
1771
+ #
1772
+ # Solar Calendar Formula for Fixed Year Length Method
1773
+ #
1774
+ module SolarMethod
1775
+
1776
+ private
1777
+
1778
+ # 周期番号 -> 日時
1779
+ #
1780
+ # @param [Numeric] cn 周期番号
1781
+ # @param [Numeric] time0 日時の初期近似値
1782
+ #
1783
+ # @return [Numeric] ユリウス日
1784
+ #
1785
+ # @note 太陽黄経が整数になる日時の丸め誤差に配慮
1786
+ #
1787
+ def cn_to_time_(cn, time0=nil)
1788
+ time0 ||= (cn - @cycle_number_0m) / @cycle_number_1m
1789
+ return time0 if (cn * 360 - (cn * 360).round).abs > @cycle_precision
1790
+ ((time0 + 1.0/256 - @day_epoch) / @solar_degree).floor * @solar_degree + @day_epoch
1791
+ end
1792
+ end
1793
+
1777
1794
  # 計算の基準経度 / 度
1778
1795
  # @return [Numeric]
1779
1796
  attr_reader :long
@@ -1851,88 +1868,44 @@ module When::Ephemeris
1851
1868
 
1852
1869
  private
1853
1870
 
1854
- # 周期番号 -> 日時
1855
- #
1856
- # @param [Numeric] cn 周期番号
1857
- # @param [Numeric] time0 日時の初期近似値
1858
- #
1859
- # @return [Numeric] ユリウス日
1860
- #
1861
- def cn_to_time_(cn, time0=nil)
1862
- time0 ||= (cn - @cycle_number_0m) / @cycle_number_1m
1863
- case @formula
1864
- when /S/ ; ((time0 + 1.0/256 - @day_epoch) / @solar_terms).floor * @solar_terms + @day_epoch
1865
- when /L/ ; ((time0 + 1.0/256 - @day_epoch) / @month_tithi).floor * @month_tithi + @day_epoch
1866
- end
1867
- end
1868
-
1869
1871
  # オブジェクトの正規化
1870
1872
  def _normalize(args=[], options={})
1871
1873
  Rational
1872
1874
  @time_standard ||= 'universal'
1873
1875
  @epoch_shift ||= 1721139 # 西暦 0 年 春分
1874
1876
  @day_shift ||= Rational(-1,2) # 夜半 -1/2, 日出 -1/4
1875
- @day_shift = @day_shift.to_r
1876
- @longitude_shift ||= Rational(-1,4) # 冬至 -1/4, 立春 -1/8
1877
- @longitude_shift = @longitude_shift.to_r
1878
- @day_epoch = @day_epoch.to_i + @day_shift
1879
- @year_length = @year_length.to_r
1880
- @lunation_length = @lunation_length.to_r
1881
- @month_length = 1 / (1.to_r/@year_length + 1.to_r/@lunation_length)
1882
- @denominator = [@year_length.denominator, @lunation_length.denominator].max
1883
- @solar_terms = @year_length / 24
1884
- @month_tithi = @lunation_length / 30
1885
- @year_epoch = 0
1886
- @year_epoch = @longitude_shift -_mean_sun_(@epoch_shift).to_i
1887
- @month_epoch = 0
1888
- @month_epoch = @longitude_shift -_mean_moon_(@epoch_shift).to_i
1889
- super
1890
- end
1891
- end
1892
-
1893
- #
1894
- # Solar Calendar Formula for Variable Year Length Method
1895
- #
1896
- class VariableYearLengthMethod < Formula
1897
-
1898
- # 日時 -> 周期番号
1899
- #
1900
- # @param [Numeric] t ユリウス日(Terrestrial Time)
1901
- # @param [When::TM::TemporalPosition] t
1902
- #
1903
- # @return [Numeric] 周期番号
1904
- #
1905
- def time_to_cn(t, cn0=nil)
1906
- cn0 ||= (t.to_f - @day_epoch) / @year_length + @year_epoch + @longitude_shift
1907
- root(cn0 * 12, t.to_f) {|cn| cn_to_time(cn) }
1908
- end
1909
-
1910
- # 周期番号 -> 日時
1911
- #
1912
- # @param [Numeric] cn 周期番号
1913
- # @param [Numeric] time0 日時の初期近似値
1914
- #
1915
- # @return [Numeric] ユリウス日
1916
- #
1917
- def cn_to_time_(cn, time0=nil)
1918
- t, n = (cn / 12.0 - @longitude_shift - @year_epoch).divmod(1)
1919
- @day_epoch + @year_length * t - @year_delta * t * (t-1) + (@year_length - 2 * @year_delta * t) * n
1920
- end
1921
-
1922
- private
1923
-
1924
- # オブジェクトの正規化
1925
- def _normalize(args=[], options={})
1926
- Rational
1927
- @time_standard ||= 'universal'
1928
- @day_shift ||= Rational(-1,2) # 夜半 -1/2, 日出 -1/4
1929
1877
  @day_shift = @day_shift.to_r
1930
1878
  @longitude_shift ||= Rational(-1,4) # 冬至 -1/4, 立春 -1/8
1931
1879
  @longitude_shift = @longitude_shift.to_r
1932
- @day_epoch = @day_epoch.to_f + @day_shift
1933
- @year_epoch = @year_epoch.to_f
1934
- @year_length = @year_length.to_f
1935
- @year_delta = @year_delta.to_f * 1.0E-6
1880
+ @day_epoch = (@day_epoch.to_f == @day_epoch.to_i ? @day_epoch.to_i : @day_epoch.to_f) + @day_shift
1881
+ @year_length = @year_length.to_r
1882
+ @year_delta = @year_delta.to_f * 1.0E-6 if @year_delta
1883
+ if @year_epoch
1884
+ @year_epoch = @year_epoch.to_f
1885
+ else
1886
+ @year_epoch = 0
1887
+ @year_epoch = @longitude_shift -_mean_sun_(@epoch_shift).to_i
1888
+ end
1889
+ @cycle_precision ||= 1.0E-8
1890
+ @cycle_precision = @cycle_precision.to_f
1891
+
1892
+ if @lunation_length && /S/i !~ @formula
1893
+ # 月の位相の計算
1894
+ @lunation_length = @lunation_length.to_r
1895
+ @month_length = 1 / (1.to_r/@year_length + 1.to_r/@lunation_length)
1896
+ @half_tithi = @lunation_length / 60
1897
+ if @month_epoch
1898
+ @month_epoch = @month_epoch.to_f
1899
+ else
1900
+ @month_epoch = 0
1901
+ @month_epoch = @longitude_shift -_mean_moon_(@epoch_shift).to_i
1902
+ end
1903
+ class << self; include LunarMethod; end
1904
+ else
1905
+ # 太陽黄経の計算
1906
+ @solar_degree = @year_length / 360
1907
+ class << self; include SolarMethod; end
1908
+ end
1936
1909
  super
1937
1910
  end
1938
1911
  end