Index: trunk/psLib/src/astro/psTime.c
===================================================================
--- trunk/psLib/src/astro/psTime.c	(revision 2664)
+++ trunk/psLib/src/astro/psTime.c	(revision 2725)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.46 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-03 23:15:00 $
+ *  @version $Revision: 1.47 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-16 18:52:41 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -151,5 +151,5 @@
     // Check time metadata. Function call reports errors.
     if(timeMetadata == NULL) {
-        if(!psTimeInit(TIME_CONFIG_FILE))
+        if(!p_psTimeInit(TIME_CONFIG_FILE))
             return 0.0;
     }
@@ -184,5 +184,5 @@
 }
 
-bool psTimeInit(const char *fileName)
+bool p_psTimeInit(const char *fileName)
 {
     bool foundTable = false;
@@ -326,5 +326,5 @@
 }
 
-bool psTimeFinalize(void)
+bool p_psTimeFinalize(void)
 {
     if(timeMetadata != NULL) {
@@ -405,7 +405,5 @@
         time->sec = time->sec + delta;    // User wants TAI time. Add leapseconds.
     } else {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                PS_ERRORTEXT_psTime_TYPE_UNKNOWN,
-                type);
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_TYPE_UNKNOWN, type);
     }
 
@@ -431,5 +429,4 @@
     psF64  const6       =  0.0000013;
     psTime *ut1UtcDelta = NULL;
-    psTime *tdtDelta    = NULL;
     psTime *tdtTime     = NULL;
     psTime *taiTime     = NULL;
@@ -456,12 +453,8 @@
 
     // Convert Universal Time (UTC) to  UT1
-    ut1UtcDelta = psTimeAlloc(PS_TIME_UTC);
-    ut1UtcDbl = psTimeGetUT1Delta(taiTime)*1e6;
-    ut1UtcDelta->usec = (psU32)fabs(ut1UtcDbl);
-    if(ut1UtcDbl<0) {
-        ut1Time = psTimeSubtract(utcTime, ut1UtcDelta);
-    } else {
-        ut1Time = psTimeAdd(utcTime, ut1UtcDelta);
-    }
+    ut1UtcDbl = psTimeGetUT1Delta(taiTime);
+    utcTime->type = PS_TIME_TAI; // Don't allow addition of leapseconds to ut1Time
+    ut1Time = psTimeMath(utcTime, ut1UtcDbl);
+    utcTime->type = PS_TIME_UTC;
 
     // Calculate UT1 as Julian Centuries since J2000.0
@@ -471,8 +464,5 @@
 
     // Calculate Terrestial Dynamical Time (TDT)
-    tdtDelta = psTimeAlloc(PS_TIME_TAI);
-    tdtDelta->sec = 32;
-    tdtDelta->usec = 184000;
-    tdtTime = psTimeAdd(taiTime, tdtDelta);
+    tdtTime = psTimeMath(taiTime, 32.184);
 
     // Calculate TDT as Julian centuries since J2000.0
@@ -496,5 +486,4 @@
     psFree(ut1Time);
     psFree(tdtTime);
-    psFree(tdtDelta);
     psFree(utcTime);
     psFree(taiTime);
@@ -718,7 +707,8 @@
     // Check time metadata
     if(timeMetadata == NULL) {
-        if(!psTimeInit(TIME_CONFIG_FILE))
+        if(!p_psTimeInit(TIME_CONFIG_FILE)) {
             psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_FILE_NOT_FOUND, "psTime.config");
-        return 0.0;
+            return 0.0;
+        }
     }
 
@@ -741,5 +731,5 @@
     // Check for successful interpolation
     for(i=0; i<stats->n; i++) {
-        if(stats->data.U32[i]!=PS_LOOKUP_PAST_BOTTOM && stats->data.U32[i]!=PS_LOOKUP_PAST_TOP) {
+        if(stats->data.U32[i] == PS_LOOKUP_ERROR) {
             psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_INTERPOLATION_FAILED);
         }
@@ -835,11 +825,9 @@
     // Converts psTime to YYYY-MM-DDThh:mm:ss.sss in string form
     if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) {
-        psError(PS_ERR_OS_CALL_FAILED, true,
-                PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED);
+        psError(PS_ERR_OS_CALL_FAILED, true, PS_ERRORTEXT_psTime_CONVERT_TIME_TO_STRING_FAILED);
     }
 
     if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) {
-        psError(PS_ERR_OS_CALL_FAILED, true,
-                PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED);
+        psError(PS_ERR_OS_CALL_FAILED, true, PS_ERRORTEXT_psTime_APPEND_MSEC_FAILED);
     }
     psFree(tempString);
