commit
message
[WIP:WEEKNUM] shifting weekdays based on shift-system
author
Ben Vogt <[email protected]>
date
2017-04-12 02:44:25
stats
2 file(s) changed,
203 insertions(+),
4 deletions(-)
files
src/RawFormulas/Date.ts
tests/DateFormulasTest.ts
1diff --git a/src/RawFormulas/Date.ts b/src/RawFormulas/Date.ts
2index 528f509..8ec43db 100644
3--- a/src/RawFormulas/Date.ts
4+++ b/src/RawFormulas/Date.ts
5@@ -257,20 +257,82 @@ var WEEKDAY = function (...values) {
6 };
7
8
9+/**
10+ * Returns a number representing the week of the year where the provided date falls. When inputting the date, it is best
11+ * to use the DATE function, as text values may return errors.
12+ *
13+ * Behind the scenes, there are two week numbering "systems" used for this function: System 1 - The first week of the
14+ * year is considered to be the week containing January 1, which is numbered week 1. System 2 - The first week of the
15+ * year is considered to be the week containing the first Thursday of the year, which is numbered as week 1. System 2 is
16+ * the approach specified in ISO 8601, also known as the European system for numbering weeks.
17+ *
18+ * @param values[0] date - The date for which to determine the week number. Must be a reference to a cell containing a
19+ * date, a function returning a date type, or a number.
20+ * @param values[1] type - [ OPTIONAL - default is 1 ] - A number representing the day that a week starts on as well as
21+ * the system used for determining the first week of the year (1=Sunday, 2=Monday).
22+ * @returns {number} representing week number of year.
23+ * @constructor
24+ */
25 var WEEKNUM = function (...values) {
26- ArgsChecker.checkLength(values, 1);
27+ ArgsChecker.checkLengthWithin(values, 1, 2);
28 var date = TypeCaster.firstValueAsExcelDate(values[0], true); // tell firstValueAsExcelDate to coerce boolean
29+ var shiftType = values.length === 2 ? TypeCaster.firstValueAsNumber(values[1]) : 1;
30 if (date.toNumber() < 0) {
31 throw new NumError("Function YEAR parameter 1 value is " + date.toNumber() + ". It should be greater than or equal to 0.");
32 }
33 var dm = date.toMoment();
34 var week = dm.week();
35- // If this weekYear is not the same as the year, then we're technically in "week-53"
36- // See https://momentjs.com/docs/#/get-set/week-year/ for more info.
37- if (dm.weekYear() !== dm.year()) {
38- return 53;
39+ var dayOfWeek = dm.day() + 1; // between 1 and 7, inclusively
40+ if (shiftType === 1) {
41+ // If this weekYear is not the same as the year, then we're technically in "week 53"
42+ // See https://momentjs.com/docs/#/get-set/week-year/ for more info.
43+ if (dm.weekYear() !== dm.year()) {
44+ week = 53;
45+ }
46+ return week;
47+ } else if (shiftType === 2 || shiftType === 11) {
48+ if (dm.weekYear() !== dm.year()) {
49+ week = 53;
50+ }
51+ if (dayOfWeek === 1) { // sunday shift back
52+ return week - 1;
53+ }
54+ return week;
55+ } else if (shiftType === 12) {
56+ if (dm.weekYear() !== dm.year()) {
57+ week = 53;
58+ }
59+ if (dayOfWeek <= 2) { // sunday, monday shift back
60+ return week - 1;
61+ }
62+ return week;
63+ } else if (shiftType === 13) {
64+ if (dm.weekYear() !== dm.year()) {
65+ week = 53;
66+ }
67+ if (dayOfWeek <= 3) { // sunday, monday, tuesday shift back
68+ return week - 1;
69+ }
70+ return week;
71+ } else if (shiftType === 14) {
72+ if (dm.weekYear() !== dm.year()) {
73+ week = 53;
74+ }
75+ if (dayOfWeek <= 4) { // sunday, monday, tuesday, wednesday shift back
76+ return week - 1;
77+ }
78+ return week;
79+ } else if (shiftType === 15) {
80+
81+ } else if (shiftType === 16) {
82+
83+ } else if (shiftType === 17) {
84+
85+ } else if (shiftType === 21) {
86+
87+ } else {
88+ throw new NumError("Function WEEKNUM parameter 2 value " + shiftType + " is out of range.");
89 }
90- return week;
91 };
92
93
94diff --git a/tests/DateFormulasTest.ts b/tests/DateFormulasTest.ts
95index 4e59172..78f7e03 100644
96--- a/tests/DateFormulasTest.ts
97+++ b/tests/DateFormulasTest.ts
98@@ -76,9 +76,134 @@ assertEquals(WEEKNUM(23749), 2);
99 assertEquals(WEEKNUM(23750), 2);
100 assertEquals(WEEKNUM(23751), 2);
101 assertEquals(WEEKNUM(23752), 3);
102-
103-
104-
105+// type=2
106+assertEquals(WEEKNUM(23737, 2), 52);
107+assertEquals(WEEKNUM(23738, 2), 52);
108+assertEquals(WEEKNUM(23739, 2), 53);
109+assertEquals(WEEKNUM(23740, 2), 53);
110+assertEquals(WEEKNUM(23741, 2), 53);
111+assertEquals(WEEKNUM(23742, 2), 53);
112+assertEquals(WEEKNUM(23743, 2), 1);
113+assertEquals(WEEKNUM(23744, 2), 1);
114+assertEquals(WEEKNUM(23745, 2), 1);
115+assertEquals(WEEKNUM(23746, 2), 2);
116+assertEquals(WEEKNUM(23747, 2), 2);
117+assertEquals(WEEKNUM(23748, 2), 2);
118+assertEquals(WEEKNUM(23749, 2), 2);
119+assertEquals(WEEKNUM(23750, 2), 2);
120+assertEquals(WEEKNUM(23751, 2), 2);
121+assertEquals(WEEKNUM(23752, 2), 2);
122+assertEquals(WEEKNUM(23753, 2), 3);
123+assertEquals(WEEKNUM(23754, 2), 3);
124+assertEquals(WEEKNUM(23755, 2), 3);
125+assertEquals(WEEKNUM(23756, 2), 3);
126+assertEquals(WEEKNUM(23757, 2), 3);
127+assertEquals(WEEKNUM(23758, 2), 3);
128+assertEquals(WEEKNUM(23759, 2), 3);
129+assertEquals(WEEKNUM(23760, 2), 4);
130+//type=11
131+assertEquals(WEEKNUM(23737, 11), 52);
132+assertEquals(WEEKNUM(23738, 11), 52);
133+assertEquals(WEEKNUM(23739, 11), 53);
134+assertEquals(WEEKNUM(23740, 11), 53);
135+assertEquals(WEEKNUM(23741, 11), 53);
136+assertEquals(WEEKNUM(23742, 11), 53);
137+assertEquals(WEEKNUM(23743, 11), 1);
138+assertEquals(WEEKNUM(23744, 11), 1);
139+assertEquals(WEEKNUM(23745, 11), 1);
140+assertEquals(WEEKNUM(23746, 11), 2);
141+assertEquals(WEEKNUM(23747, 11), 2);
142+assertEquals(WEEKNUM(23748, 11), 2);
143+assertEquals(WEEKNUM(23749, 11), 2);
144+assertEquals(WEEKNUM(23750, 11), 2);
145+assertEquals(WEEKNUM(23751, 11), 2);
146+assertEquals(WEEKNUM(23752, 11), 2);
147+assertEquals(WEEKNUM(23753, 11), 3);
148+assertEquals(WEEKNUM(23754, 11), 3);
149+assertEquals(WEEKNUM(23755, 11), 3);
150+assertEquals(WEEKNUM(23756, 11), 3);
151+assertEquals(WEEKNUM(23757, 11), 3);
152+assertEquals(WEEKNUM(23758, 11), 3);
153+assertEquals(WEEKNUM(23759, 11), 3);
154+assertEquals(WEEKNUM(23760, 11), 4);
155+//type=12
156+assertEquals(WEEKNUM(23737, 12), 52);
157+assertEquals(WEEKNUM(23738, 12), 52);
158+assertEquals(WEEKNUM(23739, 12), 52);
159+assertEquals(WEEKNUM(23740, 12), 53);
160+assertEquals(WEEKNUM(23741, 12), 53);
161+assertEquals(WEEKNUM(23742, 12), 53);
162+assertEquals(WEEKNUM(23743, 12), 1);
163+assertEquals(WEEKNUM(23744, 12), 1);
164+assertEquals(WEEKNUM(23745, 12), 1);
165+assertEquals(WEEKNUM(23746, 12), 1);
166+assertEquals(WEEKNUM(23747, 12), 2);
167+assertEquals(WEEKNUM(23748, 12), 2);
168+assertEquals(WEEKNUM(23749, 12), 2);
169+assertEquals(WEEKNUM(23750, 12), 2);
170+assertEquals(WEEKNUM(23751, 12), 2);
171+assertEquals(WEEKNUM(23752, 12), 2);
172+assertEquals(WEEKNUM(23753, 12), 2);
173+assertEquals(WEEKNUM(23754, 12), 3);
174+assertEquals(WEEKNUM(23755, 12), 3);
175+assertEquals(WEEKNUM(23756, 12), 3);
176+assertEquals(WEEKNUM(23757, 12), 3);
177+assertEquals(WEEKNUM(23758, 12), 3);
178+assertEquals(WEEKNUM(23759, 12), 3);
179+assertEquals(WEEKNUM(23760, 12), 3);
180+//type=13
181+assertEquals(WEEKNUM(23737, 13), 52);
182+assertEquals(WEEKNUM(23738, 13), 52);
183+assertEquals(WEEKNUM(23739, 13), 52);
184+assertEquals(WEEKNUM(23740, 13), 52);
185+assertEquals(WEEKNUM(23741, 13), 53);
186+assertEquals(WEEKNUM(23742, 13), 53);
187+assertEquals(WEEKNUM(23743, 13), 1);
188+assertEquals(WEEKNUM(23744, 13), 1);
189+assertEquals(WEEKNUM(23745, 13), 1);
190+assertEquals(WEEKNUM(23746, 13), 1);
191+assertEquals(WEEKNUM(23747, 13), 1);
192+assertEquals(WEEKNUM(23748, 13), 2);
193+assertEquals(WEEKNUM(23749, 13), 2);
194+assertEquals(WEEKNUM(23750, 13), 2);
195+assertEquals(WEEKNUM(23751, 13), 2);
196+assertEquals(WEEKNUM(23752, 13), 2);
197+assertEquals(WEEKNUM(23753, 13), 2);
198+assertEquals(WEEKNUM(23754, 13), 2);
199+assertEquals(WEEKNUM(23755, 13), 3);
200+assertEquals(WEEKNUM(23756, 13), 3);
201+assertEquals(WEEKNUM(23757, 13), 3);
202+assertEquals(WEEKNUM(23758, 13), 3);
203+assertEquals(WEEKNUM(23759, 13), 3);
204+assertEquals(WEEKNUM(23760, 13), 3);
205+//type=14
206+assertEquals(WEEKNUM(23734, 14), 52);
207+assertEquals(WEEKNUM(23735, 14), 53);
208+assertEquals(WEEKNUM(23736, 14), 53);
209+assertEquals(WEEKNUM(23737, 14), 53);
210+assertEquals(WEEKNUM(23738, 14), 53);
211+assertEquals(WEEKNUM(23739, 14), 53);
212+assertEquals(WEEKNUM(23740, 14), 53);
213+assertEquals(WEEKNUM(23741, 14), 53);
214+assertEquals(WEEKNUM(23742, 14), 54);
215+assertEquals(WEEKNUM(23743, 14), 1);
216+assertEquals(WEEKNUM(23744, 14), 1);
217+assertEquals(WEEKNUM(23745, 14), 1);
218+assertEquals(WEEKNUM(23746, 14), 1);
219+assertEquals(WEEKNUM(23747, 14), 1);
220+assertEquals(WEEKNUM(23748, 14), 1);
221+assertEquals(WEEKNUM(23749, 14), 2);
222+assertEquals(WEEKNUM(23750, 14), 2);
223+assertEquals(WEEKNUM(23751, 14), 2);
224+assertEquals(WEEKNUM(23752, 14), 2);
225+assertEquals(WEEKNUM(23753, 14), 2);
226+assertEquals(WEEKNUM(23754, 14), 2);
227+assertEquals(WEEKNUM(23755, 14), 2);
228+assertEquals(WEEKNUM(23756, 14), 3);
229+assertEquals(WEEKNUM(23757, 14), 3);
230+assertEquals(WEEKNUM(23758, 14), 3);
231+assertEquals(WEEKNUM(23759, 14), 3);
232+assertEquals(WEEKNUM(23760, 14), 3);
233
234
235 // Test WEEKDAY