@@ -395,7 +395,7 @@ private List<DateTime> GetWeekNoVariants(List<DateTime> dates, RecurrencePattern
395
395
var weekNoDates = new List < DateTime > ( ) ;
396
396
foreach ( var t in dates )
397
397
{
398
- foreach ( var weekNo in pattern . ByWeekNo )
398
+ foreach ( var weekNo in GetByWeekNoForYearNormalized ( pattern , t . Year ) )
399
399
{
400
400
var date = t ;
401
401
// Determine our current week number
@@ -429,6 +429,17 @@ private List<DateTime> GetWeekNoVariants(List<DateTime> dates, RecurrencePattern
429
429
return weekNoDates ;
430
430
}
431
431
432
+ /// <summary>
433
+ /// Normalize the BYWEEKNO values to be positive integers.
434
+ /// </summary>
435
+ private List < int > GetByWeekNoForYearNormalized ( RecurrencePattern pattern , int year )
436
+ {
437
+ var weeksInYear = new Lazy < int > ( ( ) => Calendar . GetIso8601WeeksInYear ( year , pattern . FirstDayOfWeek ) ) ;
438
+ return pattern . ByWeekNo
439
+ . Select ( weekNo => weekNo >= 0 ? weekNo : weeksInYear . Value + weekNo + 1 )
440
+ . ToList ( ) ;
441
+ }
442
+
432
443
/// <summary>
433
444
/// Applies BYYEARDAY rules specified in this Recur instance to the specified date list.
434
445
/// If no BYYEARDAY rules are specified, the date list is returned unmodified.
@@ -641,13 +652,14 @@ private List<DateTime> GetAbsWeekDays(DateTime date, WeekDay weekDay, Recurrence
641
652
642
653
var nextWeekNo = Calendar . GetIso8601WeekOfYear ( date , pattern . FirstDayOfWeek ) ;
643
654
var currentWeekNo = Calendar . GetIso8601WeekOfYear ( date , pattern . FirstDayOfWeek ) ;
655
+ var byWeekNoNormalized = GetByWeekNoForYearNormalized ( pattern , Calendar . GetIso8601YearOfWeek ( date , pattern . FirstDayOfWeek ) ) ;
644
656
645
657
//When we manage weekly recurring pattern and we have boundary case:
646
658
//Weekdays: Dec 31, Jan 1, Feb 1, Mar 1, Apr 1, May 1, June 1, Dec 31 - It's the 53th week of the year, but all another are 1st week number.
647
659
//So we need an EXRULE for this situation, but only for weekly events
648
660
while ( currentWeekNo == weekNo || ( nextWeekNo < weekNo && currentWeekNo == nextWeekNo && pattern . Frequency == FrequencyType . Weekly ) )
649
661
{
650
- if ( ( pattern . ByWeekNo . Count == 0 || pattern . ByWeekNo . Contains ( currentWeekNo ) )
662
+ if ( ( byWeekNoNormalized . Count == 0 || byWeekNoNormalized . Contains ( currentWeekNo ) )
651
663
&& ( pattern . ByMonth . Count == 0 || pattern . ByMonth . Contains ( date . Month ) ) )
652
664
{
653
665
days . Add ( date ) ;
@@ -668,11 +680,12 @@ private List<DateTime> GetAbsWeekDays(DateTime date, WeekDay weekDay, Recurrence
668
680
date = date . AddDays ( 1 ) ;
669
681
}
670
682
683
+ var byWeekNoNormalized = GetByWeekNoForYearNormalized ( pattern , Calendar . GetIso8601YearOfWeek ( date , pattern . FirstDayOfWeek ) ) ;
671
684
while ( date . Month == month )
672
685
{
673
686
var currentWeekNo = Calendar . GetIso8601WeekOfYear ( date , pattern . FirstDayOfWeek ) ;
674
687
675
- if ( ( pattern . ByWeekNo . Count == 0 || pattern . ByWeekNo . Contains ( currentWeekNo ) )
688
+ if ( ( byWeekNoNormalized . Count == 0 || byWeekNoNormalized . Contains ( currentWeekNo ) )
676
689
&& ( pattern . ByMonth . Count == 0 || pattern . ByMonth . Contains ( date . Month ) ) )
677
690
{
678
691
days . Add ( date ) ;
0 commit comments