aboutsummaryrefslogtreecommitdiffstats
path: root/poi
diff options
context:
space:
mode:
authorPJ Fanning <fanningpj@apache.org>2022-02-11 00:12:51 +0000
committerPJ Fanning <fanningpj@apache.org>2022-02-11 00:12:51 +0000
commit1e85583580d014ba44e6debe4f92f84346d6e59e (patch)
tree8bd74b351dff0164d58d3b8f07ab4fddf107c3de /poi
parent9c55c8d45663c4c45482c9f1e98ea369be583e5d (diff)
downloadpoi-1e85583580d014ba44e6debe4f92f84346d6e59e.tar.gz
poi-1e85583580d014ba44e6debe4f92f84346d6e59e.zip
[bug-65879] add WORKDAY.INTL function
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1897953 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poi')
-rw-r--r--poi/src/main/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java1
-rw-r--r--poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java4
-rw-r--r--poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java4
-rw-r--r--poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java86
4 files changed, 93 insertions, 2 deletions
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java b/poi/src/main/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
index 5dcb5720dd..eaaf184576 100644
--- a/poi/src/main/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
+++ b/poi/src/main/java/org/apache/poi/ss/formula/atp/AnalysisToolPak.java
@@ -184,6 +184,7 @@ public final class AnalysisToolPak implements UDFFinder {
r(m, "TEXTJOIN", TextJoinFunction.instance);
r(m, "WEEKNUM", WeekNum.instance);
r(m, "WORKDAY", WorkdayFunction.instance);
+ r(m, "WORKDAY.INTL", WorkdayIntlFunction.instance);
r(m, "XIRR", null);
r(m, "XLOOKUP", XLookupFunction.instance);
r(m, "XMATCH", XMatchFunction.instance);
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
index a0aa551f9b..c9cdcb2853 100644
--- a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
+++ b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
@@ -89,6 +89,10 @@ public class WorkdayCalculator {
// enforcing singleton
}
+ public Set<Integer> getValidWeekendTypes() {
+ return weekendTypeMap.keySet();
+ }
+
/**
* Calculate how many workdays are there between a start and an end date, as excel representations, considering a range of holidays.
*
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java
index 83cba23259..3793bd7d36 100644
--- a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java
+++ b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayFunction.java
@@ -46,8 +46,8 @@ final class WorkdayFunction implements FreeRefFunction {
}
/**
- * Evaluate for WORKDAY. Given a date, a number of days and a optional date or interval of holidays, determines which date it is past
- * number of parametrized workdays.
+ * Evaluate for WORKDAY. Given a date, a number of days and an optional date or interval of holidays, determines which date it is past
+ * number of parameterized workdays.
*
* @return {@link ValueEval} with date as its value.
*/
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java
new file mode 100644
index 0000000000..5a5ab7023b
--- /dev/null
+++ b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java
@@ -0,0 +1,86 @@
+/* ====================================================================
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.formula.atp;
+
+import org.apache.poi.ss.formula.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.EvaluationException;
+import org.apache.poi.ss.formula.eval.NumberEval;
+import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.functions.FreeRefFunction;
+import org.apache.poi.ss.usermodel.DateUtil;
+
+/**
+ * Implementation of Excel 'Analysis ToolPak' function WORKDAY.INTL()<br>
+ * Returns the date past a number of workdays beginning at a start date, considering an interval of holidays. A workday is any non
+ * saturday/sunday date.
+ * <p>
+ * <b>Syntax</b><br>
+ * <b>WORKDAY</b>(<b>startDate</b>, <b>days</b>, weekendType, holidays)
+ * <p>
+ * https://support.microsoft.com/en-us/office/workday-intl-function-a378391c-9ba7-4678-8a39-39611a9bf81d
+ */
+final class WorkdayIntlFunction implements FreeRefFunction {
+
+ public static final FreeRefFunction instance = new WorkdayIntlFunction(ArgumentsEvaluator.instance);
+
+ private ArgumentsEvaluator evaluator;
+
+ private WorkdayIntlFunction(ArgumentsEvaluator anEvaluator) {
+ // enforces singleton
+ this.evaluator = anEvaluator;
+ }
+
+ /**
+ * Evaluate for WORKDAY.INTL. Given a date, a number of days, an optional weekend type
+ * and an optional date or interval of holidays, determines which date it is past
+ * number of parameterized workdays.
+ *
+ * @return {@link ValueEval} with date as its value.
+ */
+ public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
+ if (args.length < 2 || args.length > 4) {
+ return ErrorEval.VALUE_INVALID;
+ }
+
+ int srcCellRow = ec.getRowIndex();
+ int srcCellCol = ec.getColumnIndex();
+
+ double start;
+ int days;
+ int weekendType = 1;
+ double[] holidays;
+ try {
+ start = this.evaluator.evaluateDateArg(args[0], srcCellRow, srcCellCol);
+ days = (int) Math.floor(this.evaluator.evaluateNumberArg(args[1], srcCellRow, srcCellCol));
+ if (args.length >= 3) {
+ weekendType = (int) this.evaluator.evaluateNumberArg(args[2], srcCellRow, srcCellCol);
+ if (!WorkdayCalculator.instance.getValidWeekendTypes().contains(weekendType)) {
+ return ErrorEval.NUM_ERROR;
+ }
+ }
+ ValueEval holidaysCell = args.length >= 4 ? args[3] : null;
+ holidays = this.evaluator.evaluateDatesArg(holidaysCell, srcCellRow, srcCellCol);
+ return new NumberEval(DateUtil.getExcelDate(
+ WorkdayCalculator.instance.calculateWorkdays(start, days, weekendType, holidays)));
+ } catch (EvaluationException e) {
+ return ErrorEval.VALUE_INVALID;
+ }
+ }
+
+}