# Recurring Holidays - Exclude Holidays between two dates

Has anyone of you used recurring holidays and were you able to exclude holidays between two days using Holiday object? If I create a individual record for every holiday and year, I'm able to account the holidays and exclude them. The challenge is when they are set up as recurring, it just creates records for the elapsed holidays only and not for the upcoming ones in Holiday object.

You haven't given alot of detail on what you want to do, so I'm going to give a generic answer here.

First, whenever applicable, your best bet is probably to use business hours. From the documentation:`

The following example finds whether a given time is within the default business hours.

``````// Get the default business hours

// Create Datetime on May 28, 2013 at 1:06:08 AM in the local timezone.
Datetime targetTime = Datetime.newInstance(2013, 5, 28, 1, 6, 8);

// Find whether the time is within the default business hours
``````

So in most cases, you can probably just loop through these to get what you need.

However, if you need to get a list off all Holidays for a certain time period (like I did), you'll find that recurring Holidays make life very difficult.

First off, there are 6 types of recurring Holidays

1. RecursYearly - Like New Years or Christmas that happen on a specific date every year

2. RecursYearlyNth - Like Thanksgiving or Columbus day, that happen on something like the 3rd Monday of a Month

3. RecursMonthly - That occurs on a specific day every month
4. RecursMonthlyNth - That occurs on a X-th some-day every month (like 3rd Tuesday)
5. RecursWeekly - such as every tuesday
6. RecursDaily - reoccurs every X days from start day

Secondly, RecursYearlyNth and RecursMonthlyNth use a field called "RecurrenceDayOfWeekMask." So instead of using 1, 2, 3, 4, etc. for the days in the week (Sunday being 1, Monday being 2), it goes - 1, 2, 4, 8, 16, 32, 64. (Sunday being 1, Monday being 2, and so on)

After searching and not finding a solution from anyone else, this is what I came up with to get all Holidays between certain dates:

``````    public class HolidayUtil {
List<Integer> toReturn = new List<Integer>();
LIst<Integer> bits = new List<Integer>{64, 32, 16, 8, 4, 2, 1};

for (Integer bit : bits){
}
}
}
return new Map<Integer, Integer>{1 => 1, 2 => 2, 4 => 3, 8 => 4, 16 => 5, 32 => 6, 64 => 7};//1 =  1 - Sunday, 2 = 2 Monday, 4 = 3 Tuesday, /8 = 4 Wednesday, 16 = 5 Thursday, 32 = 6 Friday, 64 = 7 Saturday
}
public static Map<String, Integer> getMonthMap(){
return new Map<String, Integer>{'January' => 1, 'February' => 2, 'March' => 3, 'April' => 4, 'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8, 'September' => 9,
'October' => 10, 'November' => 11, 'December' => 12};
}
public static Map<String, Integer> getWeekMap(){return new Map<String, Integer>{'First' => 1, 'Second' => 2, 'Third' => 3, 'Fourth' => 4, 'Fifth' => 5};}

public static Map<Date, Holiday> getHolidaysForDates(Date startDate, date endDate){
Map<Date, Holiday> toReturn = new Map<Date, holiday>();
List<Date> dates = new List<Date>();
List<Holiday> holidays = [select id, name, ActivityDate, Description, EndTimeInMinutes, IsAllDay, IsRecurrence, RecurrenceDayOfMonth, RecurrenceDayOfWeekMask, RecurrenceEndDateOnly,
RecurrenceInstance, RecurrenceInterval, RecurrenceMonthOfYear, RecurrenceStartDate, RecurrenceType, StartTimeInMinutes FROM Holiday
WHERE IsRecurrence = true OR ActivityDate = THIS_YEAR];

for (Holiday h : holidays){
if (h.RecurrenceType == 'RecursYearlyNth')
dates = getYearlyNthHoliday(h, startDate, endDate);
else if (h.RecurrenceType == 'RecursYearly')
dates = getYearlyHoliday(h, startDate, endDate);
else if (h.RecurrenceType == 'RecursMonthlyNth')
dates = getMonthlyNthHoliday(h, startDate, endDate);
else if (h.RecurrenceType == 'RecursMonthly')
dates = getMonthlyHoliday(h, startDate, endDate);
else if (h.RecurrenceType == 'RecursWeekly')
dates = getWeeklyHoliday(h, startDate, endDate);
else if (h.RecurrenceType == 'RecursDaily')
dates = getDailyHoliday(h, startDate, endDate);
for (Date d : dates)
toReturn.put(d, h);
}
}

public static List<Date> getYearlyHoliday(Holiday h, date startDate, date endDate){//recurs on set days in a year, like Christmas, New Years
List<Date> toReturn = new List<Date>();
Map<String, Integer> monthMap = getMonthMap();
for (Integer year : getYears(startDate, EndDate)){
Integer month = monthMap.get(h.RecurrenceMonthOfYear);
Date d = date.newInstance(year, month, h.RecurrenceDayOfMonth);
if (d > startDate && d < endDate)
}
}

public static List<Date> getYearlyNthHoliday(Holiday h, date startDate, date endDate){//recurs on something like 2nd tuesday of march - Thanksgiving, MLK day, Columbus Day
List<Date> toReturn = new List<Date>();

Map<String, Integer> monthMap = getMonthMap();
Map<String, Integer> weekMap = getWeekMap();

Integer month = monthMap.get(h.RecurrenceMonthOfYear);
for (Integer year : getYears(startDate, EndDate)){
Date d;
if (h.RecurrenceInstance == 'Last')
d = getLastXOfMonth(day, month, year);
else{
Integer week = weekMap.get(h.RecurrenceInstance);
d = getXDayOfMonth(week, day, date.newInstance(year, month, 2));
}
if (d > startDate && d < endDate)
}
}

public static List<Date> getMonthlyHoliday(Holiday h, date startDate, date endDate){//recurs on set day of every month - something like 5th of every month
List<Date> toReturn = new List<Date>();
for (Date d : getMonths(startDate, endDate)){
Date da = date.newInstance(d.year(), d.month(), h.RecurrenceDayOfMonth);
if (da > startDate && da < endDate)
}
}
public static List<Date> getMonthlyNthHoliday(Holiday h, date startDate, date endDate){//recurs monthly - something like every second sunday
List<Date> toReturn = new List<Date>();

List<Date> months = getMonths(startDate, endDate);

Integer week = getWeekMap().get(h.RecurrenceInstance);
for (date month : months){
Date d;
if (h.RecurrenceInstance == 'Last')
d = getLastXOfMonth(day, month.month(), month.year());
else
d = getXDayOfMonth(week, day, date.newInstance(month.year(), month.month(), 1));
if (d > startDate && d < endDate)
}
}
public static List<Date> getWeeklyHoliday(Holiday h, date startDate, date endDate){//something like every sat, sun or tues
List<Date> toReturn = new List<Date>();
Map<String, Integer> wMap = createDayOfWeekMap();
DateTime d = datetime.newInstance(startDate.year(), startdate.month(), startDate.day(), 0, 0, 0);//valueOf(startDate);
while (wMap.get(d.format('EEEE')) != day)
while (d < endDate){
if (d > startDate && d < endDate)
}
}
public static List<Date> getDailyHoliday(Holiday h, date startDate, date endDate){//something like every 15 days from start
List<Date> toReturn = new List<Date>();
Integer remainder;

while (remainder != 0){
remainder = math.mod(h.RecurrenceStartDate.daysBetween(dailyDate), h.RecurrenceInterval);
}
while (dailyDate < endDate){
if (dailyDate > startDate && dailyDate < endDate)
}
}

public static Date getLastXOfMonth(Integer dayOfWeek, Integer month, Integer year){
Map<String, Integer> DayOfWeekMap = createDayofWeekMap();
DateTime lastMonthDate = DateTime.newInstance(year, month + 1, 0, 0, 0, 0);
Integer day = DayOfWeekMap.get(lastMonthDate.format('EEEE'));

while(day != dayOfWeek){
day = DayOfWeekMap.get(lastMonthDate.format('EEEE'));
}
return Date.valueOf(lastMonthDate);
}

public static Date getXDayOfMonth(Integer week, Integer day, date monthIn){
Map<String, Integer> DayOfWeekMap = createDayofWeekMap();
DateTime firstMonthDate = DateTime.newInstance(monthIn.year(), monthIn.month(), 0, 0, 0, 0);

Integer dayName;
while(dayName != day){
dayName = DayOfWeekMap.get(firstMonthDate.format('EEEE'));
}
if (week == 1)
return date.valueOf(firstMonthDate);
else
return date.valueOf(firstMonthDate.addDays(7 * (week - 1)));
}

public static Map<String, Integer> createDayOfWeekMap(){
return new Map<String, Integer>{'Sunday' => 1, 'Monday' => 2, 'Tuesday' => 3, 'Wednesday' => 4, 'Thursday' => 5, 'Friday' => 6, 'Saturday' => 7};
}
public static List<Date> getMonths(Date startDate, Date endDate){
List<Date> months = new List<Date>();
Date m = date.newInstance(startDate.year(), startDate.month(), 1);
if (startDate.month() != endDate.month() || startDate.year() != endDate.year()){
while (m.monthsBetween(endDate) != 0){
}
}
return months;
}

public static List<Integer> getYears(date startDate, date endDate){
List<Integer> years = new List<Integer>();
Integer y = startDate.year();
if (startDate.year() != endDate.year()){
while (y != endDate.year()){
y = y + 1;
}
}
return years;
}

}
``````