@@ -987,10 +975,7 @@
 
     // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time
-    if (sscanf(time, "%d-%d-%dT%d:%d:%d.%d",
-               &tmTime.tm_year,&tmTime.tm_mon,&tmTime.tm_mday,
-               &tmTime.tm_hour,&tmTime.tm_min,&tmTime.tm_sec,&millisecond) < 7) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                PS_ERRORTEXT_psTime_ISOTIME_MALFORMED,
-                time);
+    if (sscanf(time, "%d-%d-%dT%d:%d:%d.%d", &tmTime.tm_year, &tmTime.tm_mon, &tmTime.tm_mday,
+               &tmTime.tm_hour, &tmTime.tm_min, &tmTime.tm_sec,&millisecond) < 7) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true, PS_ERRORTEXT_psTime_ISOTIME_MALFORMED, time);
         return NULL;
     }
@@ -1095,121 +1080,92 @@
 }
 
-psTime* psTimeAdd(const psTime *tai1, const psTime *tai2)
-{
-    psF64 deltaSec = 0;
-    psS64 deltaUsec = 0;
+psTime* psTimeMath(const psTime *time, psF64 delta)
+{
+    psS64 deltaSec = 0;
+    psF64 uSecTimeInput = 0.0;
     psTime *outTime = NULL;
-
-
-    // Error checks
-    PS_PTR_CHECK_NULL(tai1,NULL);
-    PS_PTR_CHECK_NULL(tai2,NULL);
-    PS_INT_CHECK_RANGE(tai1->usec,0,1e6-1,NULL);
-    PS_INT_CHECK_RANGE(tai2->usec,0,1e6-1,NULL);
-
-    if(tai1->type != tai2->type) {
-        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                PS_ERRORTEXT_psTime_TYPE_MISMATCH);
-        return NULL;
-    }
-
-    outTime = psTimeAlloc(tai1->type);
-    outTime->sec = tai1->sec + tai2->sec;
-    deltaUsec = tai1->usec + tai2->usec;
-
-    // Adjust time in case of microsecond overflow after addition
-    if(deltaUsec >= 1e6) {
-        if(deltaSec < 0 ) {
-            outTime->sec--; // Negative seconds - make more negative
-        } else {
-            outTime->sec++; // Positive seconds - make more positive
-        }
-        outTime->usec = deltaUsec - 1e6;
+    psTime *tempTime = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time,NULL);
+    PS_INT_CHECK_RANGE(time->usec,0,1e6-1,NULL);
+
+    // Convert time to TAI if necessary, but without changing input arguments
+    if(time->type == PS_TIME_UTC) {
+        tempTime = psTimeAlloc(PS_TIME_UTC);
+        tempTime->sec = time->sec;
+        tempTime->usec = time->usec;
+        tempTime = psTimeConvert(tempTime, PS_TIME_TAI);
     } else {
-        outTime->usec = deltaUsec;
-    }
+        tempTime = psMemIncrRefCounter((psTime*)time);
+    }
+
+    uSecTimeInput = tempTime->sec >= 0 ? 1.0 : -1.0;
+    uSecTimeInput = uSecTimeInput*tempTime->usec/1e6;
+    delta = delta + uSecTimeInput;
+    deltaSec = (psS64)delta;
+
+    // Create output time
+    outTime = psTimeAlloc(PS_TIME_TAI);
+    outTime->sec = delta + (psF64)tempTime->sec;
+    outTime->usec = fabs((delta-(psF64)deltaSec)*1e6);
 
     // Error check
     PS_INT_CHECK_RANGE(outTime->usec,0,1e6-1,outTime);
 
+    // Convert result to same time type as input
+    if(time->type == PS_TIME_UTC) {
+        outTime = psTimeConvert(outTime, PS_TIME_UTC);
+    }
+
+    psFree(tempTime);
+
     return outTime;
 }
 
