diff --git a/v2/cal_business.go b/v2/cal_business.go index 504b9b5..12294b9 100644 --- a/v2/cal_business.go +++ b/v2/cal_business.go @@ -145,6 +145,25 @@ func (c *BusinessCalendar) WorkdaysInMonth(year int, month time.Month) int { return c.WorkdaysRemain(t) } +// HolidaysInRange reports the number of holidays between the start and end +// times (inclusive). +func (c *BusinessCalendar) HolidaysInRange(start, end time.Time) int { + factor := 1 + if end.Before(start) { + factor = -1 + start, end = end, start + } + result := 0 + to := DayStart(end) + for i := DayStart(start); i.Before(to) || i.Equal(to); i = i.AddDate(0, 0, 1) { + _, holiday, _ := c.IsHoliday(i) + if holiday { + result++ + } + } + return factor * result +} + // WorkdaysInRange reports the number of workdays between the start and end // times (inclusive). func (c *BusinessCalendar) WorkdaysInRange(start, end time.Time) int { diff --git a/v2/cal_business_test.go b/v2/cal_business_test.go index 59ce701..1255da9 100644 --- a/v2/cal_business_test.go +++ b/v2/cal_business_test.go @@ -242,6 +242,43 @@ func TestWorkdaysInRange(t *testing.T) { } } +func TestHolidaysInRange(t *testing.T) { + c := NewBusinessCalendar() + hol := &Holiday{ + Type: ObservancePublic, + Month: time.July, + Day: 4, + Observed: []AltDay{ + {Day: time.Saturday, Offset: -1}, + {Day: time.Sunday, Offset: 1}, + }, + Func: CalcDayOfMonth, + } + c.AddHoliday(hol) + + tests := []struct { + f time.Time + t time.Time + want int + }{ + {d(2015, 4, 4), d(2015, 4, 5), 0}, + {d(2015, 7, 1), d(2015, 7, 6), 1}, + } + + for _, test := range tests { + got := c.HolidaysInRange(test.f, test.t) + if got != test.want { + t.Errorf("got: %d; want: %d (%s-%s)", got, test.want, test.f, test.t) + } + if !test.f.Equal(test.t) { + got = c.HolidaysInRange(test.t, test.f) + if got != -test.want { + t.Errorf("got: %d; want: %d (%s-%s)", got, -test.want, test.t, test.f) + } + } + } +} + func TestWorkdayN(t *testing.T) { c := NewBusinessCalendar() hol := &Holiday{