TimeConverters.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: TimeConverters.cpp 70 2006-08-01 18:36:21Z ehagen $"
00002 
00003 
00004 
00005 //============================================================================
00006 //
00007 //  This file is part of GPSTk, the GPS Toolkit.
00008 //
00009 //  The GPSTk is free software; you can redistribute it and/or modify
00010 //  it under the terms of the GNU Lesser General Public License as published
00011 //  by the Free Software Foundation; either version 2.1 of the License, or
00012 //  any later version.
00013 //
00014 //  The GPSTk is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with GPSTk; if not, write to the Free Software Foundation,
00021 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //  
00023 //  Copyright 2004, The University of Texas at Austin
00024 //
00025 //============================================================================
00026 
00027 #include "TimeConverters.hpp"
00028 #include "TimeConstants.hpp"
00029 #include <math.h>
00030 
00031 namespace gpstk
00032 {
00033 
00034       // These two routines convert 'integer JD' and calendar time; they were
00035       // derived from Sinnott, R. W. "Bits and Bytes" Sky & Telescope Magazine,
00036       // Vol 82, p. 183, August 1991, and The Astronomical Almanac, published
00037       // by the U.S. Naval Observatory.
00038       // NB range of applicability of this routine is from 0JD (4713BC)
00039       // to approx 3442448JD (4713AD).
00040    void convertJDtoCalendar( long jd, 
00041                              int& iyear, 
00042                              int& imonth,
00043                              int& iday )
00044       throw()
00045    {
00046       long L, M, N, P, Q;
00047       if(jd > 2299160)    // after Oct 4, 1582
00048       {
00049          L = jd + 68569;
00050          M = (4 * L) / 146097;
00051          L = L - ((146097 * M + 3) / 4);
00052          N = (4000 * (L + 1)) / 1461001;
00053          L = L - ((1461 * N) / 4) + 31;
00054          P = (80 * L) / 2447;
00055          iday = int(L - (2447 * P) / 80);
00056          L = P / 11;
00057          imonth = int(P + 2 - 12 * L);
00058          iyear = int(100 * (M - 49) + N + L);
00059       }
00060       else 
00061       {
00062          P = jd + 1402;
00063          Q = (P - 1) / 1461;
00064          L = P - 1461 * Q;
00065          M = (L - 1) / 365 - L / 1461;
00066          N = L - 365 * M + 30;
00067          P = (80 * N) / 2447;
00068          iday = int(N - (2447 * P) / 80);
00069          N = P / 11;
00070          imonth = int(P + 2 - 12 * N);
00071          iyear = int(4 * Q + M + N - 4716);
00072          if(iyear <= 0) 
00073          {
00074             --iyear;
00075          }
00076       }
00077          // catch century/non-400 non-leap years
00078       if(iyear > 1599 && 
00079          !(iyear % 100) && 
00080          (iyear % 400) && 
00081          imonth == 2 && 
00082          iday == 29)
00083       {
00084          imonth = 3;
00085          iday = 1;
00086       }
00087    }
00088    
00089    long convertCalendarToJD( int yy, 
00090                              int mm,
00091                              int dd ) 
00092       throw()
00093    {
00094       if(yy == 0)
00095          --yy;         // there is no year 0
00096 
00097       if(yy < 0) 
00098          ++yy;
00099       
00100       long jd;
00101       double y = static_cast<double>( yy ), 
00102          m = static_cast<double>( mm ), 
00103          d = static_cast<double>( dd );
00104 
00105          // In the conversion from the Julian Calendar to the Gregorian
00106          // Calendar the day after October 4, 1582 was October 15, 1582.
00107          //
00108          // if the date is before October 15, 1582
00109       if(yy < 1582 || (yy == 1582 && (mm < 10 || (mm == 10 && dd < 15))))
00110       {
00111          jd = 1729777 + dd + 367 * yy 
00112             - static_cast<long>(7 * ( y + 5001 +
00113                                       static_cast<long>((m - 9) / 7)) / 4) 
00114             + static_cast<long>(275 * m / 9);
00115       }
00116       else   // after Oct 4, 1582
00117       {     
00118         jd = 1721029 + dd + 367 * yy 
00119            - static_cast<long>(7 * (y + static_cast<long>((m + 9) / 12)) / 4)
00120            - static_cast<long>(3 * (static_cast<long>((y + (m - 9) / 7) / 100) 
00121                                     + 1) / 4) 
00122            + static_cast<long>(275 * m / 9);
00123 
00124             // catch century/non-400 non-leap years
00125          if( (! (yy % 100) && 
00126               (yy % 400) && 
00127               mm > 2 && 
00128               mm < 9)      || 
00129              (!((yy - 1) % 100) &&
00130               ((yy - 1) % 400) &&
00131               mm == 1)) 
00132          {
00133             --jd;
00134          }
00135       }
00136       return jd;
00137    }
00138 
00139    void convertSODtoTime( double sod, 
00140                           int& hh,
00141                           int& mm,
00142                           double& sec ) 
00143       throw()
00144    {
00145          // Get us to within one day.
00146       if (sod < 0)
00147       {
00148          sod += (1 + 
00149                  static_cast<unsigned long>(sod / SEC_PER_DAY)) * SEC_PER_DAY ;
00150       }
00151       else if (sod >= SEC_PER_DAY)
00152       {
00153          sod -= static_cast<unsigned long>(sod / SEC_PER_DAY) * SEC_PER_DAY ;
00154       }
00155       
00156       double temp;               // variable to hold the integer part of sod
00157       sod = modf(sod, &temp);    // sod holds the fraction, temp the integer
00158       long seconds = static_cast<long>(temp); // get temp into a real integer
00159 
00160       hh = seconds / 3600 ;
00161       mm = (seconds % 3600) / 60 ;
00162       sec = double(seconds % 60) + sod ;
00163 
00164    }
00165 
00166    double convertTimeToSOD( int hh, 
00167                             int mm,
00168                             double sec ) 
00169       throw()
00170    {
00171       return (sec + 60. * (mm + 60. * hh));
00172    }
00173 
00174 } // namespace

Generated on Wed Feb 8 03:31:03 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1