/* @(#)trtime.c 17.1.1.1 (ES0-DMD) 01/25/02 17:47:39 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++ .TYPE Module .IDENTIFICATION trtime.c .LANGUAGE C .AUTHOR Francois Ochsenbein [ESO-IPG] .CATEGORY Time expression .COMMENTS Times may be expressed in three forms: \begin{TeX} \begin{itemize} \item integer (mnemonic {\tt i}): the number of seconds elapsed since Jan 1, 1970, at 00:00:00. The available period is roughly 1902-2037. \item double (mnemonic {\tt jd}): the Julian Date \item structure (mnemonic {\tt tm}): a structure containing, as integers: \begin{itemize} \item {\tt year} number \item {\tt mon} the month number in range [0-11] \item {\tt mday} the day number within month, in range [1-31] \item {\tt yday} the day number within year, in range [0-355] \item {\tt wday} the day number within week, in range [0-6] (0 is Sunday) \item {\tt hour} in range [0-23] \item {\tt min} in range [0-59] \item {\tt sec} in range [0-59] \end{itemize} \end{itemize} This routine does only include transformations between structure tm and integer. \end{TeX} .VERSION 1.0 04-Mar-1987: Creation .VERSION 1.1 21-Oct-1988: Cosmetic modifications .VERSION 1.2 14-Mar-1989: Removed bug in tr_tmi .VERSION 1.3 13-Jul-1989: Corrected bug in tr_tmi (returned status) Also checked if day is correct. --------------------------*/ #include #include #include #define DEBUG 0 #define FINISH goto FIN #define RETURN FIN: return (trerror->errno ? -1 : 0) MID_EXTERN struct trerr_s *trerror; MID_STATIC unsigned char month[12]={31,28,31,30,31,30,31,31,30,31,30,31}; /*========================================================================*/ int tr_itm(t, T) /*+++ .PURPOSE Transform integer time to structure .RETURNS 0 .REMARKS ---*/ long int t; /* IN: Time in seconds since Jan 1, 1970 */ struct tm *T; /* OUT: Time in the structure */ { long int days, year; #if DEBUG printf("Input time is %ld sec\n", t); #endif days = t/86400L; if (t < 0) days--; t -= (days*86400L); #if DEBUG printf("Time of day is %ld sec\n", t); #endif T->tm_hour = t/3600; T->tm_min = 0; T->tm_sec = (t%3600); #if DEBUG printf("Days since 1970: %ld\n", days); printf("Time %dh %dmn %ds\n", T->tm_hour, T->tm_min, T->tm_sec); #endif days += (70L*365L + 18L); /* Offset 1900 */ year = (4L*days)/1461L; T->tm_year = year; T->tm_mon = 0; T->tm_mday = 0; T->tm_yday = days - 365L*year - (year+3)/4; T->tm_year+= 1900; tr_tm(T); return(0); } /*========================================================================*/ int tr_tmi(T, t) /*+++ .PURPOSE Transform structure time to time in seconds from Jan 1, 1970 .RETURNS 0 / -1 (time not in limits 1902-2037). Error message logged, .REMARKS ---*/ struct tm *T; /* IN: Time as a structure */ long int *t; /* OUT: Time in seconds */ { register long int n, y; trerror->errno = 0; trerror->len = 0; *t = 0x80000000; /* Default returned time... */ if (tr_tm(T)) /* Compute missing information... */ FINISH; if ((T->tm_year < 1902) || (T->tm_year >=2038)) { trerror->errno = -1; trerror->msg = "Year outside limits [1902, 2038]"; tr_error(); FINISH; } n = T->tm_year - 1970; y = (n >= 0 ? n+1 : n-2); /* Leap year counter */ n = 365*n + y/4; *t = (n + T->tm_yday) * 86400L + T->tm_hour * 3600L + T->tm_min * 60L + T->tm_sec; RETURN; } /*========================================================================*/ int tr_tm(T) /*+++ .PURPOSE Compute missing info in T structure .RETURNS 0 (good date) / -1 (bad data: invalid month or day number ...) .REMARKS ---*/ struct tm *T; /* MOD: Time as a structure */ { long int y, j, t; trerror->errno = 0; trerror->len = 0; trerror->msg = (char *)0; month[1] = 29; if (T->tm_mday) /* Compute Day of 400 yr cycle */ { if ( (T->tm_mon > 11) || (T->tm_mon < 0) ) trerror->msg = "bad month"; if ( (T->tm_mday <= 0) || (T->tm_mday > (int)month[T->tm_mon])) trerror->msg = "bad day_in_month"; if (trerror->msg) { trerror->errno = -1; tr_error(); FINISH; } } /* Convert time */ j = 0; t = ((long)(T->tm_hour*60) + (long)(T->tm_min))*60 + T->tm_sec; while (t < 0) { j--; t += 86400L; } while (t >= 86400L) { j++; t -= 86400L; } #if DEBUG printf("tr_tm: Time of day is %ld sec\n", t); #endif T->tm_sec = t%60; t /= 60; T->tm_min = t%60; T->tm_hour= t/60; t = j; /* Days */ y = T->tm_year % 400; T->tm_year /= 400; if (y < 0) { y += 400; T->tm_year -= 1;} T->tm_year *= 400; if (T->tm_mday) /* Compute Day of 400 yr cycle */ { y += 400; /* Positive interval */ j = y - (11 - T->tm_mon)/10; t += ((1461L*j)/4 + (306L * ((T->tm_mon+10)%12) + 5)/10 - (3* ((j + 100L)/100L))/4 + T->tm_mday + 59L) % 146097L; y -= 400; } else t += 365*y + (y+3)/4 - (y-1)/100 + T->tm_yday; while (t < 0) { T->tm_year -= 400; t += 146097L;} /* Compute Week day */ T->tm_wday = (t+6L)%7L; /* Compute Year */ T->tm_year += 400L*(t/146097L); t %= 146097L; y = 4 *(t + (t-60)/36524L) / 1461L; T->tm_year += y; T->tm_yday = t - y*365L - (y+3)/4 + (y-1)/100; /* Compute mday + mon from yday */ if (y&3) month[1] = 28; if ( ((y%100) == 0) && (y)) month[1] = 28; for (y=T->tm_yday, j=0; y>=(int)month[j]; y -= month[j], j++) ; T->tm_mon = j; T->tm_mday = y+1; #if DEBUG printf("Time %dh %dmn %ds\n", T->tm_hour, T->tm_min, T->tm_sec); #endif RETURN; }