UNPKG

14.1 kBJavaScriptView Raw
1/**
2 * Created by Avell on 15/12/2016.
3 */
4/* Date Parser */
5function Dates(knwl) {
6 this.languages = {
7 english: true,
8 };
9
10 this.year = {};
11 this.year.lookForYear = function(pos) {
12 /*
13 Attempts to find year in string through ranking:
14 1. Proximity to trigger source
15 2. Punctuation syntax
16 */
17
18 const potential = [];
19
20 let fall = 1.0; //ranking fall
21
22 for (let ee = pos; ee > pos - 20; ee--) {
23 if (dates.db.wordsWithPunc[ee] === undefined) {
24 break;
25 }
26 if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
27 //rank lower if comma seperates results
28 fall += 4;
29 } else if (dates.db.wordsWithPunc[ee].search(/[.?!]/g) !== -1) {
30 //rank much lower if in another sentence
31 fall += 72;
32 }
33 const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); //cleanup
34 if (isNaN(parseInt(curWord)) === false) {
35 const parsedWord = parseInt(curWord);
36 if (parsedWord.toString().length === 4) {
37 potential.push({
38 offset: (pos - ee) * fall,
39 year: parseInt(curWord),
40 });
41 break;
42 }
43 }
44 }
45
46 fall = 1.0; //reset ranking fall
47
48 for (let ee = pos; ee < pos + 20; ee++) {
49 if (dates.db.wordsWithPunc[ee] === undefined) {
50 break;
51 }
52 const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); //cleanup
53 if (isNaN(parseInt(curWord)) === false) {
54 const parsedWord = parseInt(curWord);
55 if (parsedWord.toString().length === 4) {
56 potential.push({
57 offset: (ee - pos) * fall,
58 year: parseInt(curWord),
59 });
60 break;
61 }
62 }
63 if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
64 //rank lower if comma seperates results
65 fall += 4;
66 } else if (dates.db.wordsWithPunc[ee].search(/[.?!]/g) !== -1) {
67 //rank much lower if in another sentence
68 fall += 72;
69 }
70 }
71 if (potential.length > 0) {
72 const sortedByPotential = potential.sort(function(a, b) {
73 return a.offset - b.offset;
74 });
75 return sortedByPotential[0].year;
76 } else {
77 return 'unknown';
78 }
79 };
80
81 this.day = {};
82 this.day.prefix = ['twenty', 'thirty'];
83 this.day.suffix = [
84 'primeir',
85 'segundo',
86 'terceiro',
87 'quarto',
88 'quinto',
89 'sexto',
90 'sétimo',
91 'ouitavo',
92 'nineth',
93 'tenth',
94 'eleventh',
95 'twelfth',
96 'thirteenth',
97 'fourteenth',
98 'fifteenth',
99 'sixteenth',
100 'seventeenth',
101 'eighteenth',
102 'nineteenth',
103 ];
104 this.months = [
105 'janeiro',
106 'fevereiro',
107 'março',
108 'abril',
109 'maio',
110 'junho',
111 'julho',
112 'agosto',
113 'setembro',
114 'outubro',
115 'novembro',
116 'dezembro',
117 ];
118 this.monthAbbrs = [
119 'jan',
120 'fev',
121 'mar',
122 'apr',
123 'mai',
124 'jun',
125 'jul',
126 'ago',
127 'set',
128 'out',
129 'nov',
130 'dez',
131 ];
132 this.holidays = [
133 ['black', 'friday'],
134 ['natal'],
135 ['ano', 'novo'],
136 ['independencia'],
137 ['dia', 'do', 'trabalhador'],
138 ['dia', 'da', 'mentira'],
139 ];
140
141 this.holidaysD = [
142 [28, 11],
143 [25, 12],
144 [1, 1],
145 [4, 7],
146 [31, 10],
147 [1, 4],
148 ];
149 this.dateObj = new Date();
150 this.constructDateObj = function(year, month, day) {
151 return {
152 year: year,
153 month: month,
154 day: day,
155 preview: null,
156 };
157 };
158
159 this.getDay = function(word) {
160 if (word === undefined) {
161 return 'unknown';
162 }
163 //word (twenty-first)
164 const pieces = word.toLowerCase().split('-');
165 let numberStr = '';
166 for (let ii = 0; ii < pieces.length; ii++) {
167 let foundPrefix = false;
168 if (ii === 0) {
169 for (let ee = 0; ee < dates.day.prefix.length; ee++) {
170 if (pieces[ii] === dates.day.prefix[ee]) {
171 if (dates.day.prefix[ee] === 'twenty') {
172 numberStr += '2';
173 } else if (dates.day.prefix[ee] === 'thirty') {
174 numberStr += '3';
175 }
176 foundPrefix = true;
177 break;
178 }
179 }
180 if (foundPrefix === false) {
181 for (let ee = 0; ee < dates.day.suffix.length; ee++) {
182 if (pieces[ii] === dates.day.suffix[ee]) {
183 numberStr += ee + 1;
184 break;
185 }
186 }
187 break;
188 }
189 } else {
190 for (let ee = 0; ee < dates.day.suffix.length; ee++) {
191 if (pieces[ii] === dates.day.suffix[ee]) {
192 numberStr += ee + 1;
193 break;
194 }
195 }
196 }
197 }
198
199 if (numberStr.length > 0) {
200 return parseInt(numberStr);
201 }
202 //number (21st)
203 if (
204 parseInt(word.replace(/[^0-9\.]+/g, '')) > 0 &&
205 parseInt(word.replace(/[^0-9\.]+/g, '')) < 32
206 ) {
207 const parsed = parseInt(word);
208 if (isNaN(parsed) === true) {
209 return 'unknown';
210 }
211 return parsed;
212 }
213 };
214 this.day.lookForDay = function(pos) {
215 /*
216 Attempts to find day in string through ranking:
217 1. Proximity to trigger source
218 2. Punctuation syntax
219 */
220
221 const potential = [];
222 let fall = 1.0; //ranking fall
223 for (let ee = pos; ee > pos - 10; ee--) {
224 if (dates.db.wordsWithPunc[ee] === undefined) {
225 break;
226 }
227 if (dates.db.wordsWithPunc[ee].search(/[?!.]/g) !== -1) {
228 //if reached end of previous sentence
229 break;
230 }
231 if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
232 //rank lower if comma seperates results
233 fall += 4;
234 }
235 const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); //cleanup
236 if (curWord.length - curWord.replace(/[^0-9\.]+/g, '').length === 2) {
237 const testDay = dates.getDay(curWord);
238 if (testDay !== 'unknown' && testDay !== undefined) {
239 potential.push({
240 offset: (pos - ee) * fall,
241 day: testDay,
242 });
243 break;
244 }
245 }
246 }
247
248 fall = 1.0; //reset ranking fall
249
250 for (let ee = pos; ee < pos + 10; ee++) {
251 if (dates.db.wordsWithPunc[ee] === undefined) {
252 break;
253 }
254 let shouldBreak = false;
255 if (dates.db.wordsWithPunc[ee].search(/[?!.]/g) !== -1) {
256 //if reached end of previous sentence
257 shouldBreak = true;
258 }
259 const curWord = dates.db.wordsWithPunc[ee].replace(/[.,!?\(\)]/g, ''); //cleanup
260 if (curWord.length - curWord.replace(/[^0-9\.]+/g, '').length === 2) {
261 const testDay = dates.getDay(curWord);
262 if (testDay !== 'unknown' && testDay !== undefined) {
263 potential.push({
264 offset: (ee - pos) * fall,
265 day: testDay,
266 });
267 break;
268 }
269 }
270 if (shouldBreak) {
271 break;
272 }
273 if (dates.db.wordsWithPunc[ee].search(/[,;:]/g) !== -1) {
274 //rank lower if comma seperates results
275 fall += 4;
276 }
277 }
278 if (potential.length > 0) {
279 const sortedByPotential = potential.sort(function(a, b) {
280 return a.offset - b.offset;
281 });
282 return sortedByPotential[0].day;
283 } else {
284 return 'unknown';
285 // return dates.dateObj.getFullYear();
286 }
287 };
288 this.getMonth = function(word, typeD) {
289 if (!isNaN(word) && typeD === 'mdy') {
290 return parseInt(word);
291 } else {
292 for (let i = 0; i < dates.months.length; i++) {
293 if (dates.months[i] === word) {
294 return i + 1;
295 }
296 }
297 for (let i = 0; i < dates.monthAbbrs.length; i++) {
298 if (dates.monthAbbrs[i] === word) {
299 return i + 1;
300 }
301 }
302 }
303 };
304
305 this.db = {};
306 this.db.words = [];
307 this.db.wordsWithPunc = [];
308 this.calls = function() {
309 const words = knwl.words.get('words');
310 const wordsWithPunc = knwl.words.get('linkWords');
311
312 dates.db.words = words;
313 dates.db.wordsWithPunc = wordsWithPunc;
314
315 const results = [];
316
317 //for dates like "july 16th 1999" one
318 let dateObj = {};
319 for (let i = 0; i < words.length; i++) {
320 let year;
321 const month = dates.getMonth(words[i]);
322 if (month !== undefined) {
323 let day = dates.getDay(words[i + 1]);
324 if (day === undefined) {
325 day = dates.day.lookForDay(i);
326 }
327 let shouldContinue = true;
328 if (day === undefined || day === 'unknown') {
329 if (month === undefined || year === undefined) {
330 shouldContinue = false;
331 }
332 shouldContinue = false;
333 }
334 if (shouldContinue === true) {
335 year = dates.year.lookForYear(i);
336 dateObj = dates.constructDateObj(year, month, day);
337 dateObj.preview = knwl.tasks.preview(i);
338 dateObj.found = i;
339 results.push(dateObj);
340 }
341 }
342 }
343
344 //for dates like "7/16/1999" two
345 dateObj = {};
346 for (let i = 0; i < words.length; i++) {
347 let word = words[i].replace('(', ''); //remove parenth--- if they are present
348 word = word.replace(')', ''); //remove parenth--- if they are present
349 const testDate = word.split('/');
350 if (testDate.length === 3) {
351 let isAllNums = 0;
352 for (let z = 0; z < testDate.length; z++) {
353 if (!isNaN(testDate[z]) && testDate[z] !== '') {
354 isAllNums++;
355 }
356 }
357 if (isAllNums === 3) {
358 const day = dates.getDay(testDate[0]);
359 const month = dates.getMonth(testDate[1], 'mdy');
360 const year = parseInt(testDate[2]);
361 if (month > 12) {
362 //month cannot be over 12
363 break;
364 }
365 dateObj = dates.constructDateObj(year, month, day);
366 dateObj.preview = knwl.tasks.preview(i);
367 dateObj.found = i;
368 results.push(dateObj);
369 }
370 }
371 }
372
373 //for dates like "15/11" two
374 dateObj = {};
375 for (let i = 0; i < words.length; i++) {
376 let word = words[i].replace('(', ''); //remove parenth--- if they are present
377 word = word.replace(')', ''); //remove parenth--- if they are present
378 const testDate = word.split('/');
379 if (testDate.length === 2) {
380 let isAllNums = 0;
381 for (let z = 0; z < testDate.length; z++) {
382 if (!isNaN(testDate[z]) && testDate[z] !== '') {
383 isAllNums++;
384 }
385 }
386 if (isAllNums === 2) {
387 const day = dates.getDay(testDate[0]);
388 const month = dates.getMonth(testDate[1], 'mdy');
389 const year = new Date().getFullYear();
390 if (month > 12) {
391 //month cannot be over 12
392 break;
393 }
394 dateObj = dates.constructDateObj(year, month, day);
395 dateObj.preview = knwl.tasks.preview(i);
396 dateObj.found = i;
397 results.push(dateObj);
398 }
399 }
400 }
401
402 //for dates like "24th of december" three
403 dateObj = {};
404 for (let i = 0; i < words.length; i++) {
405 if (words[i + 1] === 'de') {
406 if (words[i + 2] !== undefined) {
407 const day = dates.getDay(words[i]);
408 const month = dates.getMonth(words[i + 2]);
409 let year = dates.dateObj.getFullYear();
410
411 if (month !== undefined && day !== undefined) {
412 //make sure month and day defined
413 year = dates.year.lookForYear(i);
414 dateObj = dates.constructDateObj(year, month, day);
415 dateObj.preview = knwl.tasks.preview(i);
416 dateObj.found = i;
417 results.push(dateObj);
418 }
419 } //finish check if month and day defined
420 }
421 }
422
423 //for dates like "thanksgiving", "christmas", or "new years"
424 dateObj = {};
425 for (let i = 0; i < words.length; i++) {
426 for (let e = 0; e < dates.holidays.length; e++) {
427 const curHol = dates.holidays[e];
428 let pos = i;
429 if (words[pos] === curHol[0]) {
430 for (let x = 0; x < curHol.length; x++) {
431 if (words[pos] === curHol[x]) {
432 if (x === curHol.length - 1) {
433 if (dates.dateObj.getMonth() <= dates.holidaysD[e][1] + 1) {
434 dateObj = dates.constructDateObj(
435 dates.year.lookForYear(i),
436 dates.holidaysD[e][1],
437 dates.holidaysD[e][0],
438 );
439 dateObj.preview = knwl.tasks.preview(i);
440 dateObj.found = i;
441 } else {
442 dateObj = dates.constructDateObj(
443 dates.year.lookForYear(i),
444 dates.holidaysD[e][1],
445 dates.holidaysD[e][0],
446 );
447 dateObj.preview = knwl.tasks.preview(i);
448 dateObj.found = i;
449 }
450 results.push(dateObj);
451 }
452 } else {
453 break;
454 }
455 pos++;
456 }
457 }
458 }
459 }
460
461 //for dates like "2013-12-15" (YMD)
462 dateObj = {};
463 for (let i = 0; i < words.length; i++) {
464 const temp = words[i].split(/[-]+/);
465 if (temp.length === 3) {
466 let numSets = 0;
467 for (let x = 0; x < temp.length; x++) {
468 if (isNaN(temp[x]) === false) {
469 numSets++;
470 }
471 }
472 if (numSets === 3) {
473 if (
474 temp[0].length === 4 &&
475 (temp[1].length === 2 || temp[1].length === 1) &&
476 (temp[2].length === 2 || temp[2].length === 1)
477 ) {
478 for (let x = 0; x < temp.length; x++) {
479 temp[x] = parseInt(temp[x]);
480 }
481 if (temp[1] > 0 && temp[1] < 13) {
482 if (temp[2] > 0 && temp[2] < 32) {
483 if (temp[0] > 0) {
484 dateObj = dates.constructDateObj(temp[0], temp[1], temp[2]);
485 dateObj.preview = knwl.tasks.preview(i, words);
486 dateObj.found = i;
487 results.push(dateObj);
488 }
489 }
490 }
491 }
492 }
493 }
494 }
495 return results;
496 };
497 const dates = this;
498}
499
500module.exports = Dates;