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

Contents of /yodaUtility/sgp4/cJulian.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Sun Apr 30 11:08:14 2006 UTC (18 years, 7 months ago) by kusanagi
Branch: MAIN
CVS Tags: yodaUtility2_0/00, yodaUtility1_0/00, yodaUtility2_2/00, yodaUtility2_1/00, HEAD
Changes since 1.1: +0 -0 lines
Various utilities for the yoda environment and its related softwares.
YFile 	   	- Inheriths from TFile     - Add custom features to a TFile object.
YException 	- Inheriths from exception - YODA specific Exceptions.
YMcmd	   	- Decoder for the Mcmd packets.
YSQLConnection 	- Singletn class for DB connections.
yodaUtility     - Various functions.
sgp4		- C++ NORAD SGP4/SDP4 Implementation - Developed by Michael F. Henry.

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