when_exe 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +210 -171
  3. data/bin/irb.rc +1 -0
  4. data/lib/when_exe.rb +78 -53
  5. data/lib/when_exe/basictypes.rb +27 -8
  6. data/lib/when_exe/calendarnote.rb +848 -805
  7. data/lib/when_exe/calendartypes.rb +110 -240
  8. data/lib/when_exe/coordinates.rb +2440 -2175
  9. data/lib/when_exe/core/compatibility.rb +1 -1
  10. data/lib/when_exe/core/duration.rb +13 -11
  11. data/lib/when_exe/core/extension.rb +38 -45
  12. data/lib/when_exe/ephemeris.rb +43 -14
  13. data/lib/when_exe/ephemeris/eclipse.rb +149 -0
  14. data/lib/when_exe/ephemeris/notes.rb +39 -7
  15. data/lib/when_exe/icalendar.rb +2 -6
  16. data/lib/when_exe/inspect.rb +1408 -1399
  17. data/lib/when_exe/parts/enumerator.rb +486 -477
  18. data/lib/when_exe/parts/resource.rb +1101 -1069
  19. data/lib/when_exe/parts/timezone.rb +6 -5
  20. data/lib/when_exe/region/babylonian.rb +405 -405
  21. data/lib/when_exe/region/bahai.rb +21 -61
  22. data/lib/when_exe/region/chinese/epochs.rb +81 -81
  23. data/lib/when_exe/region/chinese/twins.rb +51 -51
  24. data/lib/when_exe/region/christian.rb +7 -2
  25. data/lib/when_exe/region/coptic.rb +1 -1
  26. data/lib/when_exe/region/discordian.rb +9 -16
  27. data/lib/when_exe/region/french.rb +1 -1
  28. data/lib/when_exe/region/hanke_henry.rb +57 -0
  29. data/lib/when_exe/region/indian.rb +41 -73
  30. data/lib/when_exe/region/international_fixed.rb +97 -0
  31. data/lib/when_exe/region/iranian.rb +203 -203
  32. data/lib/when_exe/region/japanese.rb +13 -13
  33. data/lib/when_exe/region/japanese/eclipses.rb +1194 -0
  34. data/lib/when_exe/region/japanese/notes.rb +1482 -1383
  35. data/lib/when_exe/region/japanese/residues.rb +726 -721
  36. data/lib/when_exe/region/japanese/twins.rb +37 -37
  37. data/lib/when_exe/region/jewish.rb +2 -2
  38. data/lib/when_exe/region/pax.rb +60 -0
  39. data/lib/when_exe/region/positivist.rb +100 -0
  40. data/lib/when_exe/region/roman.rb +333 -334
  41. data/lib/when_exe/region/shire.rb +3 -20
  42. data/lib/when_exe/region/thai.rb +2 -2
  43. data/lib/when_exe/region/tibetan.rb +3 -3
  44. data/lib/when_exe/region/tranquility.rb +208 -0
  45. data/lib/when_exe/region/vanishing_leprechaun.rb +53 -0
  46. data/lib/when_exe/region/vietnamese.rb +4 -4
  47. data/lib/when_exe/region/world.rb +9 -13
  48. data/lib/when_exe/region/world_season.rb +89 -0
  49. data/lib/when_exe/region/zoroastrian.rb +4 -2
  50. data/lib/when_exe/tmobjects.rb +14 -4
  51. data/lib/when_exe/tmposition.rb +239 -81
  52. data/lib/when_exe/tmreference.rb +57 -28
  53. data/lib/when_exe/version.rb +1 -1
  54. data/link_to_online_documents +6 -3
  55. data/test/examples/today.rb +1 -1
  56. data/test/scripts.rb +23 -0
  57. data/test/scripts/2.ext.rb +169 -0
  58. data/test/scripts/2.rb +169 -0
  59. data/test/scripts/3.ext.rb +133 -0
  60. data/test/scripts/3.rb +134 -0
  61. data/test/scripts/4.ext.rb +112 -0
  62. data/test/scripts/4.min.rb +65 -0
  63. data/test/scripts/4.rb +136 -0
  64. data/test/scripts/5.ext.rb +78 -0
  65. data/test/scripts/5.rb +81 -0
  66. data/test/scripts/6.gcal.rb +131 -0
  67. data/test/scripts/6.rb +205 -0
  68. data/test/scripts/6.tz.rb +105 -0
  69. data/test/scripts/7.phase.rb +109 -0
  70. data/test/scripts/7.rb +95 -0
  71. data/test/scripts/7.term.rb +128 -0
  72. data/test/scripts/7.week.rb +84 -0
  73. data/test/scripts/8.ext.rb +61 -0
  74. data/test/scripts/8.rb +62 -0
  75. data/test/scripts/9.ext.rb +131 -0
  76. data/test/scripts/9.rb +130 -0
  77. data/test/scripts/chinese-luni-solar.rb +52 -0
  78. data/test/{examples → scripts}/geometric_complex.rb +41 -41
  79. data/test/scripts/geometric_complex.txt +18 -0
  80. data/test/scripts/korea.rb +59 -0
  81. data/test/scripts/thai-reviewed.txt +211 -0
  82. data/test/scripts/thai.rb +36 -0
  83. data/test/scripts/thai.txt +210 -0
  84. data/test/test.rb +7 -0
  85. data/test/test/basictypes.rb +22 -0
  86. data/test/test/coordinates.rb +2 -1
  87. data/test/test/ephemeris.rb +34 -2
  88. data/test/test/icalendar.rb +12 -0
  89. data/test/test/inspect.rb +37 -1
  90. data/test/test/parts.rb +4 -3
  91. data/test/test/region/armenian.rb +20 -0
  92. data/test/test/region/bahai.rb +58 -0
  93. data/test/test/region/chinese.rb +14 -3
  94. data/test/test/region/christian.rb +16 -35
  95. data/test/test/region/discordian.rb +20 -0
  96. data/test/test/region/indian.rb +30 -2
  97. data/test/test/region/japanese.rb +24 -0
  98. data/test/test/region/jewish.rb +2 -0
  99. data/test/test/region/m17n.rb +9 -0
  100. data/test/test/region/reforms.rb +121 -0
  101. data/test/test/region/residue.rb +17 -11
  102. data/test/test/region/shire.rb +58 -0
  103. data/test/test/region/swedish.rb +45 -0
  104. data/test/test/region/zoroastrian.rb +58 -0
  105. data/test/test/tmobjects.rb +74 -0
  106. data/test/test/tmposition.rb +468 -397
  107. data/when_exe.gemspec +2 -2
  108. metadata +49 -6
@@ -79,7 +79,7 @@ end
79
79
  #
80
80
  # 例外クラス
81
81
  #
82
- unless Object.const_defined?(:StopIteration)
82
+ unless ::Object.const_defined?(:StopIteration)
83
83
  # @private
84
84
  class StopIteration < IndexError
85
85
  end
@@ -33,20 +33,22 @@ end
33
33
  # Extensions to Date class
34
34
  #
35
35
  # @private
36
- class Date
36
+ if ::Object.const_defined?(:Date) && ::Date.method_defined?(:+)
37
+ class Date
37
38
 
38
- alias :_plus_ :+
39
- def +(other)
40
- other.kind_of?(When::TM::Duration) ? self + other.rational_duration : self._plus_(other)
41
- end
39
+ alias :_plus_ :+
40
+ def +(other)
41
+ other.kind_of?(When::TM::Duration) ? self + other.rational_duration : self._plus_(other)
42
+ end
42
43
 
43
44
 
44
- alias :_minus_ :-
45
- def -(other)
46
- case other
47
- when When::TM::Duration ; self - other.rational_duration
48
- when When::TimeValue ; self._minus_(kind_of?(DateTime) ? other.to_date_time : other.to_date)
49
- else ; self._minus_(other)
45
+ alias :_minus_ :-
46
+ def -(other)
47
+ case other
48
+ when When::TM::Duration ; self - other.rational_duration
49
+ when When::TimeValue ; self._minus_(other.to_date_or_datetime)
50
+ else ; self._minus_(other)
51
+ end
50
52
  end
51
53
  end
52
54
  end
@@ -5,7 +5,6 @@
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
7
7
 
8
- require 'date'
9
8
  require 'when_exe/core/duration'
10
9
 
11
10
  #
@@ -53,55 +52,49 @@ end
53
52
  #
54
53
  # Extensions to Date class
55
54
  #
56
- class Date
57
-
58
- if When::TM.const_defined?(:TemporalPosition)
55
+ if ::Object.const_defined?(:Date) && ::Date.method_defined?(:+)
56
+ class Date
57
+
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_pos(options={})
74
+ options[:frame] ||= When::CalendarTypes::Christian._default_start(self)
75
+ super(options)
76
+ end
77
+ alias :to_tm_pos :tm_pos
78
+ end
59
79
 
60
- include When::TM::TemporalPosition::Conversion
80
+ alias :__method_missing :method_missing
61
81
 
82
+ # その他のメソッド
62
83
  #
63
- # 対応する When::TM::CalDate or DateAndTime を生成
64
- #
65
- # @param [Hash] options 暦法や時法などの指定
66
- # see {When::TM::TemporalPosition._instance}
84
+ # @note
85
+ # self で定義されていないメソッドは
86
+ # tm_pos で変換して処理する
67
87
  #
68
- # @return [When::TM::CalDate, When::TM::DateAndTime]
69
- #
70
- # @note 暦法の指定がない場合、start メソッドの値によって
71
- # Julian / Gregorian / Civil 暦法を選択する
72
- #
73
- def tm_pos(options={})
74
- options[:frame] ||= When::CalendarTypes::Christian._default_start(self)
75
- super(options)
76
- end
77
- alias :to_tm_pos :tm_pos
78
- end
79
-
80
- alias :__method_missing :method_missing
81
-
82
- # その他のメソッド
83
- #
84
- # @note
85
- # self で定義されていないメソッドは
86
- # tm_pos で変換して処理する
87
- #
88
- def method_missing(name, *args, &block)
89
- return __method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
90
- self.class.module_eval %Q{
91
- def #{name}(*args, &block)
92
- result = tm_pos.send("#{name}", *args, &block)
93
- case result
94
- when When::TM::DateAndTime ; result.to_date_time
95
- when When::TM::CalDate ; result.to_date
96
- else ; result
88
+ def method_missing(name, *args, &block)
89
+ return __method_missing(name, *args, &block) if When::Parts::MethodCash::Escape.key?(name)
90
+ self.class.module_eval %Q{
91
+ def #{name}(*args, &block)
92
+ result = tm_pos.send("#{name}", *args, &block)
93
+ result.kind_of?(When::TimeValue) ? result.to_date_or_datetime : result
97
94
  end
98
- end
99
- } unless When::Parts::MethodCash.escape(name)
100
- result = tm_pos.send(name, *args, &block)
101
- case result
102
- when When::TM::DateAndTime ; result.to_date_time
103
- when When::TM::CalDate ; result.to_date
104
- else ; result
95
+ } unless When::Parts::MethodCash.escape(name)
96
+ result = tm_pos.send(name, *args, &block)
97
+ result.kind_of?(When::TimeValue) ? result.to_date_or_datetime : result
105
98
  end
106
99
  end
107
100
  end
@@ -289,12 +289,10 @@ module When::Ephemeris
289
289
  def root(t0, y0=nil, delta=0, count=10, error=1E-6, &func)
290
290
 
291
291
  # 近似値0,1
292
- # printf("y0=%20.7f\n",y0)
293
- d = [0.01, error * 10].max
294
- t = [t0-d, t0+d ]
292
+ diff = [0.01, error*1000].min
293
+ t = [t0-diff, t0+diff ]
295
294
  y = [func.call(t[0]), func.call(t[1])]
296
295
  y.map! {|y1| _adjust(y1, y0, delta)} unless delta==0
297
- # printf("t=%20.7f,L=%20.7f\n",t[1],y[1])
298
296
 
299
297
  # 近似値2(1次関数による近似)
300
298
  t << (y0 ? (t[1]-t[0])/(y[1]-y[0])*(y0-y[0])+t[0] : t0)
@@ -319,15 +317,19 @@ module When::Ephemeris
319
317
 
320
318
  if y0
321
319
  # 判別式
322
- if (d = b*b-4*a*(c-y0)) < 0
323
- i = -1
324
- break
320
+ if (discriminant = b*b-4*a*(c-y0)) < 0
321
+ # 近似値(1次関数による近似)
322
+ if y12 == 0
323
+ i = -1
324
+ break
325
+ end
326
+ t << t12/y12*(y0-y[1]) + t[1]
327
+ else
328
+ # 近似値(2次関数による近似)
329
+ sqrtd = Math.sqrt(discriminant)
330
+ sqrtd = -sqrtd if b < 0
331
+ t << (t[2] + 2*(y0-c)/(b+sqrtd)) # <-桁落ち回避
325
332
  end
326
-
327
- # 近似値(2次関数による近似)
328
- sqrtd = Math.sqrt(d)
329
- sqrtd = -sqrtd if b < 0
330
- t << (t[2] + 2*(y0-c)/(b+sqrtd)) # <-桁落ち回避
331
333
  else
332
334
  t << (t[2] - b / (2*a))
333
335
  end
@@ -1117,7 +1119,7 @@ module When::Ephemeris
1117
1119
  #
1118
1120
  # @return [Numeric]
1119
1121
  #
1120
- def eclipse(t, target, base=Earth)
1122
+ def phase_of_eclipse(t, target, base=Earth)
1121
1123
  t = +t
1122
1124
  distance = acos(self.coords(t, base).spherical_law_of_cosines(target.coords(t, base))) / CIRCLE
1123
1125
  self_radius = self.apparent_radius(t, base)
@@ -1477,6 +1479,33 @@ module When::Ephemeris
1477
1479
  day_event_in_the_day(t, 0, When.Resource('_ep:Moon'))
1478
1480
  end
1479
1481
 
1482
+ # 日食の情報
1483
+ #
1484
+ # @param [When::TM::TemporalPosition] date
1485
+ # @param [Range<When::TM::TemporalPosition>] date
1486
+ # @param [Block] block
1487
+ #
1488
+ # @return [Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>] 食の情報(のArray(dateがRangeの場合))
1489
+ # @see When::Coordinates::Spatial#eclipse_info
1490
+ #
1491
+ def solar_eclipse(date, &block)
1492
+ location.solar_eclipse(date, &block)
1493
+ end
1494
+
1495
+ # 月食の情報
1496
+ #
1497
+ # @param [When::TM::TemporalPosition] date
1498
+ # @param [Range<When::TM::TemporalPosition>] date
1499
+ # @note Rangeの場合午前6時より前は前日扱い
1500
+ # @param [Block] block
1501
+ #
1502
+ # @return [Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>] 食の情報(のArray(dateがRangeの場合))
1503
+ # @see When::Coordinates::Spatial#eclipse_info
1504
+ #
1505
+ def lunar_eclipse(date, &block)
1506
+ location.lunar_eclipse(date, &block)
1507
+ end
1508
+
1480
1509
  # 恒星の出没と太陽の位置関係に関するイベントの日時
1481
1510
  #
