aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Henriksen <LarsHenriksen@get2net.dk>2019-06-23 21:42:24 +0200
committerLukas Fleischer <lfleischer@calcurse.org>2019-09-06 18:15:36 -0400
commit5fbc499886e93f681f05b7219c7f844d17eaeb1d (patch)
tree97bdf311ec21eb87571d346ae81406bd180d4f59 /src
parent8a0354e6da920637bdc19063d87240dfa04e2b31 (diff)
downloadcalcurse-5fbc499886e93f681f05b7219c7f844d17eaeb1d.tar.gz
calcurse-5fbc499886e93f681f05b7219c7f844d17eaeb1d.zip
Fix monthly and yearly recurrence algorithms
The calculation of the year of the most recent occurrence for year dates before the start date (disregarding the year) is incorrect for frequencies greater than one. The most recent occurrence (for a date as mentioned) is either too far or too close in the past. In most cases it does no harm because the most recent ocurrence is in the past and does not span the date (i.e. there is no occurrence on the day). But the following appointment shows the presence of the bug: 12/31/2019 @ 12:00 -> 01/01/2020 @ 12:00 {2Y} |new year The occurence on 1 Jan 2020 is missing, because the most recent occurrence is too far in the past (31 Dec 2018 instead of 31 Dec 2019). An occurrence appears on 1 Jan 2021, because the most recent occurence is too close in the past (31 Dec 2020 instead of 31 Dec 2019). A similar miscalculation affects the monthly rule as proved by 3/31/2019 @ 12:00 -> 4/1/2019 @ 11:00 {2M} |change of month Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
Diffstat (limited to 'src')
-rw-r--r--src/recur.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/recur.c b/src/recur.c
index fc1d538..1fd01ad 100644
--- a/src/recur.c
+++ b/src/recur.c
@@ -798,17 +798,18 @@ recur_item_find_occurrence(time_t item_start, long item_dur,
break;
case RECUR_MONTHLY:
diff = diff_months(lt_item_day, lt_day) % rpt_freq;
- if (lt_day.tm_mday < lt_item_day.tm_mday)
- diff++;
+ if (!diff && lt_day.tm_mday < lt_item_day.tm_mday)
+ diff += rpt_freq;
lt_item_day.tm_mon = lt_day.tm_mon - diff;
lt_item_day.tm_year = lt_day.tm_year;
break;
case RECUR_YEARLY:
diff = diff_years(lt_item_day, lt_day) % rpt_freq;
- if (lt_day.tm_mon < lt_item_day.tm_mon ||
+ if (!diff &&
+ (lt_day.tm_mon < lt_item_day.tm_mon ||
(lt_day.tm_mon == lt_item_day.tm_mon &&
- lt_day.tm_mday < lt_item_day.tm_mday))
- diff++;
+ lt_day.tm_mday < lt_item_day.tm_mday)))
+ diff += rpt_freq;
lt_item_day.tm_year = lt_day.tm_year - diff;
break;
default: