/[PAMELA software]/yodaUtility/sgp4/cJulian.cpp
ViewVC logotype

Annotation of /yodaUtility/sgp4/cJulian.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Sun Apr 30 11:08:14 2006 UTC (18 years, 7 months ago) by kusanagi
Branch point for: MAIN
Initial revision

1 kusanagi 1.1 //
2     // cJulian.cpp
3     //
4     // This class encapsulates Julian dates with the epoch of 12:00 noon (12:00 UT)
5     // on January 1, 4713 B.C. Some epoch dates:
6     // 01/01/1990 00:00 UTC - 2447892.5
7     // 01/01/1990 12:00 UTC - 2447893.0
8     // 01/01/2000 00:00 UTC - 2451544.5
9     // 01/01/2001 00:00 UTC - 2451910.5
10     //
11     // Note the Julian day begins at noon, which allows astronomers to have all
12     // the dates in a single observing session the same.
13     //
14     // References:
15     // "Astronomical Formulae for Calculators", Jean Meeus
16     // "Satellite Communications", Dennis Roddy, 2nd Edition, 1995.
17     //
18     // Copyright (c) 2003 Michael F. Henry
19     //
20     // mfh 12/24/2003
21     //
22     #include "stdafx.h"
23     #include "globals.h"
24     #include "cJulian.h"
25     #include "math.h"
26     #include "time.h"
27    
28     //////////////////////////////////////////////////////////////////////////////
29     // Create a Julian date object from a time_t object. time_t objects store the
30     // number of seconds since midnight UTC January 1, 1970.
31     cJulian::cJulian(time_t time)
32     {
33     struct tm *ptm = gmtime(&time);
34     assert(ptm);
35    
36     int year = ptm->tm_year + 1900;
37     double day = ptm->tm_yday + 1 +
38     (ptm->tm_hour +
39     ((ptm->tm_min +
40     (ptm->tm_sec / 60.0)) / 60.0)) / 24.0;
41    
42     Initialize(year, day);
43     }
44    
45     //////////////////////////////////////////////////////////////////////////////
46     // Create a Julian date object from a year and day of year.
47     // Example parameters: year = 2001, day = 1.5 (Jan 1 12h)
48     cJulian::cJulian(int year, double day)
49     {
50     Initialize(year, day);
51     }
52    
53     //////////////////////////////////////////////////////////////////////////////
54     // Create a Julian date object.
55     cJulian::cJulian(int year, // i.e., 2004
56     int mon, // 1..12
57     int day, // 1..31
58     int hour, // 0..23
59     int min, // 0..59
60     double sec /* = 0.0 */) // 0..(59.999999...)
61    
62     {
63     // Calculate N, the day of the year (1..366)
64     int N;
65     int F1 = (int)((275.0 * mon) / 9.0);
66     int F2 = (int)((mon + 9.0) / 12.0);
67    
68     if (IsLeapYear(year))
69     {
70     // Leap year
71     N = F1 - F2 + day - 30;
72     }
73     else
74     {
75     // Common year
76     N = F1 - (2 * F2) + day - 30;
77     }
78    
79     double dblDay = N + (hour + (min + (sec / 60.0)) / 60.0) / 24.0;
80    
81     Initialize(year, dblDay);
82     }
83    
84     //////////////////////////////////////////////////////////////////////////////
85     void cJulian::Initialize(int year, double day)
86     {
87     // 1582 A.D.: 10 days removed from calendar
88     // 3000 A.D.: Arbitrary error checking limit
89     assert((year > 1582) && (year < 3000));
90     assert((day >= 0.0) && (day <= 366.5));
91    
92     // Now calculate Julian date
93    
94     year--;
95    
96     // Centuries are not leap years unless they divide by 400
97     int A = (year / 100);
98     int B = 2 - A + (A / 4);
99    
100     double NewYears = (int)(365.25 * year) +
101     (int)(30.6001 * 14) +
102     1720994.5 + B; // 1720994.5 = Oct 30, year -1
103    
104     m_Date = NewYears + day;
105     }
106    
107     //////////////////////////////////////////////////////////////////////////////
108     // getComponent()
109     // Return requested components of date.
110     // Year : Includes the century.
111     // Month: 1..12
112     // Day : 1..31 including fractional part
113     void cJulian::getComponent(int *pYear,
114     int *pMon /* = NULL */,
115     double *pDOM /* = NULL */) const
116     {
117     assert(pYear != NULL);
118    
119     double jdAdj = getDate() + 0.5;
120     int Z = (int)jdAdj; // integer part
121     double F = jdAdj - Z; // fractional part
122     double alpha = (int)((Z - 1867216.25) / 36524.25);
123     double A = Z + 1 + alpha - (int)(alpha / 4.0);
124     double B = A + 1524.0;
125     int C = (int)((B - 122.1) / 365.25);
126     int D = (int)(C * 365.25);
127     int E = (int)((B - D) / 30.6001);
128    
129     double DOM = B - D - (int)(E * 30.6001) + F;
130     int month = (E < 13.5) ? (E - 1) : (E - 13);
131     int year = (month > 2.5) ? (C - 4716) : (C - 4715);
132    
133     *pYear = year;
134    
135     if (pMon != NULL)
136     *pMon = month;
137    
138     if (pDOM != NULL)
139     *pDOM = DOM;
140     }
141    
142     //////////////////////////////////////////////////////////////////////////////
143     // toGMST()
144     // Calculate Greenwich Mean Sidereal Time for the Julian date. The return value
145     // is the angle, in radians, measuring eastward from the Vernal Equinox to the
146     // prime meridian. This angle is also referred to as "ThetaG" (Theta GMST).
147     //
148     // References:
149     // The 1992 Astronomical Almanac, page B6.
150     // Explanatory Supplement to the Astronomical Almanac, page 50.
151     // Orbital Coordinate Systems, Part III, Dr. T.S. Kelso, Satellite Times,
152     // Nov/Dec 1995
153     double cJulian::toGMST() const
154     {
155     const double UT = fmod(m_Date + 0.5, 1.0);
156     const double TU = (FromJan1_12h_2000() - UT) / 36525.0;
157    
158     double GMST = 24110.54841 + TU *
159     (8640184.812866 + TU * (0.093104 - TU * 6.2e-06));
160    
161     GMST = fmod(GMST + SEC_PER_DAY * OMEGA_E * UT, SEC_PER_DAY);
162    
163     if (GMST < 0.0)
164     GMST += SEC_PER_DAY; // "wrap" negative modulo value
165    
166     return (TWOPI * (GMST / SEC_PER_DAY));
167     }
168    
169     //////////////////////////////////////////////////////////////////////////////
170     // toLMST()
171     // Calculate Local Mean Sidereal Time for given longitude (for this date).
172     // The longitude is assumed to be in radians measured west from Greenwich.
173     // The return value is the angle, in radians, measuring eastward from the
174     // Vernal Equinox to the given longitude.
175     double cJulian::toLMST(double lon) const
176     {
177     return fmod(toGMST() + lon, TWOPI);
178     }
179    
180     //////////////////////////////////////////////////////////////////////////////
181     // toTime()
182     // Convert to type time_t
183     // Avoid using this function as it discards the fractional seconds of the
184     // time component.
185     time_t cJulian::toTime() const
186     {
187     int nYear;
188     int nMonth;
189     double dblDay;
190    
191     getComponent(&nYear, &nMonth, &dblDay);
192    
193     // dblDay is the fractional Julian Day (i.e., 29.5577).
194     // Save the whole number day in nDOM and convert dblDay to
195     // the fractional portion of day.
196     int nDOM = (int)dblDay;
197    
198     dblDay -= nDOM;
199    
200     const int SEC_PER_MIN = 60;
201     const int SEC_PER_HR = 60 * SEC_PER_MIN;
202     const int SEC_PER_DAY = 24 * SEC_PER_HR;
203    
204     int secs = (int)((dblDay * SEC_PER_DAY) + 0.5);
205    
206     // Create a "struct tm" type.
207     // NOTE:
208     // The "struct tm" type has a 1-second resolution. Any fractional
209     // component of the "seconds" time value is discarded.
210     struct tm tGMT;
211     memset(&tGMT, 0, sizeof(tGMT));
212    
213     tGMT.tm_year = nYear - 1900; // 2001 is 101
214     tGMT.tm_mon = nMonth - 1; // January is 0
215     tGMT.tm_mday = nDOM; // First day is 1
216     tGMT.tm_hour = secs / SEC_PER_HR;
217     tGMT.tm_min = (secs % SEC_PER_HR) / SEC_PER_MIN;
218     tGMT.tm_sec = (secs % SEC_PER_HR) % SEC_PER_MIN;
219     tGMT.tm_isdst = 0; // No conversion desired
220    
221     time_t tEpoch = mktime(&tGMT);
222    
223     if (tEpoch != -1)
224     {
225     // Valid time_t value returned from mktime().
226     // mktime() expects a local time which means that tEpoch now needs
227     // to be adjusted by the difference between this time zone and GMT.
228     tEpoch -= timezone;
229     }
230    
231     return tEpoch;
232     }

  ViewVC Help
Powered by ViewVC 1.1.23