diff options
author | Ken Murchison <murch@fastmail.com> | 2020-11-06 09:23:00 -0500 |
---|---|---|
committer | Ken Murchison <murch@fastmail.com> | 2020-11-08 09:24:03 -0500 |
commit | 6c6944d917c897f48e43f9e5ea718217aacf0c1d (patch) | |
tree | db151b1d7c8e39d7fea06f3a61a3a111756e17bc | |
parent | 0fa0bd20b158842d48ba538dcd011b07f97fdefb (diff) | |
download | libical-git-6c6944d917c897f48e43f9e5ea718217aacf0c1d.tar.gz |
icalrecur.c: fixed handling of BYWEEKNO=1 with BYDAY (added tests for first and last weeks)
-rw-r--r-- | src/libical/icalrecur.c | 41 | ||||
-rw-r--r-- | src/test/icalrecur_test.c | 10 | ||||
-rw-r--r-- | src/test/icalrecur_test.out | 8 |
3 files changed, 51 insertions, 8 deletions
diff --git a/src/libical/icalrecur.c b/src/libical/icalrecur.c index 1437198f..c1f960e6 100644 --- a/src/libical/icalrecur.c +++ b/src/libical/icalrecur.c @@ -2329,8 +2329,11 @@ static int expand_by_day(icalrecur_iterator *impl, int year, } } - (void)__icaltime_from_day_of_year(impl, day + doy_offset, year, - &this_weekno); + if (doy_offset < 0) this_weekno = 1; + else { + (void)__icaltime_from_day_of_year(impl, day + doy_offset, year, + &this_weekno); + } /* Add instance(s) of the weekday within the period */ do { @@ -2671,15 +2674,37 @@ static int expand_year_days(icalrecur_iterator *impl, int year) } } else { /* Numeric BYDAY are within the year */ + short doy_offset = 0, last_day; + + if (has_by_data(impl, BY_WEEK_NO)) { + int weekno; + + /* See which week contains Jan 1 */ + (void)__icaltime_from_day_of_year(impl, 1, year, &weekno); + if (weekno > 1) { + /* Jan 1 is in last week of previous year - jump ahead */ + doy_offset += 7; + } - /* Get day of week of first day of year */ - (void)get_day_of_year(impl, year, 1, 1, &first_dow); + /* Set start and end of ISO week-numbering year */ + doy_offset += get_start_of_week(impl) - 1; + last_day = (7 * weeks_in_year(year)); - /* Get day of week of last day of year */ - set_day_of_year(impl, days_in_year); - last_dow = get_day_of_week(impl); + first_dow = impl->rule.week_start; + last_dow = (first_dow + 6) % 7; + } + else { + /* Get day of week of first day of year */ + (void)get_day_of_year(impl, year, 1, 1, &first_dow); + + /* Get day of week of last day of year */ + set_day_of_year(impl, days_in_year); + last_dow = get_day_of_week(impl); + + last_day = days_in_year; + } - set_pos_total += expand_by_day(impl, year, 0, days_in_year, + set_pos_total += expand_by_day(impl, year, doy_offset, last_day, first_dow, last_dow, limiting); } } diff --git a/src/test/icalrecur_test.c b/src/test/icalrecur_test.c index 7043cb3d..06c4078a 100644 --- a/src/test/icalrecur_test.c +++ b/src/test/icalrecur_test.c @@ -390,6 +390,16 @@ const struct recur rfc5545[] = { "FREQ=WEEKLY;BYDAY=WE,FR;INTERVAL=2;COUNT=4", NULL}, + /* First 2 and last 2 ISO weeks of the year on Tue */ + {"20130101T000000", + "FREQ=YEARLY;BYWEEKNO=1,2,-1,-2;BYDAY=TU;UNTIL=20170101T000000Z", + NULL}, + + /* 53rd ISO week of the year on Tue and Sat */ + {"20130101T000000", + "FREQ=YEARLY;BYWEEKNO=53;BYDAY=TU,SA;UNTIL=20170101T000000Z", + NULL}, + {NULL, NULL, NULL} }; diff --git a/src/test/icalrecur_test.out b/src/test/icalrecur_test.out index c08a19eb..4e3d03bc 100644 --- a/src/test/icalrecur_test.out +++ b/src/test/icalrecur_test.out @@ -272,3 +272,11 @@ INSTANCES:20130512T000000,20260512T000000,20390512T000000 RRULE:FREQ=WEEKLY;BYDAY=WE,FR;INTERVAL=2;COUNT=4 DTSTART:20190101T100000 INSTANCES:20190102T100000,20190104T100000,20190116T100000,20190118T100000 + +RRULE:FREQ=YEARLY;BYWEEKNO=1,2,-1,-2;BYDAY=TU;UNTIL=20170101T000000Z +DTSTART:20130101T000000 +INSTANCES:20130101T000000,20130108T000000,20131217T000000,20131224T000000,20131231T000000,20140107T000000,20141216T000000,20141223T000000,20141230T000000,20150106T000000,20151222T000000,20151229T000000,20160105T000000,20160112T000000,20161220T000000,20161227T000000 + +RRULE:FREQ=YEARLY;BYWEEKNO=53;BYDAY=TU,SA;UNTIL=20170101T000000Z +DTSTART:20130101T000000 +INSTANCES:20151229T000000,20160102T000000 |