|  | using System; | 
|  | using System.Collections.Generic; | 
|  | using System.Linq; | 
|  | using System.Text; | 
|  | using OfficeOpenXml.FormulaParsing.ExpressionGraph; | 
|  | using OfficeOpenXml.Utils; | 
|  |  | 
|  | namespace OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime | 
|  | { | 
|  | 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; | 
|  | } | 
|  | } | 
|  | } |