diff options
author | Lars Henriksen <LarsHenriksen@get2net.dk> | 2019-06-23 21:42:24 +0200 |
---|---|---|
committer | Lukas Fleischer <lfleischer@calcurse.org> | 2019-09-06 18:15:36 -0400 |
commit | 5fbc499886e93f681f05b7219c7f844d17eaeb1d (patch) | |
tree | 97bdf311ec21eb87571d346ae81406bd180d4f59 /src | |
parent | 8a0354e6da920637bdc19063d87240dfa04e2b31 (diff) | |
download | calcurse-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.c | 11 |
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: |