7 #include <grass/datetime.h>
9 static int _datetime_add_field(DateTime *, DateTime *,
int);
10 static int _datetime_subtract_field(DateTime *, DateTime *,
int);
14 static double _debug_decimal(DateTime * dt)
18 if (dt->mode == DATETIME_RELATIVE) {
20 dtdec = dt->year + dt->month / 12.;
23 dtdec = dt->day / 365.25 +
24 dt->hour / 8766. + dt->minute / 525960.
25 + dt->second / 31557600.;
79 if (src->mode == DATETIME_RELATIVE) {
82 ? DATETIME_DAY : DATETIME_YEAR;
97 if ((dt->positive && incr->positive) ||
98 (dt->mode == DATETIME_RELATIVE && !dt->positive && !incr->positive)) {
100 for (i = incr->to; i >= incr->from; i--) {
101 _datetime_add_field(dt, incr, i);
105 else if (!incr->positive || dt->mode == DATETIME_RELATIVE) {
107 for (i = incr->to; i >= incr->from; i--) {
108 _datetime_subtract_field(dt, incr, i);
114 else if (!incr->positive) {
116 for (i = incr->to; i > DATETIME_YEAR; i--) {
117 _datetime_subtract_field(dt, incr, i);
119 _datetime_add_field(dt, incr, DATETIME_YEAR);
123 for (i = incr->to; i > DATETIME_YEAR; i--) {
124 _datetime_add_field(dt, incr, i);
126 _datetime_subtract_field(dt, incr, DATETIME_YEAR);
131 if (src->mode == DATETIME_RELATIVE) {
155 static int _datetime_subtract_field(DateTime * src, DateTime * incr,
159 if (src->mode == DATETIME_RELATIVE) {
160 DateTime srcinc, tinc;
166 case DATETIME_SECOND:
169 if (src->second < incr->second) {
170 if ((
int)(incr->second - src->second) == (incr->second - src->second)) {
171 borrow = 1 + (incr->second - src->second - 1) / 60;
174 borrow = 1 + (incr->second - src->second) / 60;
175 src->second += borrow * 60;
177 src->second -= incr->second;
179 srcinc.minute = borrow;
180 _datetime_subtract_field(src, &srcinc, DATETIME_MINUTE);
184 case DATETIME_MINUTE:
185 if (src->minute < incr->minute) {
186 borrow = 1 + (incr->minute - src->minute - 1) / 60;
187 src->minute += borrow * 60;
189 src->minute -= incr->minute;
191 srcinc.hour = borrow;
192 _datetime_subtract_field(src, &srcinc, DATETIME_HOUR);
197 if (src->hour < incr->hour) {
198 borrow = 1 + (incr->hour - src->hour - 1) / 24;
199 src->hour += borrow * 24;
201 src->hour -= incr->hour;
204 _datetime_subtract_field(src, &srcinc, DATETIME_DAY);
209 if (src->day < incr->day) {
210 src->day = incr->day - src->day;
219 src->day -= incr->day;
223 if (src->month < incr->month) {
224 borrow = 1 + (incr->month - src->month - 1) / 12;
225 src->month += borrow * 12;
227 src->month -= incr->month;
229 srcinc.year = borrow;
230 _datetime_subtract_field(src, &srcinc, DATETIME_YEAR);
235 if (src->year < incr->year) {
236 src->year = incr->year - src->year;
243 src->year -= incr->year;
248 else if (src->mode == DATETIME_ABSOLUTE) {
249 DateTime srcinc, tinc, cpsrc;
250 int i, newdays, borrow = 0;
255 case DATETIME_SECOND:
256 if (src->second < incr->second) {
257 borrow = 1 + (incr->second - src->second - 1) / 60;
258 src->second += borrow * 60;
260 src->second -= incr->second;
262 srcinc.minute = borrow;
263 _datetime_subtract_field(src, &srcinc, DATETIME_MINUTE);
267 case DATETIME_MINUTE:
268 if (src->minute < incr->minute) {
269 borrow = 1 + (incr->minute - src->minute - 1) / 60;
270 src->minute += borrow * 60;
272 src->minute -= incr->minute;
274 srcinc.hour = borrow;
275 _datetime_subtract_field(src, &srcinc, DATETIME_HOUR);
280 if (src->hour < incr->hour) {
281 borrow = 1 + (incr->hour - src->hour - 1) / 24;
282 src->hour += borrow * 24;
284 src->hour -= incr->hour;
287 _datetime_subtract_field(src, &srcinc, DATETIME_DAY);
293 if (src->day <= incr->day) {
300 while (newdays <= incr->day) {
301 _datetime_subtract_field(&cpsrc, &tinc, DATETIME_MONTH);
309 src->day -= incr->day;
317 srcinc.month = borrow;
318 _datetime_subtract_field(src, &srcinc, DATETIME_MONTH);
323 if (src->month <= incr->month) {
324 borrow = 1 + (incr->month - src->month) / 12;
325 src->month += borrow * 12;
327 src->month -= incr->month;
329 srcinc.year = borrow;
330 _datetime_subtract_field(src, &srcinc, DATETIME_YEAR);
335 if (src->year <= incr->year) {
337 tinc.positive = src->positive;
339 tinc.month = src->month - 1;
340 src->year = incr->year - src->year + 1;
348 tinc.day = src->day - 1;
349 for (i = src->month - 1; i > 0; i--) {
354 tinc.hour = src->hour;
355 tinc.minute = src->minute;
356 tinc.second = src->second;
357 src->year = incr->year - src->year + 1;
362 src->hour = src->minute = 0;
368 src->year -= incr->year;
380 static int _datetime_carry(DateTime * dt,
int absolute)
385 for (i = dt->to; i > dt->from && i > DATETIME_DAY; i--) {
387 case DATETIME_SECOND:
388 if (dt->second >= 60.) {
389 carry = dt->second / 60.;
391 dt->second -= carry * 60;
394 case DATETIME_MINUTE:
395 if (dt->minute >= 60) {
396 carry = dt->minute / 60;
398 dt->minute -= carry * 60;
402 if (dt->hour >= 24) {
403 carry = dt->hour / 24;
405 dt->hour -= carry * 24;
412 if (!absolute && !dt->positive && dt->mode == DATETIME_ABSOLUTE) {
413 dt->year = -dt->year;
416 if (dt->from == DATETIME_YEAR && dt->to >= DATETIME_MONTH) {
419 if (dt->mode == DATETIME_ABSOLUTE) {
420 if (dt->month > 12) {
421 carry = (dt->month - 1) / 12;
425 dt->month -= carry * 12;
432 if (dt->month >= 12) {
433 carry = dt->month / 12;
435 dt->month -= carry * 12;
442 if (dt->mode == DATETIME_ABSOLUTE && dt->to > DATETIME_MONTH) {
448 if (dt->month == 12) {
461 if (!absolute && dt->mode == DATETIME_ABSOLUTE) {
463 dt->year = -dt->year;
473 static int _datetime_add_field(DateTime * src, DateTime * incr,
int field)
476 case DATETIME_SECOND:
477 src->second += incr->second;
479 case DATETIME_MINUTE:
480 src->minute += incr->minute;
483 src->hour += incr->hour;
486 src->day += incr->day;
489 src->month += incr->month;
492 src->year += incr->year;
495 if (src->mode == DATETIME_RELATIVE)
496 _datetime_carry(src, 1);
498 _datetime_carry(src, 0);
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 'sr...
int datetime_error_code(void)
returns an error code
int datetime_is_valid_increment(const DateTime *src, const DateTime *incr)
Returns: datetime_check_increment(src, incr) == 0.
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...
int datetime_in_interval_day_second(int x)
void datetime_copy(DateTime *dst, const DateTime *src)
Copies the DateTime [into/from ???] src.
void datetime_invert_sign(DateTime *dt)
int datetime_days_in_month(int year, int month, int ad)
returns number of days in 'month' of a particular 'year'
int datetime_in_interval_year_month(int x)
int datetime_set_increment_type(const DateTime *src, DateTime *incr)
src must be legal This is a convenience routine which is implemented as follows: