summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Culot <calcurse@culot.org>2007-12-10 19:03:23 +0000
committerFrederic Culot <calcurse@culot.org>2007-12-10 19:03:23 +0000
commit4139434f409f8b7b797411598aff5b761ed02489 (patch)
tree0c6a0875e9623e49cf9e65477cc7a36111598851
parent2c4f7c9e273c337716b0c9ee17b6e43c54acab0c (diff)
downloadcalcurse-4139434f409f8b7b797411598aff5b761ed02489.zip
bugfix in recur_item_inday(): leap years should now be properly handled
-rwxr-xr-xsrc/recur.c101
1 files changed, 50 insertions, 51 deletions
diff --git a/src/recur.c b/src/recur.c
index 47db9f2..655cda8 100755
--- a/src/recur.c
+++ b/src/recur.c
@@ -1,4 +1,4 @@
-/* $calcurse: recur.c,v 1.30 2007/10/21 13:42:34 culot Exp $ */
+/* $calcurse: recur.c,v 1.31 2007/12/10 19:03:23 culot Exp $ */
/*
* Calcurse - text-based organizer
@@ -376,12 +376,9 @@ unsigned
recur_item_inday(long item_start, struct days_s *item_exc,
int rpt_type, int rpt_freq, long rpt_until, long day_start)
{
-#define YEARSTODAYS(x) ((x) * 365L + (x) / 4 - (x) / 100 + (x) / 400)
-
date_t start_date;
- long day_end;
- struct tm *lt;
- int day_month, day_year, day_yday, day_mday, diff;
+ long day_end, diff;
+ struct tm lt_item, lt_day;
struct days_s *exc;
time_t t;
char *error =
@@ -389,12 +386,8 @@ recur_item_inday(long item_start, struct days_s *item_exc,
day_end = day_start + DAYINSEC;
t = day_start;
- lt = localtime(&t);
- day_month = lt->tm_mon;
- day_year = lt->tm_year;
- day_yday = lt->tm_yday;
- day_mday = lt->tm_mday;
-
+ lt_day = *localtime(&t);
+
for (exc = item_exc; exc != 0; exc = exc->next)
if (exc->st < day_end && exc->st >= day_start)
return 0;
@@ -402,53 +395,59 @@ recur_item_inday(long item_start, struct days_s *item_exc,
if (rpt_until == 0) /* we have an endless recurrent item */
rpt_until = day_end;
- if (item_start > day_end || rpt_until < day_start)
+ if (item_start > day_end || rpt_until < day_start)
return 0;
t = item_start;
- lt = localtime(&t);
+ lt_item = *localtime(&t);
+
+ /* For proper calculation, both items must start at same time. */
+ day_start += (lt_item.tm_hour * HOURINSEC + lt_item.tm_min * MININSEC +
+ lt_item.tm_sec);
switch (rpt_type) {
- case RECUR_DAILY:
- diff = (YEARSTODAYS(lt->tm_year) + lt->tm_yday) -
- (YEARSTODAYS(day_year) + day_yday);
- if (diff % rpt_freq != 0)
- return 0;
- lt->tm_mday = day_mday;
- lt->tm_mon = day_month;
- lt->tm_year = day_year;
- break;
- case RECUR_WEEKLY:
- diff = (YEARSTODAYS(lt->tm_year) + lt->tm_yday) -
- (YEARSTODAYS(day_year) + day_yday);
- if (diff % (rpt_freq*7) != 0)
- return 0;
- lt->tm_mday = day_mday;
- lt->tm_mon = day_month;
- lt->tm_year = day_year;
- break;
- case RECUR_MONTHLY:
- diff = ((day_year - lt->tm_year) * 12) +
- (day_month - lt->tm_mon);
- if (diff % rpt_freq != 0)
- return 0;
- lt->tm_mon = day_month;
- lt->tm_year = day_year;
- break;
- case RECUR_YEARLY:
- diff = day_year - lt->tm_year;
+ case RECUR_DAILY:
+ diff = (long)difftime((time_t)day_start, (time_t)item_start);
+ if (diff % (rpt_freq * DAYINSEC) != 0)
+ return 0;
+ lt_item.tm_mday = lt_day.tm_mday;
+ lt_item.tm_mon = lt_day.tm_mon;
+ lt_item.tm_year = lt_day.tm_year;
+ break;
+ case RECUR_WEEKLY:
+ if (lt_item.tm_wday != lt_day.tm_wday)
+ return 0;
+ else {
+ diff = ((lt_day.tm_yday - lt_item.tm_yday) / WEEKINDAYS);
if (diff % rpt_freq != 0)
return 0;
- lt->tm_year = day_year;
- break;
- default:
- fputs(error, stderr);
- exit(EXIT_FAILURE);
+ }
+ lt_item.tm_mday = lt_day.tm_mday;
+ lt_item.tm_mon = lt_day.tm_mon;
+ lt_item.tm_year = lt_day.tm_year;
+ break;
+ case RECUR_MONTHLY:
+ diff = ((lt_day.tm_year - lt_item.tm_year) * 12) +
+ (lt_day.tm_mon - lt_item.tm_mon);
+ if (diff % rpt_freq != 0)
+ return 0;
+ lt_item.tm_mon = lt_day.tm_mon;
+ lt_item.tm_year = lt_day.tm_year;
+ break;
+ case RECUR_YEARLY:
+ diff = lt_day.tm_year - lt_item.tm_year;
+ if (diff % rpt_freq != 0)
+ return 0;
+ lt_item.tm_year = lt_day.tm_year;
+ break;
+ default:
+ fputs(error, stderr);
+ exit(EXIT_FAILURE);
}
- start_date.dd = lt->tm_mday;
- start_date.mm = lt->tm_mon + 1;
- start_date.yyyy = lt->tm_year + 1900;
- item_start = date2sec(start_date, lt->tm_hour, lt->tm_min);
+ start_date.dd = lt_item.tm_mday;
+ start_date.mm = lt_item.tm_mon + 1;
+ start_date.yyyy = lt_item.tm_year + 1900;
+ item_start = date2sec(start_date, lt_item.tm_hour, lt_item.tm_min);
if (item_start < day_end && item_start >= day_start)
return item_start;