1482
1511
  # @param [Numeric] t ユリウス日(Terrestrial Time)
@@ -1568,7 +1597,7 @@ module When::Ephemeris
1568
1597
  @long, @lat, @alt = [@location.long / When::Coordinates::Spatial::DEGREE,
1569
1598
  @location.lat / When::Coordinates::Spatial::DEGREE,
1570
1599
  @location.alt] if @location
1571
- @formula ||= '1L'
1600
+ @formula ||= '1S'
1572
1601
  @time_standard ||= 'dynamical'
1573
1602
  @is_dynamical = (@time_standard[0..0].downcase == 'd')
1574
1603
 
@@ -0,0 +1,149 @@
1
+ # -*- coding: utf-8 -*-
2
+ =begin
3
+ Copyright (C) 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
+ class When::Coordinates::Spatial
9
+
10
+ # @private
11
+ EclipseHalfYear = (346 + (14*3600+52*60+54.965) / 86400) / 2
12
+
13
+ # @private
14
+ EclipseRange = (75.0..120.0) # 82.05003457775217..114.62097737290446
15
+
16
+ # 日食の情報
17
+ #
18
+ # @param [When::TM::TemporalPosition] date
19
+ # @param [Range<When::TM::TemporalPosition>] date
20
+ # @param [Block] block
21
+ #
22
+ # @return [Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>] 食の情報(のArray(dateがRangeの場合))
23
+ # @see When::Coordinates::Spatial#eclipse_info
24
+ #
25
+ def solar_eclipse(date, &block)
26
+ if date.kind_of?(Range)
27
+ last = date.last.to_i
28
+ last -= 1 if date.exclude_end?
29
+ first = date.first.to_i
30
+ date = date.first
31
+ end
32
+ clock = date.clock && (date.clock.tz_prop || date.clock.label)
33
+ cn = @mean.time_to_cn(date).round
34
+ list = []
35
+ loop do
36
+ unless @ecls.key?([cn,clock.to_s])
37
+ time = @mean.cn_to_time(cn)
38
+ data = EclipseRange.include?(time % EclipseHalfYear) ?
39
+ eclipse_info(@mean._to_seed_type(time, date), self, When.Resource('_ep:Sun'), When.Resource('_ep:Moon')) : nil
40
+ @ecls[[cn,clock.to_s]] = data ? [data[2][data[2].size / 2][0].to_i, data] : nil
41
+ end
42
+ key, info = @ecls[[cn,clock.to_s]]
43
+ return info unless first
44
+ list << (block_given? ? yield(info) : info) if key && first <= key && key <= last
45
+ break if (key || first) >= last
46
+ cn += 1
47
+ end
48
+ return list
49
+ end
50
+
51
+ # 月食の情報
52
+ #
53
+ # @param [When::TM::TemporalPosition] date
54
+ # @param [Range<When::TM::TemporalPosition>] date
55
+ # @note Rangeの場合午前6時より前は前日扱い
56
+ # @param [Block] block
57
+ #
58
+ # @return [Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>] 食の情報(のArray(dateがRangeの場合))
59
+ # @see When::Coordinates::Spatial#eclipse_info
60
+ #
61
+ def lunar_eclipse(date, &block)
62
+ if date.kind_of?(Range)
63
+ last = date.last.to_i
64
+ last -= 1 if date.exclude_end?
65
+ first = date.first.to_i
66
+ date = date.first
67
+ end
68
+ clock = date.clock && (date.clock.tz_prop || date.clock.label)
69
+ cn = (@mean.time_to_cn(date)+0.25).floor+0.5
70
+ list = []
71
+ loop do
72
+ unless @ecls.key?([cn,clock.to_s])
73
+ time = @mean.cn_to_time(cn)
74
+ data = EclipseRange.include?(time % EclipseHalfYear) ?
75
+ eclipse_info(@mean._to_seed_type(time, date), When.Resource('_ep:Earth'), When.Resource('_ep:Moon'),
76
+ When.Resource('_ep:Shadow'), [self, When.Resource('_ep:Moon')]) : nil
77
+ @ecls[[cn,clock.to_s]] = data ? [(data[2][data[2].size / 2][0]-When::PT6H).to_i, data] : nil
78
+ end
79
+ key, info = @ecls[[cn,clock.to_s]]
80
+ return info unless first
81
+ list << (block_given? ? yield(info) : info) if key && first <= key && key <= last
82
+ break if (key || first) >= last
83
+ cn += 1
84
+ end
85
+ return list
86
+ end
87
+
88
+ # 食の情報
89
+ #
90
+ # @param [Numeric] date ユリウス日(Terrestrial Time)
91
+ # @param [When::TM::TemporalPosition] date
92
+ # @param [When::Ephemeris::Datum or When::Coordinates::Spatial] location 観測地
93
+ # @param [When::Ephemeris::Datum] target 隠される天体
94
+ # @param [When::Ephemeris::Datum] base 隠す天体
95
+ # @param [Array<When::Coordinates::Spatial, When::Ephemeris::Datum>] l_for_h 高度を計算する観測地と対象天体
96
+ #
97
+ # @return [Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>] 食の情報
98
+ #
99
+ # [ String - 食の種類 'T' 皆既食, 'A' 金環食, 'P' 部分食, 'B' 帯食]
100
+ # [ Numeric - 最大食分 ]
101
+ # [ Array - 第1~4接触の日時と地平座標(高度/方位角) ]
102
+ #
103
+ def eclipse_info(date, location, target, base, l_for_h=[location, base])
104
+
105
+ tc = When::Ephemeris.root(+date) {|t| # 離角最小日時
106
+ base.elongation(t, target, location)**2
107
+ }
108
+ mag = base.phase_of_eclipse(tc, target, location) # 食分
109
+ return nil unless mag >= 0 # 食なし
110
+
111
+ t1, t4 = [-0.1, +0.1].map {|dt| # 第1, 第4接触
112
+ When::Ephemeris.root(tc+dt, 0) {|t|
113
+ base.phase_of_eclipse(t, target, location)
114
+ }
115
+ }
116
+
117
+ if mag >= 1
118
+ category = 'T'
119
+ t2, t3 = [-0.01, +0.01].map {|dt| # 第2, 第3接触
120
+ When::Ephemeris.root(tc+dt, 1.0) {|t|
121
+ base.phase_of_eclipse(t, target, location)
122
+ }
123
+ }
124
+ elsif target.phase_of_eclipse(tc, base, location) >= 1
125
+ category = 'A'
126
+ t2, t3 = [-0.01, +0.01].map {|dt| # 第2, 第3接触
127
+ When::Ephemeris.root(tc+dt, 1.0) {|t|
128
+ target.phase_of_eclipse(t, base, location)
129
+ }
130
+ }
131
+ else
132
+ category = 'P'
133
+ end
134
+ ts = [t1,t2,tc,t3,t4].compact
135
+
136
+ form = When::Ephemeris::Formula.new(:location=>l_for_h[0])
137
+ height, azimuth = ts.map {|t| # 基準天体の高度・方位角
138
+ coord = form._coords(t, HORIZONTAL, l_for_h[1])
139
+ [coord.theta * 360, ((0.5-coord.phi)-(0.5-coord.phi).floor) * 360]
140
+ }.transpose
141
+ return nil unless height.max >= 0 # 見えない食
142
+ category += 'B' if height.min < 0 # 地平線下で食が始まる/終わる
143
+
144
+ [category, mag, [ts.map {|t| form._to_seed_type(t, date)}, height, azimuth].transpose]
145
+
146
+ rescue RangeError
147
+ nil
148
+ end
149
+ end
@@ -58,8 +58,10 @@ class When::CalendarNote
58
58
  #
