+// Given lon/lat, update timezone information and local_offset
+void SGTime::updateLocal( const SGGeod& aLocation, const string& root ) {
+ SGGeod location(aLocation);
+ if (!aLocation.isValid()) {
+ location = SGGeod();
+ }
+
+ time_t currGMT;
+ time_t aircraftLocalTime;
+ SGTimeZone* nearestTz = static_tzContainer->getNearest(location);
+ SGPath zone( root );
+ zone.append ( nearestTz->getDescription() );
+ zonename = zone.str();
+
+ //Avoid troubles when zone.tab hasn't got the right line endings
+ if (zonename[zonename.size()-1] == '\r')
+ {
+ zonename[zonename.size()-1]=0;
+ zone.set( zonename );
+ }
+
+ 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 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.
+double sgTimeCalcMJD(int mn, double dy, int yr) {
+ double mjd;
+
+ // internal book keeping data
+ static double last_mjd, last_dy;
+ static int last_mn, last_yr;
+
+ int b, d, m, y;
+ long c;
+
+ if (mn == last_mn && yr == last_yr && dy == last_dy) {
+ mjd = last_mjd;
+ }
+
+ m = mn;
+ y = (yr < 0) ? yr + 1 : yr;
+ if (mn < 3) {
+ m += 12;
+ y -= 1;
+ }
+
+ if (yr < 1582 || (yr == 1582 && (mn < 10 || (mn == 10 && dy < 15)))) {
+ b = 0;
+ } else {
+ int a;
+ a = y/100;
+ b = 2 - a + a/4;
+ }
+
+ if (y < 0) {
+ c = (long)((365.25*y) - 0.75) - 694025L;
+ } else {
+ c = (long)(365.25*y) - 694025L;
+ }
+
+ d = (int)(30.6001*(m+1));
+
+ mjd = b + c + d + dy - 0.5;
+
+ last_mn = mn;
+ last_dy = dy;
+ last_yr = yr;
+ last_mjd = mjd;
+
+ return mjd;
+}
+
+
+// return the current modified Julian date (number of days elapsed
+// since 1900 jan 0.5), mjd.
+double sgTimeCurrentMJD( time_t ct, long int warp ) {
+
+ struct tm m_gmt; // copy of system gmtime(&time_t) structure
+ struct tm *gmt = &m_gmt;
+
+ // get current Unix calendar time (in seconds)
+ // warp += warp_delta;
+ time_t cur_time;
+ if ( ct ) {
+ cur_time = ct + warp;
+ } else {
+ cur_time = time(NULL) + warp;
+ }
+ SG_LOG( SG_EVENT, SG_DEBUG,
+ " Current Unix calendar time = " << cur_time
+ << " warp = " << warp );
+
+ // get GMT break down for current time
+ memcpy( gmt, gmtime(&cur_time), sizeof(tm) );
+ SG_LOG( SG_EVENT, SG_DEBUG,
+ " Current GMT = " << gmt->tm_mon+1 << "/"
+ << gmt->tm_mday << "/" << (1900 + gmt->tm_year) << " "
+ << gmt->tm_hour << ":" << gmt->tm_min << ":"
+ << gmt->tm_sec );
+
+ // calculate modified Julian date
+ // t->mjd = cal_mjd ((int)(t->gmt->tm_mon+1), (double)t->gmt->tm_mday,
+ // (int)(t->gmt->tm_year + 1900));
+ double mjd = sgTimeCalcMJD( (int)(gmt->tm_mon+1), (double)gmt->tm_mday,
+ (int)(gmt->tm_year + 1900) );
+
+ return mjd;
+}
+
+
+// given an mjd, calculate greenwich mean sidereal time, gst
+double sgTimeCalcGST( double mjd ) {
+ double gst;
+
+ double day = floor(mjd-0.5)+0.5;
+ double hr = (mjd-day)*24.0;
+ double T, x;
+
+ T = ((int)(mjd - 0.5) + 0.5 - J2000)/36525.0;
+ x = 24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6 * T) * T) * T;
+ x /= 3600.0;
+ gst = (1.0/SIDRATE)*hr + x;
+
+ SG_LOG( SG_EVENT, SG_DEBUG, " gst => " << gst );
+
+ return gst;
+}
+
+
+#if defined( HAVE_TIMEGM )
+ // ignore this function
+#elif defined( MK_TIME_IS_GMT )
+ // ignore this function
+#else // ! defined ( MK_TIME_IS_GMT )
+
+ // Fix up timezone if using ftime()
+ static long int fix_up_timezone( long int timezone_orig ) {
+# if !defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_FTIME )
+ // ftime() needs a little extra help finding the current timezone
+ struct timeb current;
+ ftime(¤t);
+ return( current.timezone * 60 );
+# else
+ return( timezone_orig );
+# endif
+ }
+#endif
+
+