-psTime* psTimeSubtract(const psTime *tai1, const psTime *tai2)
-{
-    psS64 deltaSec = 0;
-    psS64 deltaUsec = 0;
-    psTime *outTime = NULL;
-
-
-    // Error checks
-    PS_PTR_CHECK_NULL(tai1,NULL);
-    PS_PTR_CHECK_NULL(tai2,NULL);
-    PS_INT_CHECK_RANGE(tai1->usec,0,1e6-1,NULL);
-    PS_INT_CHECK_RANGE(tai2->usec,0,1e6-1,NULL);
-    if(tai1->type != tai2->type) {
-        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                PS_ERRORTEXT_psTime_TYPE_MISMATCH);
-        return NULL;
-    }
-
-    outTime = psTimeAlloc(tai1->type);
-    deltaSec = tai1->sec - tai2->sec;
-    deltaUsec = (psS64)tai1->usec - (psS64)tai2->usec;
-
-    // Adjust time in case of microsecond underflow after subtraction
-    if(deltaUsec < 0) {
-        if(deltaSec < 0) {
-            deltaSec++; // Negative seconds - make less negative
-        } else {
-            deltaSec--; // Positive seconds - make less positive
-        }
-        outTime->usec = 1e6+deltaUsec;
+psF64 psTimeDelta(const psTime *time1, const psTime *time2)
+{
+    psF64 out = 0.0;
+    psF64 uSec1 = 0.0;
+    psF64 uSec2 = 0.0;
+    psTime *tempTime1 = NULL;
+    psTime *tempTime2 = NULL;
+
+
+    // Error checks
+    PS_PTR_CHECK_NULL(time1,0.0);
+    PS_INT_CHECK_RANGE(time1->usec,0,1e6-1,0.0);
+    PS_PTR_CHECK_NULL(time2,0.0);
+    PS_INT_CHECK_RANGE(time2->usec,0,1e6-1,0.0);
+
+    // Convert time to TAI if necessary, but without changing input arguments
+    if(time1->type == PS_TIME_UTC) {
+        tempTime1 = psTimeAlloc(PS_TIME_UTC);
+        tempTime1->sec = time1->sec;
+        tempTime1->usec = time1->usec;
+        tempTime1 = psTimeConvert(tempTime1, PS_TIME_TAI);
     } else {
-        outTime->usec = deltaUsec;
-    }
-
-    outTime->sec = deltaSec;
-
-    return outTime;
-}
-
-psTime* psTimeDelta(const psTime *tai1, const psTime *tai2)
-{
-    psS64 deltaSec = 0;
-    psS64 deltaUsec = 0;
-    psTime *outTime = NULL;
-
-
-    // Error checks
-    // Error checks
-    PS_PTR_CHECK_NULL(tai1,NULL);
-    PS_PTR_CHECK_NULL(tai2,NULL);
-    PS_INT_CHECK_RANGE(tai1->usec,0,1e6-1,NULL);
-    PS_INT_CHECK_RANGE(tai2->usec,0,1e6-1,NULL);
-    if(tai1->type != tai2->type) {
-        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                PS_ERRORTEXT_psTime_TYPE_MISMATCH);
-        return NULL;
-    }
-
-    outTime = psTimeAlloc(tai1->type);
-    deltaSec = tai1->sec - tai2->sec;
-    deltaUsec = (psS64)tai1->usec - (psS64)tai2->usec;
-
-    // Adjust time in case of microsecond underflow after subtraction
-    if(deltaUsec < 0) {
-        if(deltaSec < 0) {
-            deltaSec++; // Negative seconds - make less negative
-        } else {
-            deltaSec--; // Positive seconds - make less positive
-        }
-        outTime->usec = 1e6+deltaUsec;
+        tempTime1 = psMemIncrRefCounter((psTime*)time1);
+    }
+    if(time2->type == PS_TIME_UTC) {
+        tempTime2 = psTimeAlloc(PS_TIME_UTC);
+        tempTime2->sec = time2->sec;
+        tempTime2->usec = time2->usec;
+        tempTime2 = psTimeConvert(tempTime2, PS_TIME_TAI);
     } else {
-        outTime->usec = deltaUsec;
-    }
-
-    outTime->sec = abs(deltaSec);
-
-    return outTime;
-}
+        tempTime2 = psMemIncrRefCounter((psTime*)time2);
+    }
+
+    uSec1 = tempTime1->sec >= 0 ? 1.0 : -1.0;
+    uSec1 = uSec1*tempTime1->usec/1e6;
+    uSec2 = tempTime2->sec >= 0 ? 1.0 : -1.0;
+    uSec2 = uSec2*tempTime2->usec/1e6;
+    out = (tempTime1->sec-tempTime2->sec) + (uSec1-uSec2);
+
+    psFree(tempTime1);
+    psFree(tempTime2);
+
+    return out;
+}
+
Index: trunk/psLib/src/astro/psTime.h
===================================================================
--- trunk/psLib/src/astro/psTime.h	(revision 2664)
+++ trunk/psLib/src/astro/psTime.h	(revision 2725)
@@ -5,58 +5,15 @@
  *
  *  A collection of functions are required by psLib to manipulate time data. These functions primarily consist