59
59
  # @return [When::TM::CalDate] date またはその直後のイベントの日時
60
60
  #
61
- def event_eval(date, parameter=@event, precision=date.precision)
62
- num, den = parameter.kind_of?(String) ? parameter[/\d.*\z/].split(/\//, 2) : parameter
61
+ def event_eval(date, parameter=@event, precision=nil)
62
+ date = When.when?(date) unless date.kind_of?(When::TimeValue)
63
+ precision ||= date.precision
64
+ num, den = parameter.kind_of?(String) ? (parameter[/\d.*\z/]||'').split(/\//, 2) : parameter
63
65
  num = (num || @num).to_f
64
66
  den = (den || @den).to_f
65
67
  date = date.floor(precision) if precision < date.precision
@@ -67,14 +69,24 @@ class When::CalendarNote
67
69
  is_date_and_time = options.key?(:clock) || precision > When::DAY
68
70
  options[:precision] = precision
69
71
  options[:clock] ||= date.frame.time_basis || When::TM::Clock.local_time
72
+ sdn = _the_date(date, num, den)
73
+ time = When::TM::JulianDate._d_to_t(sdn)
74
+ if @formula.is_dynamical
75
+ time = date.time_standard.from_dynamical_time(time)
76
+ time += options[:clock].universal_time(sdn.round) if options[:clock].kind_of?(When::CalendarTypes::LocalTime)
77
+ end
78
+ event = date.frame.jul_trans(When::TM::JulianDate.universal_time(time), options)
79
+ is_date_and_time ? event : event.to_cal_date
80
+ end
81
+
82
+ # the event date
83
+ def _the_date(date, num, den)
70
84
  quot, mod = (@formula.time_to_cn(date)*30.0).divmod(den)
71
85
  cycle = quot * den + num
72
86
  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
87
+ @formula.cn_to_time(cycle/30.0)
77
88
  end
89
+ private :_the_date
78
90
 
79
91
  # 日付に対応する座標
80
92
  #
@@ -114,7 +126,7 @@ class When::CalendarNote
114
126
  def event_time(date, event_name, event)
115
127
  etime = term(date - When.Duration('P3D'), event, When::SYSTEM)
116
128
  if formula.respond_to?(:year_length) && formula.denominator && formula.denominator < 100000
117
- fraction = etime.clk_time.universal_time
129
+ fraction = etime.clk_time.local_time
118
130
  fraction += When::TM::Duration::DAY * (etime.to_i - date.to_i)
119
131
  fraction = (fraction / When::TM::Duration::DAY * formula.denominator * 1000 + 0.5).floor / 1000.0
120
132
  fraction = fraction.to_i if fraction == fraction.to_i
@@ -159,6 +171,26 @@ class When::CalendarNote
159
171
  end
160
172
  end
161
173
 
174
+ #
175
+ # 冬至を定気で計算し、その他の二十四節気を前後の冬至の日時を時間で等分して求める
176
+ #
177
+ class SolarTermsRevised < SolarTerms
178
+
179
+ # the event date
180
+ def _the_date(date, num, den)
181
+ quot, mod = @formula.time_to_cn(date).divmod(12)
182
+ quot += 1 if mod >= 9
183
+ range = [12*quot-3, 12*quot+9].map {|cn| [cn*30, @formula.cn_to_time(cn)]}
184
+ time = @formula.is_dynamical ? +date : date.to_f
185
+ now = [range[0][0] + (range[1][0] - range[0][0]) / (range[1][1] - range[0][1]) * (time - range[0][1]), time]
186
+
187
+ quot, mod = now[0].divmod(den)
188
+ cycle = quot * den + num
189
+ cycle += den if mod > (num % den)
190
+ range[0][1] + (range[1][1] - range[0][1]) / (range[1][0] - range[0][0]) * (cycle - range[0][0])
191
+ end
192
+ end
193
+
162
194
  #
163
195
  # 月の位相
164
196
  #