//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
+// Library General Public License for more details.
//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
//
// $Id$
#define RADHR(x) DEGHR(x*RAD_TO_DEG)
-SGTime::SGTime( const string& root )
+static const double MJD0 = 2415020.0;
+static const double J2000 = 2451545.0 - MJD0;
+static const double SIDRATE = 0.9972695677;
+
+
+SGTime::SGTime( double lon, double lat, const string& root )
{
- FGPath zone( root );
- zone.append( "Timezone" );
- zone.append( "zone.tab" );
+ FG_LOG( FG_EVENT, FG_INFO, "Initializing Time" );
- FG_LOG( FG_EVENT, FG_DEBUG, "Reading timezone info from: " << zone.str() );
- tzContainer = new TimezoneContainer( zone.c_str() );
+ gst_diff = -9999.0;
- zonename = NULL;
+ cur_time = time(NULL);
+ // cout << "Current greenwich mean time = " << asctime(gmtime(&cur_time))
+ // << endl;
+ // cout << "Current local time = "
+ // << asctime(localtime(&cur_time)) << endl;
+
+ if ( root != "" ) {
+ FGPath zone( root );
+ zone.append( "zone.tab" );
+ FG_LOG( FG_EVENT, FG_DEBUG, "Reading timezone info from: "
+ << zone.str() );
+ tzContainer = new TimezoneContainer( zone.c_str() );
+
+ GeoCoord location( RAD_TO_DEG * lat, RAD_TO_DEG * lon );
+ GeoCoord* nearestTz = tzContainer->getNearest(location);
+
+ FGPath name( root );
+ name.append( nearestTz->getDescription() );
+ zonename = strdup( name.c_str() );
+ // cout << "Using zonename = " << zonename << endl;
+ } else {
+ tzContainer = NULL;
+ zonename = NULL;
+ }
+}
+
+
+SGTime::SGTime( const string& root ) {
+ SGTime( 0.0, 0.0, root );
+}
+
+
+SGTime::SGTime() {
+ SGTime( 0.0, 0.0, "" );
}
SGTime::~SGTime()
{
- delete tzContainer;
+ if ( tzContainer != NULL ) {
+ delete tzContainer;
+ }
if ( zonename != NULL ) {
delete zonename;
}
-// Initialize the time related variables
-void SGTime::init( double lon, double lat, const string& root )
+// given Julian Date and Longitude (decimal degrees West) compute
+// Local Sidereal Time, in decimal hours.
+//
+// Provided courtesy of ecdowney@noao.edu (Elwood Downey)
+static double sidereal_precise( double mjd, double lng )
{
- FG_LOG( FG_EVENT, FG_INFO, "Initializing Time" );
- gst_diff = -9999.0;
-
- // time_t currGMT;
- // time_t systemLocalTime;
- // time_t aircraftLocalTime;
-
- // would it be better to put these sanity checks in the options
- // parsing code? (CLO)
-
- cur_time = time(NULL);
-
- // printf ("Current greenwich mean time = %24s", asctime(gmtime(&cur_time)));
- // printf ("Current local time = %24s", asctime(localtime(&cur_time)));
- // time_t tmp = cur_time;
- GeoCoord location( RAD_TO_DEG * lat, RAD_TO_DEG * lon );
+ /* printf ("Current Lst on JD %13.5f at %8.4f degrees West: ",
+ mjd + MJD0, lng); */
- GeoCoord* nearestTz = tzContainer->getNearest(location);
+ // convert to required internal units
+ lng *= DEG_TO_RAD;
- FGPath zone( root );
- zone.append( "Timezone" );
- zone.append( nearestTz->getDescription() );
+ // compute LST and print
+ double gst = sgTimeCalcGST( mjd );
+ double lst = gst - RADHR( lng );
+ lst -= 24.0 * floor( lst / 24.0 );
+ // printf ("%7.4f\n", lstTmp);
- // cout << "Using " << zone.str() << " for timezone information" << endl;
- zonename = strdup( zone.c_str() );
- // cout << "zonename = " << zonename << endl;
- //show( buffer.c_str(), cur_time, 1);
- //printf ("Current greenwich mean time = %24s", asctime(gmtime(&cur_time)));
- //printf ("Current local time = %24s", asctime(localtime(&cur_time)));
- // currGMT = get_gmt( gmtime(&cur_time) );
- // cout << "currGMT = " << currGMT << endl;
+ return lst;
+}
- // systemLocalTime = get_gmt( localtime(&cur_time) );
- // cout << "systemLocalTime = " << systemLocalTime << endl;
- // aircraftLocalTime = get_gmt( fgLocaltime(&cur_time, zone.c_str()) );
- //printf ("Current greenwich mean time = %24s", asctime(gmtime(&cur_time)));
- //printf ("Current local time = %24s", asctime(localtime(&cur_time)));
+// return a courser but cheaper estimate of sidereal time
+static double sidereal_course( time_t cur_time, struct tm *gmt, double lng )
+{
+ time_t start_gmt, now;
+ double diff, part, days, hours, lstTmp;
+ char tbuf[64];
+
+ now = cur_time;
+ start_gmt = sgTimeGetGMT(gmt->tm_year, 2, 21, 12, 0, 0);
+
+ FG_LOG( FG_EVENT, FG_DEBUG, " COURSE: GMT = "
+ << sgTimeFormatTime(gmt, tbuf) );
+ FG_LOG( FG_EVENT, FG_DEBUG, " March 21 noon (GMT) = " << start_gmt );
+
+ diff = (now - start_gmt) / (3600.0 * 24.0);
+
+ FG_LOG( FG_EVENT, FG_DEBUG,
+ " Time since 3/21/" << gmt->tm_year << " GMT = " << diff );
+
+ part = fmod(diff, 1.0);
+ days = diff - part;
+ hours = gmt->tm_hour + gmt->tm_min/60.0 + gmt->tm_sec/3600.0;
+
+ lstTmp = (days - lng)/15.0 + hours - 12;
+
+ while ( lstTmp < 0.0 ) {
+ lstTmp += 24.0;
+ }
+
+ FG_LOG( FG_EVENT, FG_DEBUG,
+ " days = " << days << " hours = " << hours << " lon = "
+ << lng << " lst = " << lstTmp );
+
+ return lstTmp;
}
// Update the time related variables
-void SGTime::update( double lon, double lat, double alt_m, long int warp ) {
+void SGTime::update( double lon, double lat, long int warp ) {
double gst_precise, gst_course;
FG_LOG( FG_EVENT, FG_DEBUG, "Updating time" );
// first time through do the expensive calculation & cheap
// calculation to get the difference.
FG_LOG( FG_EVENT, FG_INFO, " First time, doing precise gst" );
- gst_precise = gst = sidereal_precise(0.00);
- gst_course = sidereal_course(0.00);
+ gst_precise = gst = sidereal_precise( mjd, 0.00 );
+ gst_course = sidereal_course( cur_time, gmt, 0.00 );
gst_diff = gst_precise - gst_course;
- lst = sidereal_course(-(lon * RAD_TO_DEG)) + gst_diff;
+ lst = sidereal_course( cur_time, gmt, -(lon * RAD_TO_DEG) ) + gst_diff;
} else {
// course + difference should drift off very slowly
- gst = sidereal_course( 0.00 ) + gst_diff;
- lst = sidereal_course( -(lon * RAD_TO_DEG)) + gst_diff;
+ gst = sidereal_course( cur_time, gmt, 0.00 ) + gst_diff;
+ lst = sidereal_course( cur_time, gmt, -(lon * RAD_TO_DEG) ) + gst_diff;
}
FG_LOG( FG_EVENT, FG_DEBUG,
" Current lon=0.00 Sidereal Time = " << gst );
FG_LOG( FG_EVENT, FG_DEBUG,
" Current LOCAL Sidereal Time = " << lst << " ("
- << sidereal_precise(-(lon * RAD_TO_DEG))
+ << sidereal_precise( mjd, -(lon * RAD_TO_DEG) )
<< ") (diff = " << gst_diff << ")" );
}
GeoCoord location( RAD_TO_DEG * lat, RAD_TO_DEG * lon );
GeoCoord* nearestTz = tzContainer->getNearest(location);
FGPath zone( root );
- zone.append ("Timezone" );
zone.append ( nearestTz->getDescription() );
if ( zonename ) {
delete zonename;
}
zonename = strdup( zone.c_str() );
- currGMT = get_gmt( gmtime(&cur_time) );
- aircraftLocalTime = get_gmt( (fgLocaltime(&cur_time, zone.c_str())) );
+ currGMT = sgTimeGetGMT( gmtime(&cur_time) );
+ aircraftLocalTime = sgTimeGetGMT( (fgLocaltime(&cur_time, zone.c_str())) );
local_offset = aircraftLocalTime - currGMT;
// cout << "Using " << local_offset << " as local time offset Timezone is "
// << zonename << endl;
}
-// given Julian Date and Longitude (decimal degrees West) compute
-// Local Sidereal Time, in decimal hours.
-//
-// Provided courtesy of ecdowney@noao.edu (Elwood Downey)
-double SGTime::sidereal_precise( double lng )
-{
- double lstTmp;
-
- /* printf ("Current Lst on JD %13.5f at %8.4f degrees West: ",
- mjd + MJD0, lng); */
-
- // convert to required internal units
- lng *= DEG_TO_RAD;
-
- // compute LST and print
- gst = sgTimeCalcGST( mjd );
- lstTmp = gst - RADHR (lng);
- lstTmp -= 24.0*floor(lstTmp/24.0);
- // printf ("%7.4f\n", lstTmp);
-
- // that's all
- return (lstTmp);
-}
-
-
-// return a courser but cheaper estimate of sidereal time
-double SGTime::sidereal_course( double lng )
-{
- time_t start_gmt, now;
- double diff, part, days, hours, lstTmp;
- char tbuf[64];
-
- now = cur_time;
- start_gmt = get_gmt(gmt->tm_year, 2, 21, 12, 0, 0);
-
- FG_LOG( FG_EVENT, FG_DEBUG, " COURSE: GMT = "
- << sgTimeFormatTime(gmt, tbuf) );
- FG_LOG( FG_EVENT, FG_DEBUG, " March 21 noon (GMT) = " << start_gmt );
-
- diff = (now - start_gmt) / (3600.0 * 24.0);
-
- FG_LOG( FG_EVENT, FG_DEBUG,
- " Time since 3/21/" << gmt->tm_year << " GMT = " << diff );
-
- part = fmod(diff, 1.0);
- days = diff - part;
- hours = gmt->tm_hour + gmt->tm_min/60.0 + gmt->tm_sec/3600.0;
-
- lstTmp = (days - lng)/15.0 + hours - 12;
-
- while ( lstTmp < 0.0 ) {
- lstTmp += 24.0;
- }
-
- FG_LOG( FG_EVENT, FG_DEBUG,
- " days = " << days << " hours = " << hours << " lon = "
- << lng << " lst = " << lstTmp );
-
- return(lstTmp);
-}
-
-
// given a date in months, mn, days, dy, years, yr, return the
// modified Julian date (number of days elapsed since 1900 jan 0.5),
// mjd. Adapted from Xephem.
// If you are having problems with incorrectly positioned astronomical
// bodies, this is a really good place to start looking.
-time_t SGTime::get_gmt(int year, int month, int day, int hour, int min, int sec)
+time_t sgTimeGetGMT(int year, int month, int day, int hour, int min, int sec)
{
struct tm mt;
# define TIMEZONE_OFFSET_WORKS 1
# endif
- long int start = mktime(&mt);
+ time_t start = mktime(&mt);
FG_LOG( FG_EVENT, FG_DEBUG, "start1 = " << start );
// the ctime() call can screw up time progression on some versions