- *  of conversions between specific time formats.  PSLib currently uses the UNIX timeval time system as the
- *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI
- *  time varies over time due to the earth's rotation and the movement of the continental plates. It is
- *  currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates
- *  is given in the table below, which comes from:
- *
- *  ftp://maia.usno.navy.mil/ser7/tai-utc.dat
- *
- *  This table is placed into a static array and used by the psTime functions for conversions.
- *
- *   1961 JAN  1 =JD 2437300.5  TAI-UTC=   1.4228180 S + (MJD - 37300.) X 0.001296 S
- *   1961 AUG  1 =JD 2437512.5  TAI-UTC=   1.3728180 S + (MJD - 37300.) X 0.001296 S
- *   1962 JAN  1 =JD 2437665.5  TAI-UTC=   1.8458580 S + (MJD - 37665.) X 0.0011232S
- *   1963 NOV  1 =JD 2438334.5  TAI-UTC=   1.9458580 S + (MJD - 37665.) X 0.0011232S
- *   1964 JAN  1 =JD 2438395.5  TAI-UTC=   3.2401300 S + (MJD - 38761.) X 0.001296 S
- *   1964 APR  1 =JD 2438486.5  TAI-UTC=   3.3401300 S + (MJD - 38761.) X 0.001296 S
- *   1964 SEP  1 =JD 2438639.5  TAI-UTC=   3.4401300 S + (MJD - 38761.) X 0.001296 S
- *   1965 JAN  1 =JD 2438761.5  TAI-UTC=   3.5401300 S + (MJD - 38761.) X 0.001296 S
- *   1965 MAR  1 =JD 2438820.5  TAI-UTC=   3.6401300 S + (MJD - 38761.) X 0.001296 S
- *   1965 JUL  1 =JD 2438942.5  TAI-UTC=   3.7401300 S + (MJD - 38761.) X 0.001296 S
- *   1965 SEP  1 =JD 2439004.5  TAI-UTC=   3.8401300 S + (MJD - 38761.) X 0.001296 S
- *   1966 JAN  1 =JD 2439126.5  TAI-UTC=   4.3131700 S + (MJD - 39126.) X 0.002592 S
- *   1968 FEB  1 =JD 2439887.5  TAI-UTC=   4.2131700 S + (MJD - 39126.) X 0.002592 S
- *   1972 JAN  1 =JD 2441317.5  TAI-UTC=  10.0       S + (MJD - 41317.) X 0.0      S
- *   1972 JUL  1 =JD 2441499.5  TAI-UTC=  11.0       S + (MJD - 41317.) X 0.0      S
- *   1973 JAN  1 =JD 2441683.5  TAI-UTC=  12.0       S + (MJD - 41317.) X 0.0      S
- *   1974 JAN  1 =JD 2442048.5  TAI-UTC=  13.0       S + (MJD - 41317.) X 0.0      S
- *   1975 JAN  1 =JD 2442413.5  TAI-UTC=  14.0       S + (MJD - 41317.) X 0.0      S
- *   1976 JAN  1 =JD 2442778.5  TAI-UTC=  15.0       S + (MJD - 41317.) X 0.0      S
- *   1977 JAN  1 =JD 2443144.5  TAI-UTC=  16.0       S + (MJD - 41317.) X 0.0      S
- *   1978 JAN  1 =JD 2443509.5  TAI-UTC=  17.0       S + (MJD - 41317.) X 0.0      S
- *   1979 JAN  1 =JD 2443874.5  TAI-UTC=  18.0       S + (MJD - 41317.) X 0.0      S
- *   1980 JAN  1 =JD 2444239.5  TAI-UTC=  19.0       S + (MJD - 41317.) X 0.0      S
- *   1981 JUL  1 =JD 2444786.5  TAI-UTC=  20.0       S + (MJD - 41317.) X 0.0      S
- *   1982 JUL  1 =JD 2445151.5  TAI-UTC=  21.0       S + (MJD - 41317.) X 0.0      S
- *   1983 JUL  1 =JD 2445516.5  TAI-UTC=  22.0       S + (MJD - 41317.) X 0.0      S
- *   1985 JUL  1 =JD 2446247.5  TAI-UTC=  23.0       S + (MJD - 41317.) X 0.0      S
- *   1988 JAN  1 =JD 2447161.5  TAI-UTC=  24.0       S + (MJD - 41317.) X 0.0      S
- *   1990 JAN  1 =JD 2447892.5  TAI-UTC=  25.0       S + (MJD - 41317.) X 0.0      S
- *   1991 JAN  1 =JD 2448257.5  TAI-UTC=  26.0       S + (MJD - 41317.) X 0.0      S
- *   1992 JUL  1 =JD 2448804.5  TAI-UTC=  27.0       S + (MJD - 41317.) X 0.0      S
- *   1993 JUL  1 =JD 2449169.5  TAI-UTC=  28.0       S + (MJD - 41317.) X 0.0      S
- *   1994 JUL  1 =JD 2449534.5  TAI-UTC=  29.0       S + (MJD - 41317.) X 0.0      S
- *   1996 JAN  1 =JD 2450083.5  TAI-UTC=  30.0       S + (MJD - 41317.) X 0.0      S
- *   1997 JUL  1 =JD 2450630.5  TAI-UTC=  31.0       S + (MJD - 41317.) X 0.0      S
- *   1999 JAN  1 =JD 2451179.5  TAI-UTC=  32.0       S + (MJD - 41317.) X 0.0      S
+ *  of conversions between specific time formats.  They use the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated.
  *
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-11-10 18:27:08 $
+ *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-16 18:52:51 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
  */
