1: <?php
2: 3: 4:
5: class Horde_Block_Moon extends Horde_Core_Block
6: {
7: 8:
9: public function __construct($app, $params = array())
10: {
11: parent::__construct($app, $params);
12:
13: $this->_name = _("Moon Phases");
14: }
15:
16: 17:
18: protected function _params()
19: {
20: return array(
21: 'phase' => array(
22: 'name' => _("Which phases"),
23: 'type' => 'enum',
24: 'default' => 'current',
25: 'values' => array('current' => _("Current 4 Phases"),
26: 'next' => _("Next 4 Phases"))),
27: 'hemisphere' => array(
28: 'name' => _("Hemisphere"),
29: 'type' => 'enum',
30: 'default' => 'northern',
31: 'values' => array('northern' => _("Northern Hemisphere"),
32: 'southern' => _("Southern Hemisphere"))),
33: );
34: }
35:
36: 37:
38: protected function _content()
39: {
40: $phases = $this->_calculateMoonPhases(date('Y'));
41: $now = time();
42:
43: $lastNew = 0;
44: $lastNewStamp = 0;
45: $offset = 0;
46: foreach ($phases as $key => $val) {
47: if ($key < $now && $key > $lastNewStamp && $val == _("New Moon")) {
48: $lastNew = $offset;
49: $lastNewStamp = $key;
50: }
51: $offset++;
52: }
53:
54: if (isset($this->_params['phase']) && $this->_params['phase'] == 'next') {
55: $dates = array_slice(array_keys($phases), $lastNew + 4, 4);
56: } else {
57: $dates = array_slice(array_keys($phases), $lastNew, 4);
58: }
59:
60: if (isset($this->_params['hemisphere']) && $this->_params['hemisphere'] == 'northern') {
61: $location = _("Northern Hemisphere");
62: } else {
63: $location = _("Southern Hemisphere");
64: }
65:
66: $html = '<table width="100%" height="100%" cellspacing="0">' .
67: '<tr><td colspan="4" class="control"><strong>' . $location . '</strong></td></tr>' .
68: '<tr height="100%"><td width="25%" align="center">' .
69: Horde::img('block/moon/newmoon.png', _("New Moon")) .
70: '<br />' . strftime('%d %b', $dates[0]) .
71: '</td>';
72:
73: $html .= '<td width="25%" align="center">';
74: if (isset($this->_params['hemisphere']) && $this->_params['hemisphere'] == 'northern') {
75: $html .= Horde::img('block/moon/lastquarter.png', _("First Quarter"));
76: } else {
77: $html .= Horde::img('block/moon/firstquarter.png', _("First Quarter"));
78: }
79: $html .= '<br />' . strftime('%d %b', $dates[1]) . '</td>';
80:
81: $html .= '<td width="25%" align="center">' .
82: Horde::img('block/moon/fullmoon.png', _("Full Moon")) .
83: '<br />' . strftime('%d %b', $dates[2]) . '</td>';
84:
85: $html .= '<td width="25%" align="center">';
86: if (isset($this->_params['hemisphere']) && $this->_params['hemisphere'] == 'northern') {
87: $html .= Horde::img('block/moon/firstquarter.png', _("Last Quarter"));
88: } else {
89: $html .= Horde::img('block/moon/lastquarter.png', _("Last Quarter"));
90: }
91: $html .= '<br />' . strftime('%d %b', $dates[3]) . '</td></tr></table>';
92:
93: return $html;
94: }
95:
96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111:
112: private function _calculateMoonPhases($Y)
113: {
114: $R1 = 3.14159265 / 180;
115: $U = false;
116: $K0 = intval(($Y - 1900) * 12.3685);
117: $T = ($Y - 1899.5) / 100;
118: $T2 = $T * $T;
119: $T3 = $T * $T * $T;
120: $J0 = 2415020 + 29 * $K0;
121: $F0 = 0.0001178 * $T2 - 0.000000155 * $T3;
122: $F0 += (0.75933 + 0.53058868*$K0);
123: $F0 -= (0.000837 * $T + 0.000335 * $T2);
124: $M0 = $K0 * 0.08084821133;
125: $M0 = 360 * ($M0 - intval($M0)) + 359.2242;
126: $M0 -= 0.0000333 * $T2;
127: $M0 -= 0.00000347 * $T3;
128: $M1 = $K0 * 0.07171366128;
129: $M1 = 360 * ($M1 - intval($M1)) + 306.0253;
130: $M1 += 0.0107306 * $T2;
131: $M1 += 0.00001236 * $T3;
132: $B1 = $K0 * 0.08519585128;
133: $B1 = 360 * ($B1 - intval($B1)) + 21.2964;
134: $B1 -= 0.0016528 * $T2;
135: $B1 -= 0.00000239 * $T3;
136: for ($K9 = 0; $K9 <= 28; $K9 = $K9 + 0.5) {
137: $J = $J0 + 14 * $K9;
138: $F = $F0 + 0.765294 * $K9;
139: $K = $K9 / 2;
140: $M5 = ($M0 + $K * 29.10535608) * $R1;
141: $M6 = ($M1 + $K * 385.81691806) * $R1;
142: $B6 = ($B1 + $K * 390.67050646) * $R1;
143: $F -= 0.4068 * sin($M6);
144: $F += (0.1734 - 0.000393 * $T) * sin($M5);
145: $F += 0.0161 * sin(2 * $M6);
146: $F += 0.0104 * sin(2 * $B6);
147: $F -= 0.0074 * sin($M5 - $M6);
148: $F -= 0.0051 * sin($M5 + $M6);
149: $F += 0.0021 * sin(2 * $M5);
150: $F += 0.0010 * sin(2 * $B6 - $M6);
151:
152: 153:
154: $F += 0.5 / 1440;
155: $J += intval($F);
156: $F -= intval($F);
157:
158:
159: $julian = $J + round($F);
160: $parts = explode('/', $this->_jdtogregorian($julian));
161: $stamp = gmmktime(0, 0, 0, $parts[0], $parts[1], $parts[2]);
162:
163:
164: if (($K9 - floor($K9)) > 0) {
165: if ($U) {
166:
167: $phases[$stamp] = _("First Half");
168: } else {
169:
170: $phases[$stamp] = _("Last Half");
171: }
172: } else {
173:
174: if (!$U) {
175: $phases[$stamp] = _("New Moon");
176: } else {
177: $phases[$stamp] = _("Full Moon");
178: }
179: $U = !$U;
180: }
181: }
182:
183: return $phases;
184: }
185:
186: 187: 188: 189: 190: 191: 192: 193:
194: private function _jdtogregorian($julian)
195: {
196: if (function_exists('jdtogregorian')) {
197: return jdtogregorian($julian);
198: }
199:
200:
201: $julian = $julian - 1721119;
202: $calc1 = 4 * $julian - 1;
203: $year = floor($calc1 / 146097);
204: $julian = floor($calc1 - 146097 * $year);
205: $day = floor($julian / 4);
206: $calc2 = 4 * $day + 3;
207: $julian = floor($calc2 / 1461);
208: $day = $calc2 - 1461 * $julian;
209: $day = floor(($day + 4) / 4);
210: $calc3 = 5 * $day - 3;
211: $month = floor($calc3 / 153);
212: $day = $calc3 - 153 * $month;
213: $day = floor(($day + 5) / 5);
214: $year = 100 * $year + $julian;
215:
216: if ($month < 10) {
217: $month = $month + 3;
218: } else {
219: $month = $month - 9;
220: $year = $year + 1;
221: }
222:
223: return "$month/$day/$year";
224: }
225:
226: }
227: