commit
message
[WORKDAY] work-in-progress on formula and tests, adding TODO for NETWORKDAYS$INTL
author
Ben Vogt <[email protected]>
date
2017-04-29 01:10:22
stats
4 file(s) changed,
69 insertions(+),
19 deletions(-)
files
src/Cell.ts
src/RawFormulas/Date.ts
src/RawFormulas/RawFormulas.ts
tests/DateFormulasTest.ts
1diff --git a/src/Cell.ts b/src/Cell.ts
2index 4de3544..92baf9c 100644
3--- a/src/Cell.ts
4+++ b/src/Cell.ts
5@@ -121,21 +121,9 @@ class Cell {
6 return this.error;
7 }
8
9- /**
10- * Get the renderable value for this cell, meaning the value that is the most meaningful to the user. If the error is
11- * null, we return the error. If we don't have an error, return the value.
12- * @returns {string} renderable string value to return.
13- */
14- getRenderedValue() : string {
15- if (this.error !== null) {
16- return this.value;
17- }
18- return this.error;
19- }
20-
21 /**
22 * Returns the human-readable string representation of this cell, omitting some obvious fields.
23- * @returns {string} to return
24+ * @returns {string}
25 */
26 toString() : string {
27 return "id=" + this.id + ", value=" + this.value + ", formula=" + this.formula + ", error=" + this.error;
28diff --git a/src/RawFormulas/Date.ts b/src/RawFormulas/Date.ts
29index 568c76d..463f08c 100644
30--- a/src/RawFormulas/Date.ts
31+++ b/src/RawFormulas/Date.ts
32@@ -725,7 +725,9 @@ var NETWORKDAYS$INTL = function (...values) : number {
33 + "' cannot be coerced to a number.")
34 }
35 } else {
36- weekendDays = [1, 6];
37+ // TODO: This had the wrong number of default weekend values and was still passing. Add a test that fails with
38+ // TODO: weekendDays = [1, 6] but not with [2, 6].
39+ weekendDays = [0, 6];
40 }
41 var hasHolidays = values.length === 4;
42 var holidays = [];
43@@ -815,9 +817,56 @@ var TIME = function (...values) : ExcelTime {
44 };
45
46
47+/**
48+ * Calculates the end date after a specified number of working days.
49+ * @param values[0] start_date - The date from which to begin counting.
50+ * @param values[1] num_days - The number of working days to advance from start_date. If negative, counts backwards. If
51+ * not an integer, truncate.
52+ * @param values[2] holidays - [ OPTIONAL ] - A range or array constant containing the dates to consider holidays. The
53+ * values provided within an array for holidays must be date serial number values, as returned by N or date values, as
54+ * returned by DATE, DATEVALUE or TO_DATE. Values specified by a range should be standard date values or date serial
55+ * numbers.
56+ * @returns {ExcelDate} end date after a specified number of working days.
57+ * @constructor
58+ */
59+var WORKDAY = function (...values) {
60+ ArgsChecker.checkLengthWithin(values, 2, 3);
61+ var start = TypeCaster.firstValueAsExcelDate(values[0], true);
62+ var days = TypeCaster.firstValueAsNumber(values[1]);
63+ var hasHolidays = values.length === 3;
64+ var holidays = [];
65+ if (hasHolidays) {
66+ if (values[2].length === 0) {
67+ throw new RefError("Reference does not exist.");
68+ }
69+ for (var holidayDateValue of values[2]) {
70+ if (holidayDateValue instanceof ExcelDate) {
71+ holidays.push(holidayDateValue.toNumber());
72+ } else if (typeof holidayDateValue === "number") {
73+ holidays.push(holidayDateValue);
74+ } else {
75+ throw new ValueError("WORKDAY expects number values. But '" + holidayDateValue + "' is a " +
76+ (typeof holidayDateValue) + " and cannot be coerced to a number.")
77+ }
78+ }
79+ }
80+
81+ var weekend_days = [0, 6];
82+ var cd = moment.utc(start.toMoment());
83+ var j = 0;
84+ while (j < days) {
85+ cd.add(1, 'days');
86+ if (weekend_days.indexOf(cd.day()) < 0 && holidays.indexOf(new ExcelDate(cd).toNumber()) < 0) {
87+ j++;
88+ }
89+ }
90+ return new ExcelDate(cd);
91+};
92+
93+
94+
95 // Functions unimplemented.
96 var WORKDAY$INTL;
97-var WORKDAY;
98
99 export {
100 DATE,
101@@ -841,5 +890,6 @@ export {
102 NETWORKDAYS$INTL,
103 NOW,
104 TODAY,
105- TIME
106+ TIME,
107+ WORKDAY
108 }
109\ No newline at end of file
110diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
111index f2a7682..af7c60e 100644
112--- a/src/RawFormulas/RawFormulas.ts
113+++ b/src/RawFormulas/RawFormulas.ts
114@@ -130,7 +130,8 @@ import {
115 NETWORKDAYS$INTL,
116 NOW,
117 TODAY,
118- TIME
119+ TIME,
120+ WORKDAY
121 } from "./Date"
122
123 var ACCRINT = Formula["ACCRINT"];
124@@ -264,5 +265,6 @@ export {
125 NETWORKDAYS$INTL,
126 NOW,
127 TODAY,
128- TIME
129+ TIME,
130+ WORKDAY
131 }
132\ No newline at end of file
133diff --git a/tests/DateFormulasTest.ts b/tests/DateFormulasTest.ts
134index 443accc..ea33e4a 100644
135--- a/tests/DateFormulasTest.ts
136+++ b/tests/DateFormulasTest.ts
137@@ -19,7 +19,8 @@ import {
138 SECOND,
139 NETWORKDAYS,
140 NETWORKDAYS$INTL,
141- TIME
142+ TIME,
143+ WORKDAY
144 } from "../src/RawFormulas/RawFormulas"
145 import * as ERRORS from "../src/Errors"
146 import {
147@@ -28,6 +29,13 @@ import {
148 } from "./utils/Asserts"
149 import moment = require("moment");
150
151+
152+// Test WORKDAY
153+assertEquals(WORKDAY(DATE(1999, 2, 2), 10), DATE(1999, 2, 16));
154+assertEquals(WORKDAY(DATE(1999, 10, 10), 100), DATE(2000, 2, 25));
155+
156+
157+
158 // Test TIME
159 assertEquals(TIME(10, 10, 10).toNumber(), 0.4237268518518518);
160 assertEquals(TIME(34, 10, 10).toNumber(), 0.4237268518518518);