+
 
 #ifndef PSTIME_H
@@ -107,5 +64,5 @@
  * @return  bool: True for success, false for failure.
  */
-psBool psTimeInit(const char *fileName);
+psBool p_psTimeInit(const char *fileName);
 
 /** Free memory persistant time data.
@@ -115,5 +72,5 @@
  * @return  void: void.
  */
-psBool psTimeFinalize(void);
+psBool p_psTimeFinalize(void);
 
 /** Allocate time struct.
@@ -305,36 +262,24 @@
 );
 
-/** Add two TAI times.
- *
- *  Adds two TAI times. This function does not add or subtract leapseconds.
+/** Adds delta to time. Result is in TAI time.
+ *
+ *  Adds delta to time. Input time is converted to TAI format if necessary.
  *
  *  @return  psTime*: time.
  */
-psTime* psTimeAdd(
-    const psTime *tai1,                 ///< First TAI time.
-    const psTime *tai2                  ///< Second TAI time.
-);
-
-/** Subtract two TAI times.
- *
- *  Subtracts two TAI times. This function does not add or subtract leapseconds.
- *
- *  @return  psTime*: time.
- */
-psTime* psTimeSubtract(
-    const psTime *tai1,                 ///< First TAI time.
-    const psTime *tai2                  ///< Second TAI time.
-);
-
-
-/** Find delta of two TAI times.
- *
- *  Finds the absolute difference of two TAI times. This function does not add or subtract leapseconds.
- *
- *  @return  psTime*: time.
- */
-psTime* psTimeDelta(
-    const psTime *tai1,                 ///< First TAI time.
-    const psTime *tai2                  ///< Second TAI time.
+psTime* psTimeMath(
+    const psTime *time,                 ///< Time.
+    psF64 delta                         ///< Time delta.
+);
+
+/** Determine difference between two times. Result is in TAI time.
+ *
+ *  Determine difference between two times. Input times are converted to TAI format if necessary.
+ *
+ *  @return psF64: Time difference.
+ */
+psF64 psTimeDelta(
+    const psTime *time1,                ///< First time.
+    const psTime *time2                 ///< Second time.
 );
 
