IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 24, 2004, 3:37:45 PM (22 years ago)
Author:
harman
Message:

Updated for new version of SDRS

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/astro/psTime.c

    r1598 r1614  
    1 
    21/** @file  psTime.c
    32 *
     
    76 *  A collection of functions are required by psLib to manipulate time data. These functions primarily consist
    87 *  of conversions between specific time formats.  PSLib currently uses the UNIX timeval time system as the
    9  *  base upon which International Atomic Time (TAI) time is calculated. TAI time varies over time due to the
    10  *  earth's rotation and the movement of the continental plates. It is currentls 32 seconds faster than
    11  *  UTC/timeval time.
     8 *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI
     9 *  time varies over time due to the earth's rotation and the movement of the continental plates. It is
     10 *  currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates
     11 *  is given in the table below, which comes from:
     12 *
     13 *  ftp://maia.usno.navy.mil/ser7/tai-utc.dat
     14 *
     15 *  This table is placed into a static array and used by the psTime functions for conversions.
     16 *
     17 *   1961 JAN  1 =JD 2437300.5  TAI-UTC=   1.4228180 S + (MJD - 37300.) X 0.001296 S
     18 *   1961 AUG  1 =JD 2437512.5  TAI-UTC=   1.3728180 S + (MJD - 37300.) X 0.001296 S
     19 *   1962 JAN  1 =JD 2437665.5  TAI-UTC=   1.8458580 S + (MJD - 37665.) X 0.0011232S
     20 *   1963 NOV  1 =JD 2438334.5  TAI-UTC=   1.9458580 S + (MJD - 37665.) X 0.0011232S
     21 *   1964 JAN  1 =JD 2438395.5  TAI-UTC=   3.2401300 S + (MJD - 38761.) X 0.001296 S
     22 *   1964 APR  1 =JD 2438486.5  TAI-UTC=   3.3401300 S + (MJD - 38761.) X 0.001296 S
     23 *   1964 SEP  1 =JD 2438639.5  TAI-UTC=   3.4401300 S + (MJD - 38761.) X 0.001296 S
     24 *   1965 JAN  1 =JD 2438761.5  TAI-UTC=   3.5401300 S + (MJD - 38761.) X 0.001296 S
     25 *   1965 MAR  1 =JD 2438820.5  TAI-UTC=   3.6401300 S + (MJD - 38761.) X 0.001296 S
     26 *   1965 JUL  1 =JD 2438942.5  TAI-UTC=   3.7401300 S + (MJD - 38761.) X 0.001296 S
     27 *   1965 SEP  1 =JD 2439004.5  TAI-UTC=   3.8401300 S + (MJD - 38761.) X 0.001296 S
     28 *   1966 JAN  1 =JD 2439126.5  TAI-UTC=   4.3131700 S + (MJD - 39126.) X 0.002592 S
     29 *   1968 FEB  1 =JD 2439887.5  TAI-UTC=   4.2131700 S + (MJD - 39126.) X 0.002592 S
     30 *   1972 JAN  1 =JD 2441317.5  TAI-UTC=  10.0       S + (MJD - 41317.) X 0.0      S
     31 *   1972 JUL  1 =JD 2441499.5  TAI-UTC=  11.0       S + (MJD - 41317.) X 0.0      S
     32 *   1973 JAN  1 =JD 2441683.5  TAI-UTC=  12.0       S + (MJD - 41317.) X 0.0      S
     33 *   1974 JAN  1 =JD 2442048.5  TAI-UTC=  13.0       S + (MJD - 41317.) X 0.0      S
     34 *   1975 JAN  1 =JD 2442413.5  TAI-UTC=  14.0       S + (MJD - 41317.) X 0.0      S
     35 *   1976 JAN  1 =JD 2442778.5  TAI-UTC=  15.0       S + (MJD - 41317.) X 0.0      S
     36 *   1977 JAN  1 =JD 2443144.5  TAI-UTC=  16.0       S + (MJD - 41317.) X 0.0      S
     37 *   1978 JAN  1 =JD 2443509.5  TAI-UTC=  17.0       S + (MJD - 41317.) X 0.0      S
     38 *   1979 JAN  1 =JD 2443874.5  TAI-UTC=  18.0       S + (MJD - 41317.) X 0.0      S
     39 *   1980 JAN  1 =JD 2444239.5  TAI-UTC=  19.0       S + (MJD - 41317.) X 0.0      S
     40 *   1981 JUL  1 =JD 2444786.5  TAI-UTC=  20.0       S + (MJD - 41317.) X 0.0      S
     41 *   1982 JUL  1 =JD 2445151.5  TAI-UTC=  21.0       S + (MJD - 41317.) X 0.0      S
     42 *   1983 JUL  1 =JD 2445516.5  TAI-UTC=  22.0       S + (MJD - 41317.) X 0.0      S
     43 *   1985 JUL  1 =JD 2446247.5  TAI-UTC=  23.0       S + (MJD - 41317.) X 0.0      S
     44 *   1988 JAN  1 =JD 2447161.5  TAI-UTC=  24.0       S + (MJD - 41317.) X 0.0      S
     45 *   1990 JAN  1 =JD 2447892.5  TAI-UTC=  25.0       S + (MJD - 41317.) X 0.0      S
     46 *   1991 JAN  1 =JD 2448257.5  TAI-UTC=  26.0       S + (MJD - 41317.) X 0.0      S
     47 *   1992 JUL  1 =JD 2448804.5  TAI-UTC=  27.0       S + (MJD - 41317.) X 0.0      S
     48 *   1993 JUL  1 =JD 2449169.5  TAI-UTC=  28.0       S + (MJD - 41317.) X 0.0      S
     49 *   1994 JUL  1 =JD 2449534.5  TAI-UTC=  29.0       S + (MJD - 41317.) X 0.0      S
     50 *   1996 JAN  1 =JD 2450083.5  TAI-UTC=  30.0       S + (MJD - 41317.) X 0.0      S
     51 *   1997 JUL  1 =JD 2450630.5  TAI-UTC=  31.0       S + (MJD - 41317.) X 0.0      S
     52 *   1999 JAN  1 =JD 2451179.5  TAI-UTC=  32.0       S + (MJD - 41317.) X 0.0      S
    1253 *
    1354 *  @author Ross Harman, MHPCC
    1455 *
    15  *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
    16  *  @date $Date: 2004-08-19 18:57:49 $
     56 *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
     57 *  @date $Date: 2004-08-25 01:37:34 $
    1758 *
    1859 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2667#include "psError.h"
    2768#include "psMemory.h"
    28 
    29 /******************************************************************************/
    30 /*  DEFINE STATEMENTS                                                         */
    31 /******************************************************************************/
    32 /******************************************************************************/
    33 /*  DEFINE STATEMENTS                                                         */
    34 /******************************************************************************/
    35 
    36 // None
    37 
    38 /******************************************************************************/
    39 /*  TYPE DEFINITIONS                                                          */
    40 /******************************************************************************/
    41 
    42 // None
    43 
    44 /*****************************************************************************/
    45 /*  GLOBAL VARIABLES                                                         */
    46 /*****************************************************************************/
    47 
    48 // None
    49 
    50 /*****************************************************************************/
    51 /*  FILE STATIC VARIABLES                                                    */
    52 /*****************************************************************************/
    53 
    54 // None
    55 
    56 /*****************************************************************************/
    57 /*  FUNCTION IMPLEMENTATION - LOCAL                                          */
    58 /*****************************************************************************/
    59 
    60 /******************************************************************************/
    61 /*  DEFINE STATEMENTS                                                         */
    62 /******************************************************************************/
     69#include "psAbort.h"
     70
    6371
    6472/** Number of available leapsecond updates */
    65 #define NUM_LEAPSECOND_UPDATES 23
     73#define NUM_UPDATES 36
    6674
    6775/** Maximum length of time string */
     
    8391#define USEC_PER_DAY 86400000000.0
    8492
    85 /** Preprocessor macro to generate error for negative time in struct */
    86 #define CHECK_NEGATIVE_TIME_STRUCT(NAME,RETURN)                                                              \
    87 if(NAME.tv_sec < 0) {                                                                                        \
    88     psError(__func__,"Negative seconds are not allowed: %ld", NAME.tv_sec);                                  \
     93/** Preprocessor macro to check for null psTime struct */
     94#define CHECK_NULL_TIME(TIME,RETURN)                                                                         \
     95if(TIME == NULL) {                                                                                           \
     96    psError(__func__,"NULL value not allowed");                                                              \
    8997    return RETURN;                                                                                           \
    90 } else if(NAME.tv_usec<0) {                                                                                  \
    91     psError(__func__,"Negative microseconds are not allowed: %ld", NAME.tv_usec);                            \
    92     return RETURN;                                                                                           \
    93 }
    94 
    95 /** Preprocessor macro to generate error for negative time */
    96 #define CHECK_NEGATIVE_TIME(NAME,RETURN)                                                                     \
    97 if(NAME < 0.0) {                                                                                             \
    98     psError(__func__,"Negative time is not allowed: %f", NAME);                                              \
    99     return RETURN;                                                                                           \
    100 }                                                                                                            \
    101 
    102 /* The table below comes from http://tycho.usno.navy.mil/leapsec.html, which reports the current state of
    103 the TAI/UTC leapsecond conversion times. This table is placed into a two dimensional array and used by
    104 the psTimeGetTime() function to calculate TAI time from  UTC time.
    105  
    106 1972 JAN 1 = JD 2441317.5  TAI-UTC = 10.0
    107 1972 JUL 1 = JD 2441499.5  TAI-UTC = 11.0
    108 1973 JAN 1 = JD 2441683.5  TAI-UTC = 12.0
    109 1974 JAN 1 = JD 2442048.5  TAI-UTC = 13.0
    110 1975 JAN 1 = JD 2442413.5  TAI-UTC = 14.0
    111 1976 JAN 1 = JD 2442778.5  TAI-UTC = 15.0
    112 1977 JAN 1 = JD 2443144.5  TAI-UTC = 16.0
    113 1978 JAN 1 = JD 2443509.5  TAI-UTC = 17.0
    114 1979 JAN 1 = JD 2443874.5  TAI-UTC = 18.0
    115 1980 JAN 1 = JD 2444239.5  TAI-UTC = 19.0
    116 1981 JUL 1 = JD 2444786.5  TAI-UTC = 20.0
    117 1982 JUL 1 = JD 2445151.5  TAI-UTC = 21.0
    118 1983 JUL 1 = JD 2445516.5  TAI-UTC = 22.0
    119 1985 JUL 1 = JD 2446247.5  TAI-UTC = 23.0
    120 1988 JAN 1 = JD 2447161.5  TAI-UTC = 24.0
    121 1990 JAN 1 = JD 2447892.5  TAI-UTC = 25.0
    122 1991 JAN 1 = JD 2448257.5  TAI-UTC = 26.0
    123 1992 JUL 1 = JD 2448804.5  TAI-UTC = 27.0
    124 1993 JUL 1 = JD 2449169.5  TAI-UTC = 28.0
    125 1994 JUL 1 = JD 2449534.5  TAI-UTC = 29.0
    126 1996 JAN 1 = JD 2450083.5  TAI-UTC = 30.0
    127 1997 JUL 1 = JD 2450630.5  TAI-UTC = 31.0
    128 1999 JAN 1 = JD 2451179.5  TAI-UTC = 32.0
     98}
     99
     100/** Preprocessor macro to allocate psTime strict */
     101#define ALLOC_TIME(TIME)                                                                                     \
     102TIME = (psTime*)psAlloc(sizeof(psTime));                                                                 \
     103if (TIME == NULL) {                                                                                      \
     104    psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__);                               \
     105}
     106
     107/*
     108 The table below comes from ftp://maia.usno.navy.mil/ser7/tai-utc.dat, which reports the current state of
     109 the TAI/UTC leapsecond conversion times.
    129110*/
    130 static double leapseconds[NUM_LEAPSECOND_UPDATES][2] = {
    131             {2441317.5, 10.0},
    132             {2441499.5, 11.0},
    133             {2441683.5, 12.0},
    134             {2442048.5, 13.0},
    135             {2442413.5, 14.0},
    136             {2442778.5, 15.0},
    137             {2443144.5, 16.0},
    138             {2443509.5, 17.0},
    139             {2443874.5, 18.0},
    140             {2444239.5, 19.0},
    141             {2444786.5, 20.0},
    142             {2445151.5, 21.0},
    143             {2445516.5, 22.0},
    144             {2446247.5, 23.0},
    145             {2447161.5, 24.0},
    146             {2447892.5, 25.0},
    147             {2448257.5, 26.0},
    148             {2448804.5, 27.0},
    149             {2449169.5, 28.0},
    150             {2449534.5, 29.0},
    151             {2450083.5, 30.0},
    152             {2450630.5, 31.0},
    153             {2451179.5, 32.0}
    154         };
    155 
    156 psTime psTimeGetTime(void)
     111static double lsTable[NUM_UPDATES][4] = {
     112                                            {2437300.5,  1.422818, 37300.0, 0.0012960},
     113                                            {2437512.5,  1.372818, 37300.0, 0.0012960},
     114                                            {2437665.5,  1.845858, 37665.0, 0.0011232},
     115                                            {2438334.5,  1.945858, 37665.0, 0.0011232},
     116                                            {2438395.5,  3.240130, 38761.0, 0.0012960},
     117                                            {2438486.5,  3.340130, 38761.0, 0.0012960},
     118                                            {2438639.5,  3.440130, 38761.0, 0.0012960},
     119                                            {2438761.5,  3.540130, 38761.0, 0.0012960},
     120                                            {2438820.5,  3.640130, 38761.0, 0.0012960},
     121                                            {2438942.5,  3.740130, 38761.0, 0.0012960},
     122                                            {2439004.5,  3.840130, 38761.0, 0.0012960},
     123                                            {2439126.5,  4.313170, 39126.0, 0.0025920},
     124                                            {2439887.5,  4.213170, 39126.0, 0.0025920},
     125                                            {2441317.5, 10.000000, 41317.0, 0.0000000},
     126                                            {2441499.5, 11.000000, 41317.0, 0.0000000},
     127                                            {2441683.5, 12.000000, 41317.0, 0.0000000},
     128                                            {2442048.5, 13.000000, 41317.0, 0.0000000},
     129                                            {2442413.5, 14.000000, 41317.0, 0.0000000},
     130                                            {2442778.5, 15.000000, 41317.0, 0.0000000},
     131                                            {2443144.5, 16.000000, 41317.0, 0.0000000},
     132                                            {2443509.5, 17.000000, 41317.0, 0.0000000},
     133                                            {2443874.5, 18.000000, 41317.0, 0.0000000},
     134                                            {2444239.5, 19.000000, 41317.0, 0.0000000},
     135                                            {2444786.5, 20.000000, 41317.0, 0.0000000},
     136                                            {2445151.5, 21.000000, 41317.0, 0.0000000},
     137                                            {2445516.5, 22.000000, 41317.0, 0.0000000},
     138                                            {2446247.5, 23.000000, 41317.0, 0.0000000},
     139                                            {2447161.5, 24.000000, 41317.0, 0.0000000},
     140                                            {2447892.5, 25.000000, 41317.0, 0.0000000},
     141                                            {2448257.5, 26.000000, 41317.0, 0.0000000},
     142                                            {2448804.5, 27.000000, 41317.0, 0.0000000},
     143                                            {2449169.5, 28.000000, 41317.0, 0.0000000},
     144                                            {2449534.5, 29.000000, 41317.0, 0.0000000},
     145                                            {2450083.5, 30.000000, 41317.0, 0.0000000},
     146                                            {2450630.5, 31.000000, 41317.0, 0.0000000},
     147                                            {2451179.5, 32.000000, 41317.0, 0.0000000}
     148                                        };
     149
     150
     151psTime* psTimeGetTime(psTimeType type)
    157152{
    158153    struct timeval now;
    159     psTime time;
    160 
    161     time.tv_sec = 0;
    162     time.tv_usec = 0;
     154    psTime *time = NULL;
     155
     156    // Allocate psTime struct
     157    ALLOC_TIME(time);
    163158
    164159    if (gettimeofday(&now, (struct timezone *)0) == -1) {
    165160        psError(__func__, " : Line %d - Failed to get time", __LINE__);
    166         return time;
    167     }
     161        return NULL;
     162    }
     163
    168164    // Convert timeval time to psTime
    169     time.tv_sec = now.tv_sec;
    170     time.tv_usec = now.tv_usec;
    171 
    172     // Add most current leapseconds value to UTC time to get TAI time
    173     time.tv_sec += leapseconds[NUM_LEAPSECOND_UPDATES - 1][1];
     165    time->sec = now.tv_sec;
     166    time->usec = now.tv_usec;
     167    time->type = type;
     168
     169    // Add most leapseconds to UTC time to get TAI time if necessary
     170    if(type == PS_TIME_TAI) {
     171        time->sec += psGetTAIDelta(time);
     172    }
    174173
    175174    return time;
    176175}
    177176
    178 char *psTimeToISO(psTime time)
     177psTime* psTimeConvert(psTime *time, psTimeType type)
     178{
     179    double delta = 0.0;
     180
     181    if(time->type == type) {
     182        psError(__func__, " : Line %d - Time is already in the correct psTime format. Time type: %d", __LINE__, type);
     183        return NULL;
     184    }
     185
     186    delta = psGetTAIDelta(time);
     187
     188    if(type == PS_TIME_UTC) {
     189        time->sec = time->sec - delta;    // User wants UTC time. Remove leapseconds.
     190    } else if(type == PS_TIME_TAI) {
     191        time->sec = time->sec + delta;    // User wants TAI time. Add leapseconds.
     192    } else {
     193        psError(__func__, " : Line %d - Invalid psTimeType: %d", __LINE__, type);
     194    }
     195
     196    return time;
     197}
     198
     199double psTimeToLST(psTime *time, double longitude)
     200{
     201    double delta = 0;
     202
     203    return delta;
     204}
     205
     206psTime* psLSTToTime(double time, double longitude)
     207{
     208    psTime *outTime = NULL;
     209
     210    return outTime;
     211}
     212
     213double psGetUT1Delta(psTime *time)
     214{
     215    double delta = 0;
     216
     217    return delta;
     218}
     219
     220double psGetTAIDelta(psTime *time)
     221{
     222    int i = 0;
     223    double delta = 0.0;
     224    double jd = 0.0;
     225    double mjd = 0.0;
     226
     227    // Determine Julian and modified Julian dates used in table lookup and time delta calculation
     228    jd = psTimeToJD(time);
     229    mjd = psTimeToMJD(time);
     230
     231    // Perform table lookup
     232    if(jd < lsTable[0][1]) {                        // Times earlier than 1961
     233        delta = 0.0;
     234    } else if(jd > lsTable[NUM_UPDATES-1][1]) {      // Times greater than latest table entry
     235        delta = lsTable[NUM_UPDATES-1][1] + (mjd - lsTable[NUM_UPDATES-1][2]) * lsTable[NUM_UPDATES-1][3];
     236    } else {                                        // All other times
     237        for (i = 0; i<NUM_UPDATES-1; i++) {
     238            if (jd>lsTable[i][0] && jd<lsTable[i+1][0]) {
     239                delta = lsTable[i][1] + (mjd - lsTable[i][2]) * lsTable[i][3];
     240            }
     241        }
     242    }
     243
     244    return delta;
     245}
     246
     247double psTimeToJD(psTime *time)
     248{
     249    double jd = 0.0;
     250
     251    // NULL error check
     252    CHECK_NULL_TIME(time,0.0);
     253
     254    // Julian date conversion courtesy of Eugene Magnier
     255    if(time->sec < 0) {
     256        jd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 2440587.5; // psTime earlier than epoch
     257    } else {
     258        jd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 2440587.5; // psTime greater than epoch
     259    }
     260
     261    return jd;
     262}
     263
     264double psTimeToMJD(psTime *time)
     265{
     266    double mjd = 0.0;
     267
     268    // NULL error check
     269    CHECK_NULL_TIME(time,0.0);
     270
     271    // Modified Julian date conversion courtesy of Eugene Magnier
     272    if(time->sec < 0) {
     273        mjd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 40587.0; // psTime earlier than epoch
     274    } else {
     275        mjd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 40587.0; // psTime greater than epoch
     276    }
     277
     278    return mjd;
     279}
     280
     281char* psTimeToISO(psTime *time)
    179282{
    180283    int ms = 0;
     
    184287    time_t sec;
    185288
    186     CHECK_NEGATIVE_TIME_STRUCT(time, NULL);
     289    // NULL error check
     290    CHECK_NULL_TIME(time,NULL);
    187291
    188292    tempString = psAlloc(MAX_TIME_STRING_LENGTH);
    189293    timeString = psAlloc(MAX_TIME_STRING_LENGTH);
    190294
    191     // Converts psTime to YYYY/MM/DD,HH:MM:SS.SSS in string form
    192     ms = time.tv_usec / 1000;
    193 
    194     sec = time.tv_sec;
     295    ms = time->usec / 1000;
     296    sec = time->sec;
     297
    195298    // tmTime variable is statically allocated, no need to free
    196299    tmTime = gmtime(&sec);
    197     if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y/%m/%d,%H:%M:%S", tmTime)) {
     300
     301    // Converts psTime to YYYY-MM-DDThh:mm:ss.sss in string form
     302    if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) {
    198303        psError(__func__, " : Line %d - Failed strftime conversion", __LINE__);
    199304    }
    200305
    201     if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3d", tempString, ms) < 0) {
     306    if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) {
    202307        psError(__func__, " : Line %d - Failed snprintf conversion", __LINE__);
    203308    }
     
    207312}
    208313
    209 psTime psTimeToUTC(psTime time)
    210 {
    211     int i = 0;
    212     double jd = 0.0;
    213     double ls = 0.0;
    214     double *jdTable = NULL;
    215     psTime outTime;
    216 
    217     CHECK_NEGATIVE_TIME_STRUCT(time, outTime);
    218 
    219     // Find leapseconds to subtract from psTime to get UTC time
    220     jd = psTimeToJD(time);
    221     jdTable = leapseconds[0];
    222     for (i = 0; i < NUM_LEAPSECOND_UPDATES; i++, jdTable += 2) {
    223         if (jd > *jdTable) {
    224             ls = *(jdTable + 1);
    225         }
    226     }
    227 
    228     outTime.tv_sec = time.tv_sec - ls;
    229     outTime.tv_usec = time.tv_usec;
    230 
    231     CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime);
    232 
    233     return outTime;
    234 }
    235 
    236 double psTimeToMJD(psTime time)
    237 {
    238     double mjd = 0.0;
    239 
    240     CHECK_NEGATIVE_TIME_STRUCT(time, mjd);
    241 
    242     // Modified Julian date conversion courtesy of Eugene Magnier
    243     mjd = time.tv_sec / SEC_PER_DAY + time.tv_usec / USEC_PER_DAY + 40587.0;
    244 
    245     return mjd;
    246 }
    247 
    248 double psTimeToJD(psTime time)
    249 {
    250     double jd = 0.0;
    251 
    252     CHECK_NEGATIVE_TIME_STRUCT(time, jd);
    253 
    254     // Julian date conversion courtesy of Eugene Magnier
    255     jd = time.tv_sec / SEC_PER_DAY + time.tv_usec / USEC_PER_DAY + 2440587.5;
    256 
    257     return jd;
    258 }
    259 
    260 struct timeval psTimeToTimeval(psTime time)
     314struct timeval psTimeToTimeval(psTime *time)
    261315{
    262316    struct timeval timevalTime;
    263317
    264     CHECK_NEGATIVE_TIME_STRUCT(time, timevalTime);
    265     timevalTime.tv_sec = time.tv_sec;
    266     timevalTime.tv_usec = time.tv_usec;
     318    // NULL error check
     319    CHECK_NULL_TIME(time,timevalTime);
     320
     321    timevalTime.tv_sec = time->sec;
     322    timevalTime.tv_usec = time->usec;
    267323
    268324    return timevalTime;
    269325}
    270326
    271 struct tm *psTimeToTM(psTime time)
     327struct tm* psTimeToTM(psTime *time)
    272328{
    273329    struct tm *tmTime = NULL;
    274330    time_t sec;
    275331
    276     CHECK_NEGATIVE_TIME_STRUCT(time, tmTime);
    277     sec = time.tv_sec;
     332    sec = time->sec;
    278333    tmTime = gmtime(&sec);
    279334
     
    281336}
    282337
    283 psTime psISOToTime(char *time)
     338psTime* psJDToTime(double time)
     339{
     340    double days = 0.0;
     341    double seconds = 0.0;
     342    psTime *outTime = NULL;
     343
     344    // Allocate psTime struct
     345    ALLOC_TIME(outTime);
     346
     347    // Julian date conversion courtesy of Eugene Magnier
     348    days = time - 2440587.5;
     349    seconds = days * SEC_PER_DAY;
     350    if(seconds < 0.0) {
     351        outTime->usec = (seconds - (long)seconds) * -1000000.0;  // psTime earlier than epoch
     352    } else {
     353        outTime->usec = (seconds - (long)seconds) * 1000000.0;   // psTime greater than epoch
     354    }
     355    outTime->sec = seconds;
     356
     357    return outTime;
     358}
     359
     360psTime* psMJDToTime(double time)
     361{
     362    double days = 0.0;
     363    double seconds = 0.0;
     364    psTime *outTime = NULL;
     365
     366    // Allocate psTime struct
     367    ALLOC_TIME(outTime);
     368
     369    // Modified Julian date conversion courtesy of Eugene Magnier
     370    days = time - 40587.0;
     371    seconds = days * SEC_PER_DAY;
     372    if(seconds < 0.0) {
     373        outTime->usec = (seconds - (long)seconds) * -1000000.0;  // psTime earlier than epoch
     374    } else {
     375        outTime->usec = (seconds - (long)seconds) * 1000000.0;   // psTime greater than epoch
     376    }
     377    outTime->sec = seconds;
     378
     379    return outTime;
     380}
     381
     382psTime* psISOToTime(char *time)
    284383{
    285384    char tempString[MAX_TIME_STRING_LENGTH];
     
    292391    int millisecond;
    293392    struct tm tmTime;
    294     psTime outTime;
    295 
     393    psTime *outTime = NULL;
     394
     395    // Preserve input string by creating duplicate
    296396    strncpy(tempString, time, MAX_TIME_STRING_LENGTH);
    297397
    298     // Convert YYYY/MM/DD,HH:MM:SS.SSS in string form to tm time
    299     year = atoi(strtok(tempString, "/"));
    300     if (year < 1900) {
    301         psError(__func__, "Years less than 1900 not allowed. Value: %d", year);
    302         return outTime;
    303     }
    304 
    305     month = atoi(strtok(NULL, "/"));
     398    // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time
     399    year = atoi(strtok(tempString, "-"));
     400    if (year < 0) {
     401        psError(__func__, "Years less than 0 not allowed. Value: %d", year);
     402        return outTime;
     403    }
     404
     405    month = atoi(strtok(NULL, "-"));
    306406    if (month < 1 || month > 12) {
    307407        psError(__func__, "Month must have a value from 1 to 12. Value: %d", month);
     
    309409    }
    310410
    311     day = atoi(strtok(NULL, ","));
     411    day = atoi(strtok(NULL, "T"));
    312412    if (day < 1 || day > 31) {
    313413        psError(__func__, "Day must have a value from 1 to 31. Value: %d", day);
     
    333433    }
    334434
    335     millisecond = atoi(strtok(NULL, "X"));
     435    millisecond = atoi(strtok(NULL, "Z"));
    336436    if (millisecond < 0 || millisecond > 1000) {
    337437        psError(__func__, "Millisecond must have a value from 0 to 999. Value: %d", millisecond);
     
    347447    tmTime.tm_isdst = -1;
    348448
     449    // Allocate psTime struct
     450    ALLOC_TIME(outTime)
     451
    349452    // Convert tm time to psTime
    350453    outTime = psTMToTime(&tmTime);
    351     outTime.tv_usec = millisecond * 1000;
    352 
    353     return outTime;
    354 }
    355 
    356 psTime psUTCToTime(psTime time)
    357 {
    358     psTime outTime;
    359 
    360     CHECK_NEGATIVE_TIME_STRUCT(time, outTime);
    361 
    362     // Convert UTC time to psTime/TAI
    363     outTime.tv_sec = time.tv_sec + leapseconds[NUM_LEAPSECOND_UPDATES - 1][1];
    364     outTime.tv_usec = time.tv_usec;
    365     CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime);
    366 
    367     return outTime;
    368 }
    369 
    370 psTime psMJDToTime(double time)
    371 {
    372     psTime outTime;
    373     double days = 0.0;
    374     double seconds = 0.0;
    375 
    376     CHECK_NEGATIVE_TIME(time, outTime);
    377 
    378     // Modified Julian date conversion courtesy of Eugene Magnier
    379     days = time - 40587.0;
    380 
    381     // Convert to psTime/TAI
    382     seconds = days * SEC_PER_DAY;
    383     outTime.tv_usec = (seconds - (long)seconds) * 1000000.0;
    384     outTime.tv_sec = seconds;
    385 
    386     CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime);
    387 
    388     return outTime;
    389 }
    390 
    391 psTime psJDToTime(double time)
    392 {
    393     double days = 0.0;
    394     double seconds = 0.0;
    395     psTime outTime;
    396 
    397     CHECK_NEGATIVE_TIME(time, outTime);
    398 
    399     // Julian date conversion courtesy of Eugene Magnier
    400     days = time - 2440587.5;
    401 
    402     // Convert to psTime/TAI
    403     seconds = days * SEC_PER_DAY;
    404     outTime.tv_sec = seconds;
    405     outTime.tv_usec = (seconds - (long)seconds) * 1000000.0;
    406 
    407     CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime);
    408 
    409     return outTime;
    410 }
    411 
    412 psTime psTimevalToTime(struct timeval * time)
    413 {
    414     psTime outTime;
    415 
    416     if (time == NULL)
    417     {
    418         psError(__func__, "Null value for timeval arg not allowed");
    419         return outTime;
    420     } else if (time->tv_sec < 0)
    421     {
    422         psError(__func__, "Negative seconds are not allowed: %ld", time->tv_sec);
    423         return outTime;
    424     } else if (time->tv_usec < 0)
    425     {
    426         psError(__func__, "Negative microseconds are not allowed: %ld", time->tv_usec);
    427         return outTime;
    428     }
    429     // Convert to psTime/TAI
    430     outTime.tv_sec = time->tv_sec;
    431     outTime.tv_usec = time->tv_usec;
    432 
    433     CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime);
    434 
    435     return outTime;
    436 }
    437 
    438 psTime psTMToTime(struct tm * time)
    439 {
    440     int i;
    441     int n;
    442     int y;
    443     int mon[] = {
    444                     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    445                 };
    446     long epoch;
    447     psTime outTime;
    448 
    449     i = 0;
    450     n = 0;
    451     y = 0;
    452     epoch = 0;
    453 
    454     if (time == NULL)
    455     {
    456         psError(__func__, "Null value for tm arg not allowed");
    457         return outTime;
    458     } else if (time->tm_year < 70)
    459     {
    460         psError(__func__, "Input times earlier than 1970 not allowed. Value: %d", time->tm_year + 1900);
    461         return outTime;
    462     } else if (time->tm_mon < 0 || time->tm_mon > 11)
    463     {
    464         psError(__func__, "Month must have a value from 0 to 11. Value: %d", time->tm_mon);
    465         return outTime;
    466     } else if (time->tm_mday < 1 || time->tm_mday > 31)
    467     {
    468         psError(__func__, "Day must have a value from 1 to 31. Value: %d", time->tm_mday);
    469         return outTime;
    470     } else if (time->tm_hour < 0 || time->tm_hour > 23)
    471     {
    472         psError(__func__, "Hour must have a value from 0 to 23. Value: %d", time->tm_hour);
    473         return outTime;
    474     } else if (time->tm_min < 0 || time->tm_min > 59)
    475     {
    476         psError(__func__, "Minute must have a value from 0 to 59. Value: %d", time->tm_min);
    477         return outTime;
    478     } else if (time->tm_sec < 0 || time->tm_sec > 59)
    479     {
    480         psError(__func__, "Second must have a value from 0 to 59. Value: %d", time->tm_sec);
    481         return outTime;
    482     }
    483 
    484     n = time->tm_year + 1900 - 1;
    485     epoch = (time->tm_year - 70) * SEC_PER_YEAR + ((n / 4 - n / 100 + n / 400) -
    486             (1969 / 4 - 1969 / 100 + 1969 / 400)) * SEC_PER_DAY;
    487 
    488     y = time->tm_year + 1900;
    489 
    490     // Adjust for leap years
    491     for (i = 0; i < time->tm_mon; i++)
    492     {
    493         epoch += mon[i] * SEC_PER_DAY;
    494         if (i == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) {
    495             epoch += SEC_PER_DAY;
    496         }
    497     }
    498 
    499     // Add everything
    500     epoch += (time->tm_mday - 1) * SEC_PER_DAY;
    501     epoch += time->tm_hour * SEC_PER_HOUR + time->tm_min * SEC_PER_MINUTE + time->tm_sec;
    502 
    503     // Create psTime
    504     outTime.tv_usec = 0;
    505     outTime.tv_sec = epoch;
    506 
    507     CHECK_NEGATIVE_TIME_STRUCT(outTime, outTime);
    508 
    509     return outTime;
    510 }
     454    outTime->usec = millisecond * 1000;
     455
     456    return outTime;
     457}
     458
     459psTime* psTimevalToTime(struct timeval *time)
     460{
     461    psTime *outTime = NULL;
     462
     463    // NULL error check
     464    CHECK_NULL_TIME(time,NULL);
     465
     466    // Allocate psTime struct
     467    ALLOC_TIME(outTime);
     468
     469    // Convert to psTime
     470    outTime->sec = time->tv_sec;
     471    outTime->usec = time->tv_usec;
     472
     473    return outTime;
     474}
     475
     476psTime* psTMToTime(struct tm* time)
     477{
     478    time_t localTimeInSeconds = 0;
     479    time_t temp = 0;
     480    struct tm *localTMTime = NULL;
     481    psTime *outTime = NULL;
     482
     483    // NULL error check
     484    CHECK_NULL_TIME(time,NULL);
     485
     486    // Allocate psTime struct
     487    ALLOC_TIME(outTime);
     488
     489    // The mktime function returns seconds since last epoch in local time, so get local time and offset
     490    localTimeInSeconds = mktime(time);
     491    localTMTime = localtime(&temp);
     492
     493    // Convert to psTime
     494    outTime->usec = 0;
     495    outTime->sec = localTMTime->tm_gmtoff + localTimeInSeconds;
     496
     497    return outTime;
     498}
     499
     500psTime* psTAIAdd(psTime *tai1, psTime *tai2)
     501{
     502    psTime *outTime = NULL;
     503
     504    if(tai1->type != PS_TIME_TAI) {
     505        psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type);
     506        return NULL;
     507    }
     508
     509    if(tai2->type != PS_TIME_TAI) {
     510        psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type);
     511        return NULL;
     512    }
     513
     514    ALLOC_TIME(outTime);
     515
     516    outTime->sec = tai1->sec + tai2->sec;
     517    outTime->usec = tai1->usec + tai2->usec;
     518
     519    // Increment seconds in case of microsecond overflow after addition
     520    if(outTime->usec<tai1->usec || outTime->usec<tai2->usec) {
     521        outTime->sec++;
     522    }
     523
     524    return outTime;
     525}
     526
     527psTime* psTAISub(psTime *tai1, psTime *tai2)
     528{
     529    psTime *outTime = NULL;
     530
     531    if(tai1->type != PS_TIME_TAI) {
     532        psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type);
     533        return NULL;
     534    }
     535
     536    if(tai2->type != PS_TIME_TAI) {
     537        psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type);
     538        return NULL;
     539    }
     540
     541    ALLOC_TIME(outTime);
     542
     543    outTime->sec = tai1->sec - tai2->sec;
     544    outTime->usec = tai1->usec - tai2->usec;
     545
     546    // Decrement seconds in case of microsecond underflow after subtraction
     547    if(outTime->usec>tai1->usec || outTime->usec>tai2->usec) {
     548        outTime->sec--;
     549    }
     550
     551    return outTime;
     552}
     553
     554psTime* psTAIDelta(psTime *tai1, psTime *tai2)
     555{
     556    psTime *outTime = NULL;
     557
     558    if(tai1->type != PS_TIME_TAI) {
     559        psError(__func__, " : Line %d - First argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai1->type);
     560        return NULL;
     561    }
     562
     563    if(tai2->type != PS_TIME_TAI) {
     564        psError(__func__, " : Line %d - Second argument is not PS_TIME_TAI type. Type: %d", __LINE__, tai2->type);
     565        return NULL;
     566    }
     567
     568    ALLOC_TIME(outTime);
     569
     570    outTime->sec = tai1->sec - tai2->sec;
     571    outTime->usec = tai1->usec - tai2->usec;
     572
     573    // Decrement seconds in case of microsecond underflow after subtraction
     574    if(outTime->usec>tai1->usec || outTime->usec>tai2->usec) {
     575        outTime->sec--;
     576    }
     577
     578    outTime->sec = abs(outTime->sec);
     579
     580
     581    return outTime;
     582}
Note: See TracChangeset for help on using the changeset viewer.