/* =================================================================== * Name : DD_time.c * Version: : 3.2 * Author : Andrey Fedorov * Institution : IKI RAN, Moscow , CESR, Toulouse * Written on : Tue Feb 21 14:27:10 EET 1995 * Modified on : Oct 5, 2002 * List of modifications: * Oct 5, 2002: V.3.0, New functions DD_Time2Double and Double2DD_Time * were added. * March 26, 2010: V.3.1 YEARS up to 2025 * Sept 05, 2011: V.3.2 SetIntNew => arg TimeKind => to work with 1970-1973 : BR *==================================================================*/ #include "DD_time.hh" #include #include #include #define YEARS 70 /*---- Static array of days shift from Jun-1-1970 -------*/ /* 1970 1971 1972 1973 1974 1975 1976 * 1977 1978 1979 1980 1981 1982 1983 * 1984 1985 1986 1987 1988 1989 1990 * 1991 1992 1993 1994 1995 1996 1997 * 1998 1999 2000 2001 2002 2003 2004 * 2005 2006 2007 2008 2009 2010 2011 * 2012 2013 2014 2015 2016 2017 2018 * 2019 2020 2021 2022 2023 2024 2025 * 2026 2027 2028 2029 2030 2031 2032 * 2033 2034 2035 2036 2037 2038 2039 */ static double YearDays[YEARS] = { 0.0, 365.0, 730.0, 1096.0, 1461.0, 1826.0, 2191.0, 2557.0, 2922.0, 3287.0, 3652.0, 4018.0, 4383.0, 4748.0, 5113.0, 5479.0, 5844.0, 6209.0, 6574.0, 6940.0, 7305.0, 7670.0, 8035.0, 8401.0, 8766.0, 9131.0, 9496.0, 9862.0, 10227.0, 10592.0, 10957.0, 11323.0, 11688.0, 12053.0, 12418.0, 12784.0, 13149.0, 13514.0, 13879.0, 14245.0, 14610.0, 14975.0, 15340.0, 15706.0, 16071.0, 16436.0, 16801.0, 17167.0, 17532.0, 17897.0, 18262.0, 18628.0, 18993.0, 19358.0, 19723.0, 20089.0, 20454.0, 20819.0, 21184.0, 21550.0, 21915.0, 22280.0, 22645.0, 23011.0, 23376.0, 23741.0, 24106.0, 24472.0, 24837.0, 25202}; static int monthday[2][12] = { {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} }; /* so, DAY = monthday[*][month-1]+day -1 */ /*================== INTERNAL FUNCTION ====================*/ /*-------------------- SetInt ----------------------------*/ void SetInt(dd_tmstr_t *UT) { SetIntNew(UT,DD_TM_UNKNOWN); } void SetIntNew(dd_tmstr_t *UT,t_DDTimeKind timeKind) /* Fill int values of dd_tmstr_t */ /* If the double times field of UT structure is defined, * this function fills remains fields of Year, day .... separately */ { static const double msofday = 24.0*60.0*60.0; static const double msofhour = 60.0*60.0; static const double msofmin = 60.0; long daynumber; double msrest; int i; daynumber = (long)(UT->times / msofday); for(i=0;iyear = i+1970; UT->day = (int)(daynumber - (long)YearDays[i]); break; } case DD_TM_TIME_INTERVAL : { //it's a time interval UT->year = 0; UT->day = (int)(daynumber); break; } default : //compatibility mode if(i > 3) { UT->year = i+1970; UT->day = (int)(daynumber - (long)YearDays[i]); } else { UT->year = 0; UT->day = (int)(daynumber); } break; } msrest = UT->times - (double)daynumber * msofday; UT->hour = (int)(msrest / msofhour); msrest -= (double)(UT->hour)*msofhour; UT->min = (int)(msrest / msofmin); msrest -= (double)(UT->min)*msofmin; UT->sec = (int)(msrest); UT->msec = (int)((msrest - (double)(UT->sec))*1000.0); return; } /*---------------- end of SetInt -----------------------*/ /*-----------------SetDouble ---------------------------*/ void SetDouble(dd_tmstr_t *UT) /* Fill double value of dd_tmstr_t */ /* If indeger fields of UT is defined, You can calculate double * field - amount of sec after Jun-1-1970 */ { if(UT->year >= 1970) UT->times = (double)UT->msec/1000.0 + (double)UT->sec + (double)UT->min*60 + (double)UT->hour*60.0*60.0 + (double)UT->day*60.0*60.0*24.0 + YearDays[(UT->year - 1970)]*60.0*60.0*24.0; else if(UT->year < YEARS) UT->times = (double)UT->msec/1000.0 + (double)UT->sec + (double)UT->min*60 + (double)UT->hour*60.0*60.0 + (double)UT->day*60.0*60.0*24.0 + YearDays[UT->year]*60.0*60.0*24.0; else UT->times = 0.0; return; } /*----------------- end of SetDouble ---------------------*/ /*=================== PUBLIC FUNCTIONS ==================*/ /*------------------- DD_Time2Double --------------------*/ double DD_Time2Double(const dd_time_t UTstring) { dd_tmstr_t UT; char year[5] = "0000"; char day[4] = "000"; char hour[3]= "00"; char min[3] = "00"; char sec[3]= "00"; char msec[4] = "000"; strncpy(year,UTstring,4); strncpy(day,UTstring+4,3); strncpy(hour,UTstring+7,2); strncpy(min,UTstring+9,2); strncpy(sec,UTstring+11,2); strncpy(msec,UTstring+13,3); sscanf(year,"%4d",&(UT.year)); sscanf(day,"%3d",&(UT.day)); sscanf(min,"%2d",&(UT.min)); sscanf(hour,"%2d",&(UT.hour)); sscanf(sec,"%2d",&(UT.sec)); sscanf(msec,"%3d",&(UT.msec)); SetDouble(&UT); return UT.times; } /*------------------------------------------------------*/ /*------------------- Double2DD_Time ---------------------*/ void Double2DD_Time(char * buffer, double Time) { dd_time_t UTstring; dd_tmstr_t UT; UT.times = Time; SetIntNew(&UT,DD_TM_DATE); // sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT.year),(UT.day),(UT.hour), (UT.min), (UT.sec),(UT.msec)); strncpy(buffer, &(UTstring[0]), TIMELENGTH); } /*------------------------------------------------------------*/ /*================== BACKUP COMPABILITY FUNCTIONS =================*/ /*---------------------ReadTime --------------------------*/ /* The fiunction ReadTime read standard for DD time string * and convert it into dd_tmstr_t structure. * see DD-time.h * Return pointer to static internal structure or NULL in case * of error. */ void ReadTime(dd_tmstr_t &UT,char *UTstring) { char year[5] = "0000"; char day[4] = "000"; char hour[3]= "00"; char min[3] = "00"; char sec[3]= "00"; char msec[4] = "000"; strncpy(year,UTstring,4); strncpy(day,UTstring+4,3); strncpy(hour,UTstring+7,2); strncpy(min,UTstring+9,2); strncpy(sec,UTstring+11,2); strncpy(msec,UTstring+13,3); sscanf(year,"%4d",&(UT.year)); sscanf(day,"%2d",&(UT.day)); sscanf(min,"%2d",&(UT.min)); sscanf(hour,"%2d",&(UT.hour)); sscanf(sec,"%2d",&(UT.sec)); sscanf(msec,"%3d",&(UT.msec)); SetDouble(&UT); } /*-------------------- end of ReadTime ------------------------*/ /*---------------------- Write Time ---------------------------*/ /* Function Write time convert use only double times field * of dd_tmstr_t structure to print time in DD style * in internal static string. The integer fields redefined. * Function return string pointer. */ char *WriteTime(dd_tmstr_t *UT) { static dd_time_t UTstring; SetIntNew(UT,DD_TM_DATE); sprintf(UTstring,"%04d%03d%02d%02d%02d%03d",(UT->year),(UT->day),(UT->hour), (UT->min), (UT->sec),(UT->msec)); return(UTstring); } /*------------------- end of WriteTime -------------------*/ void WriteFmtTime(dd_tmstr_t *UT,char *UTstring) { SetIntNew(UT,DD_TM_DATE); sprintf(UTstring,"%04d:%03d:%02d:%02d:%02d",(UT->year),(UT->day),(UT->hour), (UT->min), (UT->sec)); } /*=================== Functions for INTERBALL DECODERS ==============*/ /*---------------------- UT 2 DOUBLE ---------------------*/ dd_tmstr_t *UT2double(unsigned *ut) /* Fill the standard structure with double too using as * argument 7 int length array in Gavrilova Passport Standard */ { static dd_tmstr_t UT; int visocos; if(ut[0]%4 == 0) visocos = 1; else visocos = 0; UT.year = ut[0]; UT.day = monthday[visocos][ut[1] - 1]+ut[2] - 1; UT.hour = ut[3]; UT.min = ut[4]; UT.sec = ut[5]; UT.msec = ut[6]; SetDouble(&UT); return(&UT); } /*-------------------------------------------------------*/ /*---------------- DOUBLE 2 UT --------------------------*/ /* * Converts Standard DD double time to Gavrilova UT array */ unsigned *Double2UT(double t) { static unsigned UT[7]; dd_tmstr_t tm; int i,visocos; tm.times = t; SetIntNew(&tm,DD_TM_DATE); if(tm.year % 4 == 0) visocos = 1; else visocos = 0; i = 0; while((i < 12) && (tm.day >= monthday[visocos][i])) i++; UT[0] = tm.year; UT[1] = i; UT[2] = tm.day +1 - monthday[visocos][i-1]; UT[3] = tm.hour; UT[4] = tm.min; UT[5] = tm.sec; UT[6] = tm.msec; return( (unsigned *)UT); } /*=======================================================================*/