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)  

change.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 <grass/datetime.h>
8
9static void make_incr();
10
11
12/*!
13 * \brief
14 *
15 * Changes the from/to of the type for dt.
16 * The 'from/to' must be legal
17 * values for the mode of dt; (if they are not legal, then the original values
18 * are preserved, dt is not changed).
19 * Returns:
20 * 0 OK
21 * -1 invalid 'dt'
22 * -2 invalid 'from/to' <br>
23 <ul>
24 <li> round =
25 * negative implies floor() [decrease magnitude]
26 * 0 implies normal rounding, [incr/decr magnitude]
27 * positive implies ceil() [increase magnitude]
28 </li>
29 <li> If dt.from < 'from' (losing "lower" elements), convert the "lost"
30 * values to the equivalent value for the new 'from' Lost elements are then set
31 * to zero. (This case can only occur for dt.mode relative):
32 * months += lost years * 12 ; years = 0
33 * hours += lost days * 24 ; days = 0
34 * minutes += lost hours * 60 ; hours = 0
35 * seconds += lost minutes * 60.0 ; minutes = 0
36 </li>
37 <li> If dt.from > 'from' (adding "lower" elements), the new elements are set
38 * to zero.
39 </li>
40 <li> If dt.to < 'to' (adding "higher" elements), the new elements are set to
41 * zero.
42 </li>
43 <li> If dt.to > 'to' (losing "higher" elements), the the new 'to' is
44 * adjusted according to the value for 'round' After rounding the "lost"
45 * elements are set to zero.
46 </li></ul>
47 *
48 * \param dt
49 * \param from
50 * \param to
51 * \param round
52 * \return int
53 */
54
55int datetime_change_from_to(DateTime * dt, int from, int to, int round)
56{
57 DateTime dummy, incr;
58 int pos;
59 int carry;
60 int ndays;
61 int dtfrom;
62
63 /* is 'dt' valid? */
65 return -1;
66
67 /* is new from/to valid for dt->mode? */
68 if (datetime_set_type(&dummy, dt->mode, from, to, 0) != 0)
69 return -2;
70
71 /* copy dt->from to local variable, then change it
72 in the structure so that increment works correctly for RELATIVE.
73 Otherwise, since increment "reduces" answers, performing carries,
74 we would carry to invalid units */
75
76 dtfrom = dt->from;
77
78 /* now set the from */
79 dt->from = from;
80
81 /* convert the "lost" lower elements to equiv value for the new 'from'
82 * NOTE: this only affects DATETIME_RELATIVE
83 * since absolute will have from==dt->from==YEAR
84 */
85 for (pos = dtfrom; pos < from; pos++) {
86 switch (pos) {
87 case DATETIME_YEAR:
88 dt->month += dt->year * 12;
89 dt->year = 0;
90 break;
91 case DATETIME_DAY:
92 dt->hour += dt->day * 24;
93 dt->day = 0;
94 break;
95 case DATETIME_HOUR:
96 dt->minute += dt->hour * 60;
97 dt->hour = 0;
98 break;
99 case DATETIME_MINUTE:
100 dt->second += dt->minute * 60.0;
101 dt->minute = 0;
102 break;
103 }
104 }
105
106 /* if losing precision, round
107 * round > 0 force up if any lost values not zero
108 * round ==0 increment by all lost values
109 */
110 if (to < dt->to) {
111 if (round > 0) {
112 int x;
113
114 x = datetime_is_absolute(dt) ? 1 : 0;
115
116 for (carry = 0, pos = dt->to; carry == 0 && pos > to; pos--) {
117 switch (pos) {
118 case DATETIME_MONTH:
119 if (dt->month != x)
120 carry = 1;
121 break;
122 case DATETIME_DAY:
123 if (dt->day != x)
124 carry = 1;
125 break;
126 case DATETIME_HOUR:
127 if (dt->hour != 0)
128 carry = 1;
129 break;
130 case DATETIME_MINUTE:
131 if (dt->minute != 0)
132 carry = 1;
133 break;
134 case DATETIME_SECOND:
135 if (dt->second != 0)
136 carry = 1;
137 break;
138 }
139 }
140
141 if (carry) {
142 make_incr(&incr, to, to, dt);
143
144 incr.year = 1;
145 incr.month = 1;
146 incr.day = 1;
147 incr.hour = 1;
148 incr.minute = 1;
149 incr.second = 1.0;
150
151 datetime_increment(dt, &incr);
152 }
153 }
154
155 if (round == 0) {
156 /*NEW*/ if (datetime_is_absolute(dt))
157 /*NEW*/ ndays = datetime_days_in_year(dt->year, dt->positive);
158 /*NEW*/
159 else
160 /*NEW*/ ndays = 0;
161
162 for (pos = dt->to; pos > to; pos--) {
163 make_incr(&incr, pos, pos, dt);
164
165 incr.year = dt->year;
166 incr.month = dt->month;
167 /*NEW*/ incr.day = dt->day + ndays / 2;
168 incr.hour = dt->hour;
169 incr.minute = dt->minute;
170 incr.second = dt->second;
171
172 datetime_increment(dt, &incr);
173 /*NEW*/ if (ndays > 0 && pos == DATETIME_DAY)
174 /*NEW*/ break;
175 }
176 }
177 }
178
179 /* set the new elements to zero */
180 for (pos = from; pos < dtfrom; pos++)
181 switch (pos) {
182 case DATETIME_YEAR:
183 dt->year = 0;
184 break;
185 case DATETIME_MONTH:
186 dt->month = 0;
187 break;
188 case DATETIME_DAY:
189 dt->day = 0;
190 break;
191 case DATETIME_HOUR:
192 dt->hour = 0;
193 break;
194 case DATETIME_MINUTE:
195 dt->minute = 0;
196 break;
197 case DATETIME_SECOND:
198 dt->second = 0;
199 break;
200 }
201
202 for (pos = to; pos > dt->to; pos--)
203 switch (pos) {
204 case DATETIME_YEAR:
205 dt->year = 0;
206 break;
207 case DATETIME_MONTH:
208 dt->month = 0;
209 break;
210 case DATETIME_DAY:
211 dt->day = 0;
212 break;
213 case DATETIME_HOUR:
214 dt->hour = 0;
215 break;
216 case DATETIME_MINUTE:
217 dt->minute = 0;
218 break;
219 case DATETIME_SECOND:
220 dt->second = 0;
221 break;
222 }
223
224 /* make sure that fracsec is zero if original didn't have seconds */
225 if (dt->to < DATETIME_SECOND)
226 dt->fracsec = 0;
227
228 /* now set the to */
229 dt->to = to;
230
231 return 0;
232}
233
234static void make_incr(DateTime * incr, int from, int to, DateTime * dt)
235{
236 datetime_set_type(incr, DATETIME_RELATIVE, from, to, 0);
239}
static void make_incr()
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
int datetime_days_in_year(int year, int ad)
returns the number of days in 'year'
Definition: misc.c:41
int datetime_is_valid_type(const DateTime *dt)
Returns: 1 if datetime_check_type() returns 0 0 if not.
Definition: type.c:80
int datetime_is_absolute(const DateTime *dt)
Returns: 1 if dt.mode is absolute 0 if not (even if dt.mode is not defined)
Definition: type.c:173
int datetime_set_type(DateTime *dt, int mode, int from, int to, int fracsec)
Definition: type.c:37
int datetime_is_relative(const DateTime *dt)
Returns: 1 if dt.mode is relative 0 if not (even if dt.mode is not defined)
Definition: type.c:190
#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 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
static void dummy(void)
Definition: mask.c:19
int datetime_is_negative(const DateTime *dt)
Returns: 1 if the DateTime is negative 0 otherwise.
Definition: sign.c:37
void datetime_set_negative(DateTime *dt)
Makes the DateTime negative. (B.C. for ABSOLUTE DateTimes)
Definition: sign.c:67
int positive
Definition: datetime.h:25
int month
Definition: datetime.h:22
int year
Definition: datetime.h:22
int mode
Definition: datetime.h:19
int to
Definition: datetime.h:20
double second
Definition: datetime.h:24
int fracsec
Definition: datetime.h:21
int from
Definition: datetime.h:20
int hour
Definition: datetime.h:23
int minute
Definition: datetime.h:23
int day
Definition: datetime.h:22
#define x