commit
message
[DATEDIF] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-04-15 18:33:53
stats
3 file(s) changed,
157 insertions(+),
24 deletions(-)
files
src/RawFormulas/Date.ts
src/RawFormulas/RawFormulas.ts
tests/DateFormulasTest.ts
1diff --git a/src/RawFormulas/Date.ts b/src/RawFormulas/Date.ts
2index 988f4c0..fdfff34 100644
3--- a/src/RawFormulas/Date.ts
4+++ b/src/RawFormulas/Date.ts
5@@ -362,9 +362,79 @@ var WEEKNUM = function (...values) {
6 };
7
8
9+/**
10+ * Calculates the number of days, months, or years between two dates.
11+ * @param values[0] start_date - The start date to consider in the calculation. Must be a reference to a cell containing
12+ * a DATE, a function returning a DATE type, or a number.
13+ * @param values[1] end_date - The end date to consider in the calculation. Must be a reference to a cell containing a
14+ * DATE, a function returning a DATE type, or a number.
15+ * @param values[2] unit - A text abbreviation for unit of time. For example,"M" for month. Accepted values are "Y": the
16+ * number of whole years between start_date and end_date, "M": the number of whole months between start_date and
17+ * end_date, "D": the number of days between start_date and end_date, "MD": the number of days between start_date and
18+ * end_date after subtracting whole months, "YM": the number of whole months between start_date and end_date after
19+ * subtracting whole years, "YD": the number of days between start_date and end_date, assuming start_date and end_date
20+ * were no more than one year apart.
21+ * @returns {number} number of days, months, or years between two dates.
22+ * @constructor
23+ */
24+var DATEDIF = function (...values) {
25+ ArgsChecker.checkLength(values, 3);
26+ var start = TypeCaster.firstValueAsExcelDate(values[0], true);
27+ var end = TypeCaster.firstValueAsExcelDate(values[1], true);
28+ var unit = TypeCaster.firstValueAsString(values[2]);
29+ var unitClean = unit.toUpperCase();
30+
31+ if (start.toNumber() > end.toNumber()) {
32+ throw new NumError("Function DATEDIF parameter 1 (" + start.toString() +
33+ ") should be on or before Function DATEDIF parameter 2 (" + end.toString() + ").");
34+ }
35+
36+ if (unitClean === "Y") {
37+ return Math.floor(end.toMoment().diff(start.toMoment(), "years"));
38+ } else if (unitClean === "M") {
39+ return Math.floor(end.toMoment().diff(start.toMoment(), "months"));
40+ } else if (unitClean === "D") {
41+ return end.toNumber() - start.toNumber();
42+ } else if (unitClean === "MD") {
43+ var s = start.toMoment();
44+ var e = end.toMoment();
45+ while(s.isBefore(e)) {
46+ s.add(1, "month");
47+ }
48+ s.subtract(1, "month");
49+ var days = e.diff(s, "days");
50+ return s.date() === e.date() ? 0 : days;
51+ } else if (unitClean === "YM") {
52+ var s = start.toMoment();
53+ var e = end.toMoment();
54+ while(s.isBefore(e)) {
55+ s.add(1, "year");
56+ }
57+ s.subtract(1, "year");
58+ var months = Math.floor(e.diff(s, "months"));
59+ return months === 12 ? 0 : months;
60+ } else if (unitClean === "YD") {
61+ // var s = start.toMoment();
62+ // var e = end.toMoment();
63+ // var days = e.diff(s, "days");
64+ // return days
65+ var s = start.toMoment();
66+ var e = end.toMoment();
67+ while(s.isBefore(e)) {
68+ s.add(1, "year");
69+ }
70+ s.subtract(1, "year");
71+ var days = Math.floor(e.diff(s, "days"));
72+ return days >= 365 ? 0 : days;
73+ } else {
74+ throw new NumError("Function DATEDIF parameter 3 value is " + unit +
75+ ". It should be one of: 'Y', 'M', 'D', 'MD', 'YM', 'YD'.");
76+ }
77+};
78+
79+
80 var YEARFRAC = Formula["YEARFRAC"];
81 // Functions unimplemented.
82-var DATEDIF;
83 var HOUR;
84 var MINUTE;
85 var NETWORKDAYS;
86@@ -382,6 +452,7 @@ var WORKDAY;
87 export {
88 DATE,
89 DATEVALUE,
90+ DATEDIF,
91 DAYS,
92 DAY,
93 DAYS360,
94diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
95index f884677..96491c0 100644
96--- a/src/RawFormulas/RawFormulas.ts
97+++ b/src/RawFormulas/RawFormulas.ts
98@@ -111,6 +111,7 @@ import {
99 import {
100 DATE,
101 DATEVALUE,
102+ DATEDIF,
103 DAYS,
104 DAY,
105 DAYS360,
106@@ -244,5 +245,6 @@ export {
107 MONTH,
108 YEAR,
109 WEEKDAY,
110- WEEKNUM
111+ WEEKNUM,
112+ DATEDIF
113 }
114\ No newline at end of file
115diff --git a/tests/DateFormulasTest.ts b/tests/DateFormulasTest.ts
116index 80d0056..15c8a05 100644
117--- a/tests/DateFormulasTest.ts
118+++ b/tests/DateFormulasTest.ts
119@@ -2,6 +2,7 @@
120 import {
121 DATE,
122 DATEVALUE,
123+ DATEDIF,
124 EDATE,
125 EOMONTH,
126 DAY,
127@@ -32,6 +33,84 @@ function catchAndAssertEquals(toExecute, expected) {
128 }
129
130
131+// Test DATEDIF
132+assertEquals(DATEDIF("1992-6-19", "1996-6-19", "Y"), 4);
133+assertEquals(DATEDIF("1992-6-19", "1996-6-0", "Y"), 3);
134+assertEquals(DATEDIF("1992-6-19", "1992-8-1", "Y"), 0);
135+assertEquals(DATEDIF("1992-6-19", "2199-8-1", "Y"), 207);
136+assertEquals(DATEDIF("1992-6-19", "1996-6-19", "M"), 48);
137+assertEquals(DATEDIF("1992-6-19", "1996-6-1", "M"), 47);
138+assertEquals(DATEDIF("1992-6-19", "1992-8-1", "M"), 1);
139+assertEquals(DATEDIF("1992-6-19", "2199-8-1", "M"), 2485);
140+assertEquals(DATEDIF("1992-6-19", "1996-6-19", "D"), 1461);
141+assertEquals(DATEDIF("1992-6-19", "1996-6-1", "D"), 1443);
142+assertEquals(DATEDIF("1992-6-19", "1992-8-1", "D"), 43);
143+assertEquals(DATEDIF("1992-6-19", "2199-8-1", "D"), 75648);
144+assertEquals(DATEDIF("1992-6-19", "2199-8-1", "MD"), 13);
145+assertEquals(DATEDIF("1992-6-19", "2012-7-22", "MD"), 3);
146+assertEquals(DATEDIF("1992-6-19", "1993-8-1", "MD"), 13);
147+assertEquals(DATEDIF("1992-6-19", "2000-1-19", "MD"), 0);
148+assertEquals(DATEDIF("1992-6-19", "2000-1-20", "MD"), 1);
149+assertEquals(DATEDIF("1992-6-19", "2000-1-21", "MD"), 2);
150+assertEquals(DATEDIF("1992-6-19", "2000-1-22", "MD"), 3);
151+assertEquals(DATEDIF("1992-6-19", "2000-1-23", "MD"), 4);
152+assertEquals(DATEDIF("1992-6-19", "2000-1-24", "MD"), 5);
153+assertEquals(DATEDIF("1992-6-19", "2000-1-25", "MD"), 6);
154+assertEquals(DATEDIF("1992-6-20", "2000-1-25", "MD"), 5);
155+assertEquals(DATEDIF("1992-6-19", "2199-8-1", "YM"), 1);
156+assertEquals(DATEDIF("1992-6-19", "2012-7-22", "YM"), 1);
157+assertEquals(DATEDIF("1992-6-19", "1993-8-1", "YM"), 1);
158+assertEquals(DATEDIF("1992-6-19", "2000-1-19", "YM"), 7);
159+assertEquals(DATEDIF("1992-6-19", "2000-1-20", "YM"), 7);
160+assertEquals(DATEDIF("1992-6-19", "2000-1-21", "YM"), 7);
161+assertEquals(DATEDIF("1992-6-19", "2000-1-22", "YM"), 7);
162+assertEquals(DATEDIF("1992-6-19", "2000-1-23", "YM"), 7);
163+assertEquals(DATEDIF("1992-6-19", "2000-1-24", "YM"), 7);
164+assertEquals(DATEDIF("1992-6-19", "2000-1-25", "YM"), 7);
165+assertEquals(DATEDIF("1992-6-20", "2000-1-25", "YM"), 7);
166+assertEquals(DATEDIF("1992-6-19", "1992-6-19", "YM"), 0);
167+assertEquals(DATEDIF("1992-6-19", "1992-7-19", "YM"), 1);
168+assertEquals(DATEDIF("1992-6-19", "1993-7-19", "YM"), 1);
169+assertEquals(DATEDIF("1992-6-19", "1993-6-19", "YM"), 0);
170+assertEquals(DATEDIF("1992-6-19", "2199-8-1", "YD"), 43);
171+assertEquals(DATEDIF("1992-6-19", "2012-7-22", "YD"), 33);
172+assertEquals(DATEDIF("1992-6-19", "1993-8-1", "YD"), 43);
173+assertEquals(DATEDIF("1992-6-19", "2000-1-19", "YD"), 214);
174+assertEquals(DATEDIF("1992-6-19", "2000-1-20", "YD"), 215);
175+assertEquals(DATEDIF("1992-6-19", "2000-1-21", "YD"), 216);
176+assertEquals(DATEDIF("1992-6-19", "2000-1-22", "YD"), 217);
177+assertEquals(DATEDIF("1992-6-19", "2000-1-23", "YD"), 218);
178+assertEquals(DATEDIF("1992-6-19", "2000-1-24", "YD"), 219);
179+assertEquals(DATEDIF("1992-6-19", "2000-1-25", "YD"), 220);
180+assertEquals(DATEDIF("1992-6-19", "1992-6-19", "YD"), 0);
181+assertEquals(DATEDIF("1992-6-19", "1992-7-19", "YD"), 30);
182+assertEquals(DATEDIF("1992-6-19", "1993-7-19", "YD"), 30);
183+assertEquals(DATEDIF("1992-6-19", "1993-6-19", "YD"), 0);
184+assertEquals(DATEDIF("1992-6-19", "1993-6-19", "yd"), 0);
185+assertEquals(DATEDIF(["1992-6-19", "str"], ["1993-6-19", []], ["yd"]), 0);
186+catchAndAssertEquals(function() {
187+ DATEDIF("1996-6-19", "1992-6-19", "Y");
188+}, ERRORS.NUM_ERROR);
189+catchAndAssertEquals(function() {
190+ DATEDIF("1992-6-19", "1995-6-19", "Y ");
191+}, ERRORS.NUM_ERROR);
192+catchAndAssertEquals(function() {
193+ DATEDIF("1992-6-19", "1995-6-19", "mm");
194+}, ERRORS.NUM_ERROR);
195+catchAndAssertEquals(function() {
196+ DATEDIF();
197+}, ERRORS.NA_ERROR);
198+catchAndAssertEquals(function() {
199+ DATEDIF("1992-6-19", "1995-6-19", "mm", 0);
200+}, ERRORS.NA_ERROR);
201+catchAndAssertEquals(function() {
202+ DATEDIF("str", "1995-6-19", "mm");
203+}, ERRORS.VALUE_ERROR);
204+catchAndAssertEquals(function() {
205+ DATEDIF([], "1995-6-19", "mm");
206+}, ERRORS.REF_ERROR);
207+
208+
209 // Test WEEKNUM
210 assertEquals(WEEKNUM(DATE(1992, 6, 19)), 25);
211 assertEquals(WEEKNUM(DATE(1992, 6, 20)), 25);
212@@ -576,29 +655,6 @@ catchAndAssertEquals(function() {
213 }, ERRORS.NUM_ERROR);
214
215
216-
217-
218-
219-
220-
221-
222-
223-
224-
225-
226-
227-
228-
229-
230-
231-
232-
233-
234-
235-
236-
237-
238-
239 // Test WEEKDAY
240 assertEquals(WEEKDAY(DATE(1992, 6, 20)), 7);
241 assertEquals(WEEKDAY(DATE(1992, 6, 21)), 1);