grass  7.8.6
About: GRASS (Geographic Resources Analysis Support System) is a raster- and vector-based GIS, image processing system, graphics production system and spatial modeling system.
  Fossies Dox: grass-7.8.6.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

diff.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 1995. Bill Brown <brown@gis.uiuc.edu> & Michael Shapiro
3 *
4 * This program is free software under the GPL (>=v2)
5 * Read the file GPL.TXT coming with GRASS for details.
6 */
7#include <stdlib.h>
8#include <grass/datetime.h>
9#include "math.h"
10
11/*************************************************************/
12/*
13 This performs the formula: result = a - b;
14
15 both a and b must be absolute.
16 result will be relative
17 If a is "earlier" than b, then result should be set negative.
18
19 b must be no more "precise" than a.
20 (a copy of b is "extended" to the precision of a)
21
22 datetime_copy (tb, b)
23 datetime_reset_from_to (tb, b.from, a.to, a.fracsec))
24
25
26 If result.to == SECOND, then result.fracsec is a.fracsec
27
28 result will have the following from/to based on a.to:
29
30 result
31 a.to from to
32 YEAR YEAR YEAR
33 MONTH YEAR MONTH
34 DAY DAY DAY
35 HOUR DAY HOUR
36 MINUTE DAY MINUTE
37 SECOND DAY SECOND
38
39 If either 'a' or 'b' has a timezone, both must have a timezone.
40 The difference will account for the differences in the time zones.
41 */
42
43static int _datetime_ymd_to_ddays(const DateTime *, double *);
44static int _datetime_compare(const DateTime *, const DateTime *);
45
46
47/*!
48 * \brief
49 *
50 *
51 * This performs the formula: result = a - b;
52 * <ul>
53 <li> both a and b must be absolute.
54 * </li>
55 <li> result will be relative
56 * </li>
57 <li> If a is "earlier" than b, then result will be set negative.
58 * </li>
59 <li> b must be no more "precise" than a.
60 * (a copy of b is "extended" to the precision of a)
61 * </li>
62 <li> If result.to == SECOND, then result.fracsec is a.fracsec
63 * </li>
64 <li> result will have the following from/to based
65 * on a.to: result a.to from to YEAR YEAR YEAR MONTH YEAR
66 * MONTH DAY DAY DAY HOUR DAY HOUR MINUTE DAY
67 * MINUTE SECOND DAY SECOND [LAYOUT ??? - see HTML]
68 * </li>
69 <li> If either 'a' or 'b' has a timezone, both must have a timezone. The
70 * difference will account for the differences in the time zones.
71 </li></ul>
72
73 *
74 * \param a
75 * \param b
76 * \param result
77 * \return int
78 */
79
80int
81datetime_difference(const DateTime * a, const DateTime * b, DateTime * result)
82{
83 DateTime tb, ta, *early, *late;
84 int compare, tzmin;
85
86 /* if not both absolute, return error */
87
88 datetime_copy(&tb, b);
89 datetime_change_from_to(&tb, DATETIME_YEAR, a->to, a->fracsec);
90
91 datetime_copy(&ta, a);
92 if (datetime_get_timezone(&ta, &tzmin) == 0 ||
93 datetime_get_timezone(&tb, &tzmin) == 0) {
94 if (datetime_get_timezone(&ta, &tzmin) == 0 &&
95 datetime_get_timezone(&tb, &tzmin) == 0) {
98 }
99 else
100 return datetime_error(-1,
101 "only one opperand contains valid timezone");
102 }
103
104 /* initialize result */
107 ta.to, ta.fracsec);
108 compare = _datetime_compare(&ta, &tb);
109 if (compare > 0) {
110 early = &tb;
111 late = &ta;
112 result->positive = 1;
113 }
114 else if (compare < 0) {
115 early = &ta;
116 late = &tb;
117 result->positive = 0;
118 }
119 else { /* equal */
120 return (0);
121 }
122
123 /* now the work */
125 int dm;
126
127 if (ta.positive == tb.positive) {
128 /* change if we use doubles! */
129 result->year = abs(late->year - early->year);
130 }
131 else {
132 result->year = late->year + early->year - 2;
133 }
134 dm = late->month - early->month;
135 if (dm >= 0)
136 result->month = dm;
137 else {
138 result->year -= 1;
139 result->month = dm + 12;
140 }
141 }
142 else {
143 DateTime erel, lrel;
144 double latedays, earlydays;
145
147 _datetime_ymd_to_ddays(early, &earlydays);
148 /* copy day -> down */
149 erel.day = earlydays;
150 erel.hour = early->hour;
151 erel.minute = early->minute;
152 erel.second = early->second;
153
155 _datetime_ymd_to_ddays(late, &latedays);
156 /* copy day -> down */
157 lrel.day = latedays;
158 lrel.hour = late->hour;
159 lrel.minute = late->minute;
160 lrel.second = late->second;
161
163 datetime_increment(&erel, &lrel);
164
165 /* copy erel back to result */
166 result->day = erel.day;
167 result->hour = erel.hour;
168 result->minute = erel.minute;
169 result->second = erel.second;
170
171 /* need carry? */
172 }
173
174 return (0);
175}
176
177/*************************************************************/
178/* returns 1 if a is later than b,
179 -1 if a is earlier than a,
180 0 otherwise
181 */
182/* only looks at from-to fields defined by a */
183
184static int _datetime_compare(const DateTime * a, const DateTime * b)
185{
186 int i;
187
188 if (a->positive && !b->positive)
189 return (1);
190 else if (b->positive && !a->positive)
191 return (-1);
192
193 /* same signs */
194 for (i = a->from; i <= a->to; i++) {
195 switch (i) {
196
197 case DATETIME_SECOND:
198 if (a->second > b->second)
199 return (1);
200 else if (a->second < b->second)
201 return (-1);
202 break;
203
204 case DATETIME_MINUTE:
205 if (a->minute > b->minute)
206 return (1);
207 else if (a->minute < b->minute)
208 return (-1);
209 break;
210
211 case DATETIME_HOUR:
212 if (a->hour > b->hour)
213 return (1);
214 else if (a->hour < b->hour)
215 return (-1);
216 break;
217
218 case DATETIME_DAY:
219 if (a->day > b->day)
220 return (1);
221 else if (a->day < b->day)
222 return (-1);
223 break;
224
225 case DATETIME_MONTH:
226 if (a->month > b->month)
227 return (1);
228 else if (a->month < b->month)
229 return (-1);
230 break;
231
232 case DATETIME_YEAR: /* only place sign matters */
233 if (a->positive) {
234 if (a->year > b->year)
235 return (1);
236 else if (a->year < b->year)
237 return (-1);
238 }
239 else {
240 if (a->year < b->year)
241 return (1);
242 else if (a->year > b->year)
243 return (-1);
244 }
245 break;
246 }
247 }
248 return (0);
249
250
251}
252
253/*************************************************************/
254
255static int _datetime_ymd_to_ddays(const DateTime * dtymd, double *days)
256{ /* note extra precision! */
257 int yr, mo;
258
259
260 *days = 0.0;
261
262 if (dtymd->positive) {
263 *days = dtymd->day - 1; /* start w/ days - 1 */
264 for (mo = dtymd->month - 1; mo > 0; mo--) { /* add earlier months */
265 *days += datetime_days_in_month(dtymd->year, mo, dtymd->positive);
266 }
267 for (yr = dtymd->year - 1; yr > 0; yr--) { /* add earlier years */
268 *days += datetime_days_in_year(yr, dtymd->positive);
269 }
270 }
271 else {
272 for (yr = dtymd->year - 1; yr > 0; yr--) { /* add later years */
273 *days += datetime_days_in_year(yr, dtymd->positive);
274 }
275 for (mo = 12; mo >= dtymd->month; mo--) { /*add current & later months */
276 *days += datetime_days_in_month(dtymd->year, mo, dtymd->positive);
277 }
278 *days -= dtymd->day; /* subtract current days */
279 }
280
281 return 0;
282}
283
284/*************************************************************/
285
286/*************************************************************/
int datetime_change_from_to(DateTime *dt, int from, int to, int round)
Changes the from/to of the type for dt. The 'from/to' must be legal values for the mode of dt; (if th...
Definition: change.c:55
void datetime_copy(DateTime *dst, const DateTime *src)
Copies the DateTime [into/from ???] src.
Definition: copy.c:20
int datetime_error(int code, char *msg)
record 'code' and 'msg' as error code/msg (in static variables) code==0 will clear the error (ie set ...
Definition: error.c:30
int datetime_days_in_month(int year, int month, int ad)
returns number of days in 'month' of a particular 'year'
Definition: misc.c:64
int datetime_days_in_year(int year, int ad)
returns the number of days in 'year'
Definition: misc.c:41
int datetime_set_type(DateTime *dt, int mode, int from, int to, int fracsec)
Definition: type.c:37
int datetime_in_interval_year_month(int x)
Definition: type.c:151
#define DATETIME_MONTH
Definition: datetime.h:11
#define DATETIME_DAY
Definition: datetime.h:12
#define DATETIME_HOUR
Definition: datetime.h:13
#define DATETIME_SECOND
Definition: datetime.h:15
#define DATETIME_MINUTE
Definition: datetime.h:14
#define DATETIME_RELATIVE
Definition: datetime.h:5
#define DATETIME_YEAR
Definition: datetime.h:10
int compare(const void *a, const void *b)
Definition: dgraph.c:177
static int _datetime_compare(const DateTime *, const DateTime *)
Definition: diff.c:184
int datetime_difference(const DateTime *a, const DateTime *b, DateTime *result)
This performs the formula: result = a - b;.
Definition: diff.c:81
static int _datetime_ymd_to_ddays(const DateTime *, double *)
Definition: diff.c:255
int datetime_increment(DateTime *src, DateTime *incr)
This function changes the 'src' date/time data based on the 'incr' The type (mode/from/to) of the '...
Definition: incr1.c:67
int datetime_set_increment_type(const DateTime *src, DateTime *incr)
src must be legal This is a convenience routine which is implemented as follows:
Definition: incr3.c:86
double b
Definition: r_raster.c:39
void datetime_invert_sign(DateTime *dt)
Definition: sign.c:80
int positive
Definition: datetime.h:25
int month
Definition: datetime.h:22
int year
Definition: datetime.h:22
int to
Definition: datetime.h:20
double second
Definition: datetime.h:24
int fracsec
Definition: datetime.h:21
int hour
Definition: datetime.h:23
int minute
Definition: datetime.h:23
int day
Definition: datetime.h:22
int datetime_get_timezone(const DateTime *dt, int *minutes)
returns 0 on success
Definition: tz1.c:49
int datetime_change_to_utc(DateTime *dt)
Return datetime_change_timezone (dt, 0);.
Definition: tz2.c:63
static unsigned int a
Definition: unfl.c:8