Index: trunk/psLib/src/astronomy/psTime.c
===================================================================
--- trunk/psLib/src/astronomy/psTime.c	(revision 2607)
+++ trunk/psLib/src/astronomy/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;
+}
+
