libkholidays

lunarphase.cpp
1/*
2 This file is part of libkholidays.
3 Copyright (c) 2004 Allen Winter <winter@kde.org>
4
5 Copyright (c) 1989, 1993
6 The Regents of the University of California. All rights reserved.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22 In addition, as a special exception, the copyright holders give
23 permission to link the code of this program with any edition of
24 the TQt library by Trolltech AS, Norway (or with modified versions
25 of TQt that use the same license as TQt), and distribute linked
26 combinations including the two. You must obey the GNU General
27 Public License in all respects for all of the code used other than
28 TQt. If you modify this file, you may extend this exception to
29 your version of the file, but you are not obligated to do so. If
30 you do not wish to do so, delete this exception statement from
31 your version.
32*/
33
34#include "config.h"
35
36#include <tdeglobal.h>
37#include <tdelocale.h>
38#include <kdebug.h>
39
40#include "lunarphase.h"
41
42LunarPhase::LunarPhase( Hemisphere hemisphere )
43{
44 mHemisphere = hemisphere;
45}
46
47LunarPhase::~LunarPhase()
48{
49}
50
51void LunarPhase::setHemisphere( Hemisphere hemisphere )
52{
53 mHemisphere = hemisphere;
54}
55
56LunarPhase::Hemisphere LunarPhase::hemisphere() const
57{
58 return( mHemisphere );
59}
60
62{
63 return hemisphereName( mHemisphere );
64}
65
66TQString LunarPhase::hemisphereName( LunarPhase::Hemisphere hemisphere )
67{
68 switch( hemisphere ) {
69 case Northern:
70 default:
71 return( i18n( "Northern" ) );
72 break;
73 case Southern:
74 return( i18n( "Southern" ) );
75 break;
76 }
77}
78
79TQString LunarPhase::phaseStr( const TQDate &date ) const
80{
81 return phaseName( phase( date ) );
82}
83
84TQString LunarPhase::phaseName( LunarPhase::Phase phase )
85{
86 switch ( phase ) {
87 case New:
88 return( i18n( "New Moon" ) );
89 break;
90 case Full:
91 return( i18n( "Full Moon" ) );
92 break;
93 case FirstQ:
94 return( i18n( "First Quarter Moon" ) );
95 break;
96 case LastQ:
97 return( i18n( "Last Quarter Moon" ) );
98 break;
99 default:
100 case None:
101 return( TQString() );
102 break;
103 }
104}
105
106LunarPhase::Phase LunarPhase::phase( const TQDate &date ) const
107{
108 Phase retPhase = None;
109
110 // compute percent-full for the middle of today and yesterday.
111 TQTime noontime( 12, 0, 0 );
112 TQDateTime today( date, noontime );
113 double todayPer = percentFull( today.toTime_t() );
114 TQDateTime yesterday( date.addDays(-1), noontime );
115 double yesterdayPer = percentFull( yesterday.toTime_t() );
116
117 if ( ( todayPer < 0.50 ) && ( yesterdayPer > 0.50 ) ) {
118 retPhase = New;
119 } else if ( ( todayPer > 99.50 ) && ( yesterdayPer < 99.50 ) ) {
120 retPhase = Full;
121 } else {
122 // compute percent-full for the start of today.
123 TQTime sqt( 0, 0, 0 );
124 TQDateTime start( date, sqt );
125 double startPer = percentFull( start.toTime_t() );
126 // compute percent-full for the end of today.
127 TQTime eqt( 23, 59, 59 );
128 TQDateTime end( date, eqt );
129 double endPer = percentFull( end.toTime_t() );
130
131 if ( ( startPer <= 50 ) && ( endPer > 50 ) ) {
132 if ( mHemisphere == Northern ) {
133 retPhase = FirstQ;
134 } else {
135 retPhase = LastQ;
136 }
137 }
138 if ( ( endPer <= 50 ) && ( startPer > 50 ) ) {
139 if ( mHemisphere == Northern ) {
140 retPhase = LastQ;
141 } else {
142 retPhase = FirstQ;
143 }
144 }
145 // Note: if you want to support crescent and gibbous phases then please
146 // read the source for the original BSD 'pom' program.
147 }
148 return( retPhase );
149}
150
151/*
152 * Copyright (c) 1989, 1993
153 * The Regents of the University of California. All rights reserved.
154 *
155 * This code is derived from software posted to USENET.
156 *
157 * Redistribution and use in source and binary forms, with or without
158 * modification, are permitted provided that the following conditions
159 * are met:
160 * 1. Redistributions of source code must retain the above copyright
161 * notice, this list of conditions and the following disclaimer.
162 * 2. Redistributions in binary form must reproduce the above copyright
163 * notice, this list of conditions and the following disclaimer in the
164 * documentation and/or other materials provided with the distribution.
165 * 3. All advertising materials mentioning features or use of this software
166 * must display the following acknowledgement:
167 * This product includes software developed by the University of
168 * California, Berkeley and its contributors.
169 * 4. Neither the name of the University nor the names of its contributors
170 * may be used to endorse or promote products derived from this software
171 * without specific prior written permission.
172 *
173 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
174 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
175 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
176 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
177 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
178 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
179 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
180 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
181 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
182 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
183 * SUCH DAMAGE.
184 */
185
186#if HAVE_SYS_CDEFS_H
187#include <sys/cdefs.h>
188#endif
189
190/*
191 * Phase of the Moon. Calculates the current phase of the moon.
192 * Based on routines from `Practical Astronomy with Your Calculator',
193 * by Duffett-Smith. Comments give the section from the book that
194 * particular piece of code was adapted from.
195 *
196 * -- Keith E. Brandt VIII 1984
197 *
198 * Updated to the Third Edition of Duffett-Smith's book, Paul Janzen, IX 1998
199 *
200 */
201
202
203#include <ctype.h>
204#if HAVE_ERR_H
205#include <err.h>
206#endif
207#include <math.h>
208#include <string.h>
209#include <stdlib.h>
210#include <time.h>
211#include <unistd.h>
212
213#ifndef PI
214#define PI 3.14159265358979323846
215#endif
216
217/*
218 * The EPOCH in the third edition of the book is 1990 Jan 0.0 TDT.
219 * In this program, we do not bother to correct for the differences
220 * between UTC (as shown by the UNIX clock) and TDT. (TDT = TAI + 32.184s;
221 * TAI-UTC = 32s in Jan 1999.)
222 */
223#define EPOCH_MINUS_1970 (20 * 365 + 5 - 1) /* 20 years, 5 leaps, back 1 day to Jan 0 */
224#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */
225#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */
226#define ECCEN 0.016713 /* solar orbit eccentricity */
227#define lzero 318.351648 /* lunar mean long at EPOCH */
228#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */
229#define Nzero 318.510107 /* lunar mean long of node at EPOCH */
230
231/*
232 * percentFull --
233 * return phase of the moon as a percentage of full
234 */
235double LunarPhase::percentFull( uint tmpt ) const
236{
237 double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
238 double A4, lprime, V, ldprime, D, Nm;
239
240 double days;
241 days = ( tmpt - EPOCH_MINUS_1970 * 86400 ) / 86400.0;
242
243 N = 360 * days / 365.242191; /* sec 46 #3 */
244 adj360(&N);
245 Msol = N + EPSILONg - RHOg; /* sec 46 #4 */
246 adj360(&Msol);
247 Ec = 360 / PI * ECCEN * sin(degreesToRadians(Msol)); /* sec 46 #5 */
248 LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */
249 adj360(&LambdaSol);
250 l = 13.1763966 * days + lzero; /* sec 65 #4 */
251 adj360(&l);
252 Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */
253 adj360(&Mm);
254 Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */
255 adj360(&Nm);
256 Ev = 1.2739 * sin(degreesToRadians(2*(l - LambdaSol) - Mm)); /* sec 65 #7 */
257 Ac = 0.1858 * sin(degreesToRadians(Msol)); /* sec 65 #8 */
258 A3 = 0.37 * sin(degreesToRadians(Msol));
259 Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */
260 Ec = 6.2886 * sin(degreesToRadians(Mmprime)); /* sec 65 #10 */
261 A4 = 0.214 * sin(degreesToRadians(2 * Mmprime)); /* sec 65 #11 */
262 lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */
263 V = 0.6583 * sin(degreesToRadians(2 * (lprime - LambdaSol))); /* sec 65 #13 */
264 ldprime = lprime + V; /* sec 65 #14 */
265 D = ldprime - LambdaSol; /* sec 67 #2 */
266 return(50.0 * (1 - cos(degreesToRadians(D)))); /* sec 67 #3 */
267}
268
269/*
270 * degreesToRadians --
271 * convert degrees to radians
272 */
273double LunarPhase::degreesToRadians( double degree ) const
274{
275 return( degree * PI / 180 );
276}
277
278/*
279 * adj360 --
280 * adjust value so 0 <= degree <= 360
281 */
282void LunarPhase::adj360( double *degree ) const
283{
284 for( ;; )
285 if( *degree < 0 )
286 *degree += 360;
287 else if( *degree > 360 )
288 *degree -= 360;
289 else
290 break;
291}
Phase phase(const TQDate &date) const
Return the lunar phase for the specified Gregorian date.
Definition: lunarphase.cpp:106
TQString hemisphereStr() const
Return hemisphere as a clear text string.
Definition: lunarphase.cpp:61
Hemisphere hemisphere() const
Return the hemisphere.
Definition: lunarphase.cpp:56
void setHemisphere(Hemisphere hemisphere=Northern)
Set the hemisphere.
Definition: lunarphase.cpp:51
static TQString phaseName(Phase phase)
Return the string representation of phase.
Definition: lunarphase.cpp:84
static TQString hemisphereName(Hemisphere hemisphere)
Return the string representation of hemisphere.
Definition: lunarphase.cpp:66
TQString phaseStr(const TQDate &date) const
Return the lunar phase as a text string for the specified date.
Definition: lunarphase.cpp:79