I'm working on a leave application. I need to get the excluded dates and convert it into a dateTime array.
I used the following approach to partially achieve this. I created a Helper folder then added the following class to the folder:
namespace eLeave.Helpers
{
public class BusinessDaysCalculator
{
public int Calculate(DateTime startDate, DateTime endDate, DateTime[] holidays)
{
startDate = FixStartDate(startDate);
endDate = FixEndDate(endDate.Date);
if (startDate > endDate)
return 0;
else
return CalculateDifference(startDate, endDate, holidays);
}
private int CalculateDifference(DateTime startDate, DateTime endDate, DateTime[] holidays)
{
int difference = (int)(endDate - startDate).TotalDays;
int weeks = difference / 7;
if (endDate.DayOfWeek < startDate.DayOfWeek) weeks++;
difference -= weeks * 2;
difference -= HolidayCount(startDate, endDate, holidays);
return difference + 1;
}
private int HolidayCount(DateTime startDate, DateTime endDate, DateTime[] holidays)
{
int holidayCount = 0;
foreach (DateTime holiday in holidays)
{
if (HolidayInRange(startDate, endDate, holiday))
holidayCount++;
}
return holidayCount;
}
private DateTime FixStartDate(DateTime date)
{
if (date.DayOfWeek == DayOfWeek.Sunday)
date = date.AddDays(1);
else if (date.DayOfWeek == DayOfWeek.Saturday)
date = date.AddDays(2);
return date.Date;
}
private bool HolidayInRange(DateTime startDate, DateTime endDate, DateTime holiday)
{
return (holiday >= startDate
&& holiday <= endDate
&& holiday.DayOfWeek != DayOfWeek.Saturday
&& holiday.DayOfWeek != DayOfWeek.Sunday);
}
private DateTime FixEndDate(DateTime date)
{
if (date.DayOfWeek == DayOfWeek.Sunday)
date = date.AddDays(-2);
else if (date.DayOfWeek == DayOfWeek.Saturday)
date = date.AddDays(-1);
return date.Date;
}
}
}
I instantiated the class like below and passed the excludedDate
into it like below:
// Get the Excluded dates
var excludedDates = _context.ExcludedDate.Where(d=>d.ExcludedDates >= StartDate).Where(d=>d.ExcludedDates <= EndDate).ToArray();
BusinessDaysCalculator calc = new BusinessDaysCalculator();
int days = calc.Calculate(StartDate, EndDate, excludedDates);
The implementation was meant to work but gave errors but when tried with the holidays
DateTime Arrray below
DateTime[] holidays = new DateTime[3];
holidays[0] = new DateTime(2017, 08, 15);
holidays[1] = new DateTime(2017, 09, 1);
I got the leave days with the excluded date in the holiday
Array above
I need to get the values of excludedDates and use it with my class to get it to work.
The Errors I got here below:
Error 1 The best overloaded method match for 'eLeave.Helpers.BusinessDaysCalculator.Calculate(System.DateTime, System.DateTime, System.DateTime[])' has some invalid arguments C:\Apps\WebApplications\eLeave\eLeave\eLeave\Controllers\RequestController.cs 100 32 eLeave
Error 2 Argument 3: cannot convert from 'eLeave.Models.ExcludedDate[]' to 'System.DateTime[]' C:\Apps\WebApplications\eLeave\eLeave\eLeave\Controllers\RequestController.cs 100 67 eLeave
Model for excluded date are as follows:
public class ExcludedDate
{
public byte Id { get; set; }
public DateTime? ExcludedDates { get; set; }
}
Your query is returning an array of your ExcludedDate
class which is not type DateTime
- you need a .Select()
clause to select just the ExcludedDates
property of the object.
Change the query to
DateTime[] excludedDates = _context.ExcludedDate
.Where(d=>d.ExcludedDates >= StartDate && d.ExcludedDates <= EndDate)
.Select(x => x.ExcludedDates)
.ToArray();
Note its unclear why your property is nullable (there would be no point having a null
value for that property, and the name is a little confusing in relationship to the table name. I would suggest you change it to public DateTime Date { get; set; }