libtime++: Date and time calculation
timeutil.c
Go to the documentation of this file.
1 /* this is <timeutil.c>
2  *
3  * for manipulating absolute data times
4  *
5  * Copyright 1997 by Thomas Forbriger
6  *
7  * ----
8  * libtime is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  * ----
22  *
23  * 25/04/97 Thomas Forbriger (IfG Stuttgart)
24  * 27/05/97 timeutil_norm did ignore carry to doy
25  * 15/11/10 avoid tfmacros.h
26  *
27  * This is a pure C pre-version of libtime.f
28  * By now (5/8/2000) it is still included in libtime.a but provides no extra
29  * functionality. It may be removed in the future.
30  *
31  */
32 
33 #include <stdio.h>
34 #include <stddef.h>
35 #include <stdlib.h>
36 #include <timeutil.h>
37 
38 #define TU_EXIT_FAILURE 1
39 #define TU_CHECKERROR( EXPR , SUB, STR )\
40  if ( EXPR ) { fprintf(stderr, "ERROR (%s):\n %s\n", SUB, STR );\
41  exit(TU_EXIT_FAILURE); }
42 
43 /*
44  * some constants we need internally
45  * =================================
46  */
47 
48 /* days in each month */
49 static int timeutil_DaysInYear[13] \
50  ={0,31,28,31,30,31,30,31,31,30,31,30,31};
51 static int timeutil_DaysInLeapYear[13] \
52  ={0,31,29,31,30,31,30,31,31,30,31,30,31};
53 
54 /* value limits */
55 static long int timeutil_limits[TIMEUTIL_N_ELEMENTS] \
56  = {-1L, -1L, -1L, -1L, 24L, 60L, 60L, 1000L, 1000L};
57 
58 /*
59  * clear time structure
60  * ====================
61  */
63 timeutil_Ttime *td;
64 {
65  long int *ptr;
66  int i;
67 
68  ptr=(long int *)td;
69  for (i=0; i<TIMEUTIL_N_ELEMENTS; i++) {
70  ptr[i]=0;
71  }
72 } /* timeutil_clear */
73 
74 /*
75  * write time to string
76  * ====================
77  */
78 char *timeutil_print(td)
80 {
81  static char string[35];
82  timeutil_finish(&td);
83  sprintf(string, "%3d %2.2d/%2.2d/%4.4d %2.2d:%2.2d:%2.2d.%3.3d%3.3d",
84  td.doy, td.day, td.month, td.year,
85  td.hour, td.min, td.sec, td.msec, td.usec);
86  return string;
87 } /* timeutil_print */
88 
89 /*
90  * finish preset time structure
91  * ============================
92  *
93  * this is used to set the doy-value and the full year
94  */
96 timeutil_Ttime *td;
97 {
98  if (td->year<70) td->year=td->year+2000;
99  if (td->year<100) td->year=td->year+1900;
100  td->doy=timeutil_doy(*td);
101  timeutil_norm(td);
102 } /* timeutil_finish */
103 
104 /*
105  * calculate day of year (doy)
106  * ===========================
107  */
108 long int timeutil_doy(td)
109 timeutil_Ttime td;
110 {
111  int *days;
112  long int doy;
113  int i;
114 
115  days=timeutil_DaysInYear;
116  if (timeutil_is_leap(td.year)==1) { days=timeutil_DaysInLeapYear; }
117 
118  doy=0;
119  i=1;
120  while (i<td.month) {
121  doy=doy+days[i];
122  i=i+1;
123  TU_CHECKERROR((i>13),"timeutil_doy","month value out of range")
124  }
125  doy=doy+td.day;
126  return doy;
127 } /* timeutil_doy */
128 
129 /*
130  * check wheter year in data is leap-year or not
131  * =============================================
132  *
133  * return code
134  * 0: no leap-year
135  * 1: is leap-year
136  */
138 long int year;
139 {
140  int res1, res2, res3;
141 
142  if (year<70) { year = year + 2000; }
143  if (year<100) { year = year + 1900; }
144 
145  res1=(int)(year-(int)(year/4)*4);
146  res2=(int)(year-(int)(year/100)*100);
147  res3=(int)(year-(int)(year/400)*400);
148 
149  if (((res1==0) && (res2!=0)) || (res3==0))
150  {
151  return 1;
152  } else {
153  return 0;
154  }
155 } /* timeutil_is_leap */
156 
157 /*
158  * calculate date from day of year (doy)
159  * =====================================
160  */
161 void timeutil_date(td, doy)
162 timeutil_Ttime *td;
163 long int doy;
164 {
165  int *days;
166 
167  td->doy=doy;
168 
169  days=timeutil_DaysInYear;
170  if (timeutil_is_leap(td->year)==1) { days=timeutil_DaysInLeapYear; }
171 
172  td->day=doy;
173  td->month=1;
174  while(td->day>days[td->month]) {
175  td->day=td->day-days[td->month];
176  td->month=td->month+1;
177  TU_CHECKERROR((td->month>13), "timeutil_date", "doy value out of range")
178  }
179 } /* timeutil_date */
180 
181 /*
182  * normalize values in time structure to allowed ranges
183  * ====================================================
184  *
185  * the date is taken from the doy value in this case
186  */
188 timeutil_Ttime *td;
189 {
190  int i;
191  long int carry, diy;
192  long int *ptr;
193 
194  ptr=(long int *)td;
195 
196  /* set correct values up to hours */
197  /* carry to doy values is worked out */
198  /* but doy value may still be incorrect */
199  for (i=TIMEUTIL_N_ELEMENTS-1; i>=TIMEUTIL_FIRST_LINEAR-1; i--) {
200  carry=(long int)(ptr[i]/timeutil_limits[i]);
201  if (ptr[i]<0) carry=carry-1;
202  ptr[i]=ptr[i]-carry*timeutil_limits[i];
203  ptr[i-1]=ptr[i-1]+carry;
204  }
205 
206  /* catch day carry for doy */
207  td->doy=td->doy+carry;
208 
209  /* work on doy and year */
210  if (td->year<70) td->year=td->year+2000;
211  if (td->year<100) td->year=td->year+1900;
212  if (td->doy>0) {
213  diy=365;
214  if (timeutil_is_leap(td->year)==1) diy=366;
215  while (td->doy>diy) {
216  td->doy=td->doy-diy;
217  td->year=td->year+1;
218  diy=365;
219  if (timeutil_is_leap(td->year)==1) diy=366;
220  }
221  } else {
222  while (td->doy<1) {
223  td->year=td->year-1;
224  diy=365;
225  if (timeutil_is_leap(td->year)==1) diy=366;
226  td->doy=td->doy+diy;
227  }
228  }
229  timeutil_date(td, td->doy);
230 } /* timeutil_norm */
231 
232 /*
233  * add to time records
234  * ===================
235  */
236 void timeutil_add(sum, td1, td2)
237 timeutil_Ttime *sum;
238 timeutil_Ttime td1;
239 timeutil_Ttime td2;
240 {
241  sum->usec =td1.usec +td2.usec;
242  sum->msec =td1.msec +td2.msec;
243  sum->sec =td1.sec +td2.sec;
244  sum->min =td1.min +td2.min;
245  sum->hour =td1.hour +td2.hour;
246  sum->doy =td1.doy +td2.doy;
247  sum->year =td1.year +td2.year;
248  timeutil_norm(sum);
249 } /* timeutil_add */
250 
251 /*
252  * compare two data times
253  * ======================
254  *
255  * returnvalue:
256  * 0: both are equal
257  * 1: time1>time2
258  * -1: time1<time2
259  */
260 int timeutil_compare(time1, time2)
261 timeutil_Ttime time1;
262 timeutil_Ttime time2;
263 {
264  if (time1.year >time2.year) return 1;
265  if (time1.year <time2.year) return -1;
266  if (time1.month >time2.month) return 1;
267  if (time1.month <time2.month) return -1;
268  if (time1.day >time2.day) return 1;
269  if (time1.day <time2.day) return -1;
270  if (time1.hour >time2.hour) return 1;
271  if (time1.hour <time2.hour) return -1;
272  if (time1.min >time2.min) return 1;
273  if (time1.min <time2.min) return -1;
274  if (time1.sec >time2.sec) return 1;
275  if (time1.sec <time2.sec) return -1;
276  if (time1.msec >time2.msec) return 1;
277  if (time1.msec <time2.msec) return -1;
278  if (time1.usec >time2.usec) return 1;
279  if (time1.usec <time2.usec) return -1;
280  return 0;
281 } /* timeutil_compare */
282 
283 /***** END OF timeutil.c *****/
284 
long int doy
Definition: timeutil.h:58
static int timeutil_DaysInLeapYear[13]
Definition: timeutil.c:52
static long int timeutil_limits[TIMEUTIL_N_ELEMENTS]
Definition: timeutil.c:56
long int month
Definition: timeutil.h:58
void timeutil_date(timeutil_Ttime *td, long int doy)
Definition: timeutil.c:161
#define TU_CHECKERROR(EXPR, SUB, STR)
Definition: timeutil.c:39
long int msec
Definition: timeutil.h:59
#define TIMEUTIL_N_ELEMENTS
Definition: timeutil.h:44
int timeutil_is_leap(long int year)
Definition: timeutil.c:137
void timeutil_norm(timeutil_Ttime *td)
Definition: timeutil.c:187
long int sec
Definition: timeutil.h:59
char * timeutil_print(timeutil_Ttime td)
Definition: timeutil.c:78
#define TIMEUTIL_FIRST_LINEAR
Definition: timeutil.h:47
void timeutil_finish(timeutil_Ttime *td)
Definition: timeutil.c:95
long int hour
Definition: timeutil.h:59
int timeutil_compare(timeutil_Ttime time1, timeutil_Ttime time2)
Definition: timeutil.c:260
long int day
Definition: timeutil.h:58
static int timeutil_DaysInYear[13]
Definition: timeutil.c:50
long int usec
Definition: timeutil.h:59
long int timeutil_doy(timeutil_Ttime td)
Definition: timeutil.c:108
long int min
Definition: timeutil.h:59
void timeutil_clear(timeutil_Ttime *td)
Definition: timeutil.c:62
void timeutil_add(timeutil_Ttime *sum, timeutil_Ttime td1, timeutil_Ttime td2)
Definition: timeutil.c:236
long int year
Definition: timeutil.h:58