| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| namespace AppsheetEpplus; | |
| public class Workday : ExcelFunction { | |
| public override CompileResult Execute( | |
| IEnumerable<FunctionArgument> arguments, | |
| ParsingContext context) { | |
| ValidateArguments(arguments, 2); | |
| var startDate = System.DateTime.FromOADate(ArgToInt(arguments, 0)); | |
| var nWorkDays = ArgToInt(arguments, 1); | |
| var resultDate = System.DateTime.MinValue; | |
| var workdaysCounted = 0; | |
| var tmpDate = startDate; | |
| // first move forward to the first monday | |
| while (tmpDate.DayOfWeek != DayOfWeek.Monday && (nWorkDays - workdaysCounted) > 0) { | |
| if (!IsHoliday(tmpDate)) { | |
| workdaysCounted++; | |
| } | |
| tmpDate = tmpDate.AddDays(1); | |
| } | |
| // then calculate whole weeks | |
| var nWholeWeeks = (nWorkDays - workdaysCounted) / 5; | |
| tmpDate = tmpDate.AddDays(nWholeWeeks * 7); | |
| workdaysCounted += nWholeWeeks * 5; | |
| // calculate the rest | |
| while (workdaysCounted < nWorkDays) { | |
| tmpDate = tmpDate.AddDays(1); | |
| if (!IsHoliday(tmpDate)) { | |
| workdaysCounted++; | |
| } | |
| } | |
| resultDate = AdjustResultWithHolidays(tmpDate, arguments); | |
| return CreateResult(resultDate.ToOADate(), DataType.Date); | |
| } | |
| private System.DateTime AdjustResultWithHolidays( | |
| System.DateTime resultDate, | |
| IEnumerable<FunctionArgument> arguments) { | |
| if (arguments.Count() == 2) { | |
| return resultDate; | |
| } | |
| var holidays = arguments.ElementAt(2).Value as IEnumerable<FunctionArgument>; | |
| if (holidays != null) { | |
| foreach (var arg in holidays) { | |
| if (ConvertUtil.IsNumeric(arg.Value)) { | |
| var dateSerial = ConvertUtil.GetValueDouble(arg.Value); | |
| var holidayDate = System.DateTime.FromOADate(dateSerial); | |
| if (!IsHoliday(holidayDate)) { | |
| resultDate = resultDate.AddDays(1); | |
| } | |
| } | |
| } | |
| } else { | |
| var range = arguments.ElementAt(2).Value as ExcelDataProvider.IRangeInfo; | |
| if (range != null) { | |
| foreach (var cell in range) { | |
| if (ConvertUtil.IsNumeric(cell.Value)) { | |
| var dateSerial = ConvertUtil.GetValueDouble(cell.Value); | |
| var holidayDate = System.DateTime.FromOADate(dateSerial); | |
| if (!IsHoliday(holidayDate)) { | |
| resultDate = resultDate.AddDays(1); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return resultDate; | |
| } | |
| private bool IsHoliday(System.DateTime date) { | |
| return date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday; | |
| } | |
| } |