@syncfusion/ej2-schedule 31.1.17 → 31.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ej2-schedule.min.js +2 -2
- package/dist/ej2-schedule.umd.min.js +2 -2
- package/dist/ej2-schedule.umd.min.js.map +1 -1
- package/dist/es6/ej2-schedule.es2015.js +1 -1
- package/dist/es6/ej2-schedule.es2015.js.map +1 -1
- package/dist/es6/ej2-schedule.es5.js +1 -1
- package/dist/es6/ej2-schedule.es5.js.map +1 -1
- package/dist/global/ej2-schedule.min.js +2 -2
- package/dist/global/ej2-schedule.min.js.map +1 -1
- package/dist/global/index.d.ts +1 -1
- package/package.json +17 -52
- package/src/schedule/event-renderer/event-base.js +1 -1
- package/styles/bootstrap4-lite.css +8 -0
- package/styles/bootstrap4.css +8 -0
- package/styles/recurrence-editor/bootstrap4.css +8 -0
- package/styles/schedule/bootstrap4.css +8 -0
- package/dist/ts/common/calendar-util.d.ts +0 -92
- package/dist/ts/common/calendar-util.ts +0 -261
- package/dist/ts/common/index.d.ts +0 -4
- package/dist/ts/common/index.ts +0 -4
- package/dist/ts/components.d.ts +0 -5
- package/dist/ts/components.ts +0 -5
- package/dist/ts/index.d.ts +0 -6
- package/dist/ts/index.ts +0 -7
- package/dist/ts/recurrence-editor/date-generator.d.ts +0 -76
- package/dist/ts/recurrence-editor/date-generator.ts +0 -1699
- package/dist/ts/recurrence-editor/index.d.ts +0 -6
- package/dist/ts/recurrence-editor/index.ts +0 -6
- package/dist/ts/recurrence-editor/recurrence-editor-model.d.ts +0 -112
- package/dist/ts/recurrence-editor/recurrence-editor.d.ts +0 -245
- package/dist/ts/recurrence-editor/recurrence-editor.ts +0 -1257
- package/dist/ts/schedule/actions/action-base.d.ts +0 -44
- package/dist/ts/schedule/actions/action-base.ts +0 -493
- package/dist/ts/schedule/actions/crud.d.ts +0 -41
- package/dist/ts/schedule/actions/crud.ts +0 -784
- package/dist/ts/schedule/actions/data.d.ts +0 -63
- package/dist/ts/schedule/actions/data.ts +0 -128
- package/dist/ts/schedule/actions/drag.d.ts +0 -75
- package/dist/ts/schedule/actions/drag.ts +0 -1401
- package/dist/ts/schedule/actions/keyboard.d.ts +0 -100
- package/dist/ts/schedule/actions/keyboard.ts +0 -1435
- package/dist/ts/schedule/actions/resize.d.ts +0 -27
- package/dist/ts/schedule/actions/resize.ts +0 -602
- package/dist/ts/schedule/actions/scroll.d.ts +0 -69
- package/dist/ts/schedule/actions/scroll.ts +0 -105
- package/dist/ts/schedule/actions/touch.d.ts +0 -32
- package/dist/ts/schedule/actions/touch.ts +0 -314
- package/dist/ts/schedule/actions/virtual-scroll.d.ts +0 -55
- package/dist/ts/schedule/actions/virtual-scroll.ts +0 -596
- package/dist/ts/schedule/actions/work-cells.d.ts +0 -14
- package/dist/ts/schedule/actions/work-cells.ts +0 -151
- package/dist/ts/schedule/base/constant.d.ts +0 -102
- package/dist/ts/schedule/base/constant.ts +0 -103
- package/dist/ts/schedule/base/css-constant.d.ts +0 -475
- package/dist/ts/schedule/base/css-constant.ts +0 -475
- package/dist/ts/schedule/base/interface.d.ts +0 -673
- package/dist/ts/schedule/base/interface.ts +0 -738
- package/dist/ts/schedule/base/resource.d.ts +0 -59
- package/dist/ts/schedule/base/resource.ts +0 -1091
- package/dist/ts/schedule/base/schedule-model.d.ts +0 -930
- package/dist/ts/schedule/base/schedule.d.ts +0 -1967
- package/dist/ts/schedule/base/schedule.ts +0 -4221
- package/dist/ts/schedule/base/type.d.ts +0 -134
- package/dist/ts/schedule/base/type.ts +0 -142
- package/dist/ts/schedule/base/util.d.ts +0 -266
- package/dist/ts/schedule/base/util.ts +0 -492
- package/dist/ts/schedule/event-renderer/agenda-base.d.ts +0 -15
- package/dist/ts/schedule/event-renderer/agenda-base.ts +0 -423
- package/dist/ts/schedule/event-renderer/event-base.d.ts +0 -101
- package/dist/ts/schedule/event-renderer/event-base.ts +0 -1501
- package/dist/ts/schedule/event-renderer/inline-edit.d.ts +0 -23
- package/dist/ts/schedule/event-renderer/inline-edit.ts +0 -287
- package/dist/ts/schedule/event-renderer/month.d.ts +0 -60
- package/dist/ts/schedule/event-renderer/month.ts +0 -760
- package/dist/ts/schedule/event-renderer/timeline-view.d.ts +0 -51
- package/dist/ts/schedule/event-renderer/timeline-view.ts +0 -606
- package/dist/ts/schedule/event-renderer/vertical-view.d.ts +0 -57
- package/dist/ts/schedule/event-renderer/vertical-view.ts +0 -898
- package/dist/ts/schedule/event-renderer/year.d.ts +0 -27
- package/dist/ts/schedule/event-renderer/year.ts +0 -623
- package/dist/ts/schedule/exports/calendar-export.d.ts +0 -16
- package/dist/ts/schedule/exports/calendar-export.ts +0 -160
- package/dist/ts/schedule/exports/calendar-import.d.ts +0 -18
- package/dist/ts/schedule/exports/calendar-import.ts +0 -277
- package/dist/ts/schedule/exports/excel-export.d.ts +0 -14
- package/dist/ts/schedule/exports/excel-export.ts +0 -89
- package/dist/ts/schedule/exports/index.d.ts +0 -7
- package/dist/ts/schedule/exports/index.ts +0 -7
- package/dist/ts/schedule/exports/print.d.ts +0 -20
- package/dist/ts/schedule/exports/print.ts +0 -233
- package/dist/ts/schedule/index.d.ts +0 -26
- package/dist/ts/schedule/index.ts +0 -26
- package/dist/ts/schedule/models/event-settings-model.d.ts +0 -165
- package/dist/ts/schedule/models/event-settings.d.ts +0 -149
- package/dist/ts/schedule/models/event-settings.ts +0 -187
- package/dist/ts/schedule/models/field-options-model.d.ts +0 -37
- package/dist/ts/schedule/models/field-options.d.ts +0 -31
- package/dist/ts/schedule/models/field-options.ts +0 -41
- package/dist/ts/schedule/models/fields-model.d.ts +0 -129
- package/dist/ts/schedule/models/fields.d.ts +0 -117
- package/dist/ts/schedule/models/fields.ts +0 -149
- package/dist/ts/schedule/models/group-model.d.ts +0 -69
- package/dist/ts/schedule/models/group.d.ts +0 -60
- package/dist/ts/schedule/models/group.ts +0 -75
- package/dist/ts/schedule/models/header-rows-model.d.ts +0 -33
- package/dist/ts/schedule/models/header-rows.d.ts +0 -30
- package/dist/ts/schedule/models/header-rows.ts +0 -35
- package/dist/ts/schedule/models/models.d.ts +0 -14
- package/dist/ts/schedule/models/models.ts +0 -15
- package/dist/ts/schedule/models/quick-info-templates-model.d.ts +0 -52
- package/dist/ts/schedule/models/quick-info-templates.d.ts +0 -47
- package/dist/ts/schedule/models/quick-info-templates.ts +0 -56
- package/dist/ts/schedule/models/resources-model.d.ts +0 -122
- package/dist/ts/schedule/models/resources.d.ts +0 -106
- package/dist/ts/schedule/models/resources.ts +0 -138
- package/dist/ts/schedule/models/time-scale-model.d.ts +0 -57
- package/dist/ts/schedule/models/time-scale.d.ts +0 -50
- package/dist/ts/schedule/models/time-scale.ts +0 -61
- package/dist/ts/schedule/models/toolbar-model.d.ts +0 -196
- package/dist/ts/schedule/models/toolbar.d.ts +0 -176
- package/dist/ts/schedule/models/toolbar.ts +0 -196
- package/dist/ts/schedule/models/views-model.d.ts +0 -370
- package/dist/ts/schedule/models/views.d.ts +0 -335
- package/dist/ts/schedule/models/views.ts +0 -408
- package/dist/ts/schedule/models/work-hours-model.d.ts +0 -29
- package/dist/ts/schedule/models/work-hours.d.ts +0 -24
- package/dist/ts/schedule/models/work-hours.ts +0 -31
- package/dist/ts/schedule/popups/event-tooltip.d.ts +0 -16
- package/dist/ts/schedule/popups/event-tooltip.ts +0 -203
- package/dist/ts/schedule/popups/event-window.d.ts +0 -118
- package/dist/ts/schedule/popups/event-window.ts +0 -2055
- package/dist/ts/schedule/popups/form-validator.d.ts +0 -16
- package/dist/ts/schedule/popups/form-validator.ts +0 -110
- package/dist/ts/schedule/popups/quick-popups.d.ts +0 -78
- package/dist/ts/schedule/popups/quick-popups.ts +0 -1470
- package/dist/ts/schedule/renderer/agenda.d.ts +0 -45
- package/dist/ts/schedule/renderer/agenda.ts +0 -497
- package/dist/ts/schedule/renderer/day.d.ts +0 -20
- package/dist/ts/schedule/renderer/day.ts +0 -28
- package/dist/ts/schedule/renderer/header-renderer.d.ts +0 -48
- package/dist/ts/schedule/renderer/header-renderer.ts +0 -736
- package/dist/ts/schedule/renderer/month-agenda.d.ts +0 -29
- package/dist/ts/schedule/renderer/month-agenda.ts +0 -184
- package/dist/ts/schedule/renderer/month.d.ts +0 -61
- package/dist/ts/schedule/renderer/month.ts +0 -766
- package/dist/ts/schedule/renderer/renderer.d.ts +0 -13
- package/dist/ts/schedule/renderer/renderer.ts +0 -165
- package/dist/ts/schedule/renderer/timeline-header-row.d.ts +0 -15
- package/dist/ts/schedule/renderer/timeline-header-row.ts +0 -132
- package/dist/ts/schedule/renderer/timeline-month.d.ts +0 -29
- package/dist/ts/schedule/renderer/timeline-month.ts +0 -184
- package/dist/ts/schedule/renderer/timeline-view.d.ts +0 -31
- package/dist/ts/schedule/renderer/timeline-view.ts +0 -308
- package/dist/ts/schedule/renderer/timeline-year.d.ts +0 -22
- package/dist/ts/schedule/renderer/timeline-year.ts +0 -450
- package/dist/ts/schedule/renderer/vertical-view.d.ts +0 -63
- package/dist/ts/schedule/renderer/vertical-view.ts +0 -911
- package/dist/ts/schedule/renderer/view-base.d.ts +0 -83
- package/dist/ts/schedule/renderer/view-base.ts +0 -709
- package/dist/ts/schedule/renderer/week.d.ts +0 -22
- package/dist/ts/schedule/renderer/week.ts +0 -35
- package/dist/ts/schedule/renderer/work-week.d.ts +0 -22
- package/dist/ts/schedule/renderer/work-week.ts +0 -36
- package/dist/ts/schedule/renderer/year.d.ts +0 -46
- package/dist/ts/schedule/renderer/year.ts +0 -470
- package/dist/ts/schedule/timezone/timezone.d.ts +0 -16
- package/dist/ts/schedule/timezone/timezone.ts +0 -313
|
@@ -1,1699 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
|
-
import { isNullOrUndefined, L10n, getDefaultDateObject, getValue, cldrData } from '@syncfusion/ej2-base';
|
|
3
|
-
import { MS_PER_DAY, addDays, resetTime, capitalizeFirstWord } from '../schedule/base/util';
|
|
4
|
-
import { CalendarUtil, Islamic, Gregorian, CalendarType } from '../common/calendar-util';
|
|
5
|
-
import { Timezone } from '../schedule/timezone/timezone';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Date Generator from Recurrence Rule
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Generate Summary from Recurrence Rule
|
|
13
|
-
*
|
|
14
|
-
* @param {string} rule Accepts the Recurrence rule
|
|
15
|
-
* @param {L10n} localeObject Accepts the locale object
|
|
16
|
-
* @param {string} locale Accepts the locale name
|
|
17
|
-
* @param {CalendarType} calendarType Accepts the calendar type
|
|
18
|
-
* @returns {string} Returns the summary string from given recurrence rule
|
|
19
|
-
*/
|
|
20
|
-
export function generateSummary(rule: string, localeObject: L10n, locale: string, calendarType: CalendarType = 'Gregorian'): string {
|
|
21
|
-
const ruleObject: RecRule = extractObjectFromRule(rule);
|
|
22
|
-
let summary: string = localeObject.getConstant(EVERY) + ' ';
|
|
23
|
-
let cldrObj: string[];
|
|
24
|
-
let cldrObj1: string[];
|
|
25
|
-
const calendarMode: string = calendarType.toLowerCase();
|
|
26
|
-
if (locale === 'en' || locale === 'en-US') {
|
|
27
|
-
const nameSpace1: string = 'months.stand-alone.abbreviated';
|
|
28
|
-
const nameSpace: string = 'days.stand-alone.abbreviated';
|
|
29
|
-
cldrObj1 = <string[]>(getValue(nameSpace1, getDefaultDateObject(calendarMode)));
|
|
30
|
-
cldrObj = <string[]>(getValue(nameSpace, getDefaultDateObject(calendarMode)));
|
|
31
|
-
} else {
|
|
32
|
-
const nameSpace1: string =
|
|
33
|
-
'main.' + locale + '.dates.calendars.' + calendarMode + '.months.stand-alone.abbreviated';
|
|
34
|
-
const nameSpace: string =
|
|
35
|
-
'main.' + locale + '.dates.calendars.' + calendarMode + '.days.stand-alone.abbreviated';
|
|
36
|
-
cldrObj1 =
|
|
37
|
-
<string[]>(getValue(nameSpace1, cldrData));
|
|
38
|
-
cldrObj =
|
|
39
|
-
<string[]>(getValue(nameSpace, cldrData));
|
|
40
|
-
}
|
|
41
|
-
if (ruleObject.interval > 1) {
|
|
42
|
-
summary += ruleObject.interval + ' ';
|
|
43
|
-
}
|
|
44
|
-
switch (ruleObject.freq) {
|
|
45
|
-
case 'DAILY':
|
|
46
|
-
summary += localeObject.getConstant(DAYS);
|
|
47
|
-
break;
|
|
48
|
-
case 'WEEKLY':
|
|
49
|
-
summary += localeObject.getConstant(WEEKS) + ' ' + localeObject.getConstant(ON) + ' ';
|
|
50
|
-
ruleObject.day.forEach((day: string, index: number) => {
|
|
51
|
-
summary += capitalizeFirstWord(<string>getValue(DAYINDEXOBJECT[`${day}`], cldrObj), 'single');
|
|
52
|
-
summary += (((ruleObject.day.length - 1) === index) ? '' : ', ');
|
|
53
|
-
});
|
|
54
|
-
break;
|
|
55
|
-
case 'MONTHLY':
|
|
56
|
-
summary += localeObject.getConstant(MONTHS) + ' ' + localeObject.getConstant(ON) + ' ';
|
|
57
|
-
summary += getMonthSummary(ruleObject, cldrObj, localeObject);
|
|
58
|
-
break;
|
|
59
|
-
case 'YEARLY':
|
|
60
|
-
summary += localeObject.getConstant(YEARS) + ' ' + localeObject.getConstant(ON) + ' ';
|
|
61
|
-
summary += capitalizeFirstWord(<string>getValue((ruleObject.month[0]).toString(), cldrObj1), 'single') + ' ';
|
|
62
|
-
summary += getMonthSummary(ruleObject, cldrObj, localeObject);
|
|
63
|
-
break;
|
|
64
|
-
}
|
|
65
|
-
if (ruleObject.count) {
|
|
66
|
-
summary += ', ' + (ruleObject.count) + ' ' + localeObject.getConstant(TIMES);
|
|
67
|
-
} else if (ruleObject.until) {
|
|
68
|
-
const tempDate: Date = ruleObject.until;
|
|
69
|
-
summary += ', ' + localeObject.getConstant(UNTIL)
|
|
70
|
-
+ ' ' + tempDate.getDate()
|
|
71
|
-
+ ' ' + capitalizeFirstWord(<string>getValue((tempDate.getMonth() + 1).toString(), cldrObj1), 'single')
|
|
72
|
-
+ ' ' + tempDate.getFullYear();
|
|
73
|
-
}
|
|
74
|
-
return summary;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Generates Month summary
|
|
79
|
-
*
|
|
80
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
81
|
-
* @param {string[]} cldrObj Accepts the collections of month name from calendar
|
|
82
|
-
* @param {L10n} localeObj Accepts the locale object
|
|
83
|
-
* @returns {string} Returns the month summary string from given recurrence rule object
|
|
84
|
-
* @private
|
|
85
|
-
*/
|
|
86
|
-
function getMonthSummary(ruleObject: RecRule, cldrObj: string[], localeObj: L10n): string {
|
|
87
|
-
let summary: string = '';
|
|
88
|
-
if (ruleObject.monthDay.length) {
|
|
89
|
-
summary += ruleObject.monthDay[0];
|
|
90
|
-
} else if (ruleObject.day) {
|
|
91
|
-
const pos: number = ruleObject.setPosition - 1;
|
|
92
|
-
summary += localeObj.getConstant(WEEKPOS[pos > -1 ? pos : (WEEKPOS.length - 1)])
|
|
93
|
-
+ ' ' + capitalizeFirstWord(<string>getValue(DAYINDEXOBJECT[ruleObject.day[0]], cldrObj), 'single');
|
|
94
|
-
}
|
|
95
|
-
return summary;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Generates the date collections from the given recurrence rule
|
|
100
|
-
*
|
|
101
|
-
* @param {Date} startDate Accepts the rule start date
|
|
102
|
-
* @param {string} rule Accepts the recurrence rule
|
|
103
|
-
* @param {string} excludeDate Accepts the exception dates in string format
|
|
104
|
-
* @param {number} startDayOfWeek Accepts the start day index of week
|
|
105
|
-
* @param {number} maximumCount Accepts the maximum number count to generate date collections
|
|
106
|
-
* @param {Date} viewDate Accepts the current date instead of start date
|
|
107
|
-
* @param {CalendarType} calendarMode Accepts the calendar type
|
|
108
|
-
* @param {string} newTimezone Accepts the timezone name
|
|
109
|
-
* @returns {number[]} Returns the collection of dates
|
|
110
|
-
*/
|
|
111
|
-
export function generate(startDate: Date, rule: string, excludeDate: string, startDayOfWeek: number, maximumCount: number = MAXOCCURRENCE, viewDate: Date = null, calendarMode: CalendarType = 'Gregorian', newTimezone: string = null): number[] {
|
|
112
|
-
const ruleObject: RecRule = extractObjectFromRule(rule);
|
|
113
|
-
let cacheDate: Date; calendarUtil = getCalendarUtil(calendarMode);
|
|
114
|
-
const data: number[] = [];
|
|
115
|
-
const modifiedDate: Date = new Date(startDate.getTime());
|
|
116
|
-
tempExcludeDate = [];
|
|
117
|
-
const tempDate: string[] = isNullOrUndefined(excludeDate) ? [] : excludeDate.split(',');
|
|
118
|
-
const tz: Timezone = new Timezone();
|
|
119
|
-
tempDate.forEach((content: string) => {
|
|
120
|
-
let parsedDate: Date = getDateFromRecurrenceDateString(content);
|
|
121
|
-
if (newTimezone) {
|
|
122
|
-
parsedDate = tz.add(new Date(parsedDate.getTime()), newTimezone);
|
|
123
|
-
}
|
|
124
|
-
tempExcludeDate.push(new Date(parsedDate.getTime()).setHours(0, 0, 0, 0));
|
|
125
|
-
});
|
|
126
|
-
ruleObject.recExceptionCount = !isNullOrUndefined(ruleObject.count) ? tempExcludeDate.length : 0;
|
|
127
|
-
|
|
128
|
-
if (viewDate && viewDate > startDate && !ruleObject.count) {
|
|
129
|
-
tempViewDate = new Date(new Date(viewDate.getTime()).setHours(0, 0, 0));
|
|
130
|
-
} else {
|
|
131
|
-
tempViewDate = null;
|
|
132
|
-
}
|
|
133
|
-
if (!ruleObject.until && tempViewDate) {
|
|
134
|
-
cacheDate = new Date(tempViewDate.getTime());
|
|
135
|
-
cacheDate.setDate(tempViewDate.getDate() + maximumCount * (ruleObject.interval));
|
|
136
|
-
ruleObject.until = cacheDate;
|
|
137
|
-
}
|
|
138
|
-
if (ruleObject.until && startDate > ruleObject.until) {
|
|
139
|
-
return data;
|
|
140
|
-
}
|
|
141
|
-
maxOccurrence = maximumCount;
|
|
142
|
-
startDayOfWeek = startDayOfWeek || 0;
|
|
143
|
-
setFirstDayOfWeek(DAYINDEX[parseInt(startDayOfWeek.toString(), 10)]);
|
|
144
|
-
if (ruleObject.until) {
|
|
145
|
-
const end: Date = resetTime(ruleObject.until);
|
|
146
|
-
ruleObject.until = new Date(end.getFullYear(), end.getMonth(), end.getDate(), 23, 59, 59);
|
|
147
|
-
}
|
|
148
|
-
switch (ruleObject.freq) {
|
|
149
|
-
case 'DAILY':
|
|
150
|
-
dailyType(modifiedDate, ruleObject.until, data, ruleObject);
|
|
151
|
-
break;
|
|
152
|
-
case 'WEEKLY':
|
|
153
|
-
weeklyType(modifiedDate, ruleObject.until, data, ruleObject, startDayOfWeek);
|
|
154
|
-
break;
|
|
155
|
-
case 'MONTHLY':
|
|
156
|
-
monthlyType(modifiedDate, ruleObject.until, data, ruleObject);
|
|
157
|
-
break;
|
|
158
|
-
case 'YEARLY':
|
|
159
|
-
yearlyType(modifiedDate, ruleObject.until, data, ruleObject);
|
|
160
|
-
}
|
|
161
|
-
return data;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Generate date object from given date string
|
|
166
|
-
*
|
|
167
|
-
* @param {string} recDateString Accepts the exception date as string
|
|
168
|
-
* @returns {Date} Returns the date from exception date string
|
|
169
|
-
*/
|
|
170
|
-
export function getDateFromRecurrenceDateString(recDateString: string): Date {
|
|
171
|
-
return new Date(recDateString.substr(0, 4) +
|
|
172
|
-
'-' + recDateString.substr(4, 2) +
|
|
173
|
-
'-' + recDateString.substr(6, 5) +
|
|
174
|
-
':' + recDateString.substr(11, 2) +
|
|
175
|
-
':' + recDateString.substr(13));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Internal method to handle exclude date
|
|
180
|
-
*
|
|
181
|
-
* @param {number[]} data Accepts the exception date collections
|
|
182
|
-
* @param {number} date Accepts the new exclude date
|
|
183
|
-
* @returns {void}
|
|
184
|
-
* @private
|
|
185
|
-
*/
|
|
186
|
-
function excludeDateHandler(data: number[], date: number): void {
|
|
187
|
-
const zeroIndex: number = new Date(date).setHours(0, 0, 0, 0);
|
|
188
|
-
if (tempExcludeDate.indexOf(zeroIndex) === -1 && (!tempViewDate || zeroIndex >= tempViewDate.getTime())) {
|
|
189
|
-
data.push(date);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Internal method for get date count
|
|
195
|
-
*
|
|
196
|
-
* @param {Date} startDate Accepts the date
|
|
197
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
198
|
-
* @returns {number} Returns the number of date count
|
|
199
|
-
* @private
|
|
200
|
-
*/
|
|
201
|
-
function getDateCount(startDate: Date, ruleObject: RecRule): number {
|
|
202
|
-
let count: number = maxOccurrence;
|
|
203
|
-
if (ruleObject.count) {
|
|
204
|
-
count = ruleObject.count;
|
|
205
|
-
} else if (ruleObject.until) {
|
|
206
|
-
if (ruleObject.freq === 'DAILY' || ruleObject.freq === 'WEEKLY') {
|
|
207
|
-
count = Math.floor((ruleObject.until.getTime() - startDate.getTime()) / MS_PER_DAY) + 1;
|
|
208
|
-
} else if (ruleObject.freq === 'MONTHLY' || ruleObject.freq === 'YEARLY') {
|
|
209
|
-
count = Math.floor(((ruleObject.until.getMonth() + 12 * ruleObject.until.getFullYear()) -
|
|
210
|
-
(startDate.getMonth() + 12 * startDate.getFullYear())) / ruleObject.interval) +
|
|
211
|
-
(ruleObject.day.length > 1 ? (Math.floor((ruleObject.until.getTime() - startDate.getTime()) / MS_PER_DAY) + 1) : 1);
|
|
212
|
-
if (ruleObject.freq === 'YEARLY') {
|
|
213
|
-
count = ruleObject.month.length > 1 ? ((count as number) * ruleObject.month.length) : count;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return count;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Internal method for daily type recurrence rule
|
|
222
|
-
*
|
|
223
|
-
* @param {Date} startDate Accepts the strat date
|
|
224
|
-
* @param {Date} endDate Accepts the end date
|
|
225
|
-
* @param {number[]} data Accepts the collection of dates
|
|
226
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
227
|
-
* @returns {void}
|
|
228
|
-
* @private
|
|
229
|
-
*/
|
|
230
|
-
function dailyType(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
231
|
-
const tempDate: Date = new Date(startDate.getTime());
|
|
232
|
-
const interval: number = ruleObject.interval;
|
|
233
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
234
|
-
let state: boolean;
|
|
235
|
-
const expectedDays: string[] = ruleObject.day;
|
|
236
|
-
while (compareDates(tempDate, endDate)) {
|
|
237
|
-
state = true;
|
|
238
|
-
state = validateRules(tempDate, ruleObject);
|
|
239
|
-
if (state && (expectedDays.indexOf(DAYINDEX[tempDate.getDay()]) > -1 || expectedDays.length === 0)) {
|
|
240
|
-
excludeDateHandler(data, tempDate.getTime());
|
|
241
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
242
|
-
break;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
tempDate.setDate(tempDate.getDate() + interval);
|
|
246
|
-
if (tempDate.getHours() !== startDate.getHours()) {
|
|
247
|
-
tempDate.setHours(startDate.getHours());
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Internal method for weekly type recurrence rule
|
|
254
|
-
*
|
|
255
|
-
* @param {Date} startDate Accepts the strat date
|
|
256
|
-
* @param {Date} endDate Accepts the end date
|
|
257
|
-
* @param {number[]} data Accepts the collection of dates
|
|
258
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
259
|
-
* @param {number} startDayOfWeek Accepts the start day index of week
|
|
260
|
-
* @returns {void}
|
|
261
|
-
* @private
|
|
262
|
-
*/
|
|
263
|
-
function weeklyType(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule, startDayOfWeek: number): void {
|
|
264
|
-
let tempDate: Date = new Date(startDate.getTime());
|
|
265
|
-
if (!ruleObject.day.length) {
|
|
266
|
-
ruleObject.day.push(DAYINDEX[startDate.getDay()]);
|
|
267
|
-
}
|
|
268
|
-
const interval: number = ruleObject.interval;
|
|
269
|
-
const expectedDays: string[] = ruleObject.day;
|
|
270
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
271
|
-
let weekState: boolean = true;
|
|
272
|
-
let wkstIndex: number;
|
|
273
|
-
let weekCollection: number[][] = [];
|
|
274
|
-
if (expectedDays.length > 1) {
|
|
275
|
-
if (isNullOrUndefined(ruleObject.wkst) || ruleObject.wkst === '') {
|
|
276
|
-
ruleObject.wkst = dayIndex[0];
|
|
277
|
-
}
|
|
278
|
-
wkstIndex = DAYINDEX.indexOf(ruleObject.wkst);
|
|
279
|
-
while (compareDates(tempDate, endDate)) {
|
|
280
|
-
let startDateDiff: number = DAYINDEX.indexOf(DAYINDEX[tempDate.getDay()]) - wkstIndex;
|
|
281
|
-
startDateDiff = startDateDiff === -1 ? 6 : startDateDiff;
|
|
282
|
-
const weekstartDate: Date = addDays(tempDate, -startDateDiff);
|
|
283
|
-
let weekendDate: Date = addDays(weekstartDate, 6);
|
|
284
|
-
let compareTempDate: Date = new Date(tempDate.getTime());
|
|
285
|
-
weekendDate = resetTime(weekendDate);
|
|
286
|
-
compareTempDate = resetTime(compareTempDate);
|
|
287
|
-
while (weekendDate >= compareTempDate) {
|
|
288
|
-
if (expectedDays.indexOf(DAYINDEX[tempDate.getDay()]) > -1) {
|
|
289
|
-
weekCollection.push([tempDate.getTime()]);
|
|
290
|
-
}
|
|
291
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
tempDate.setDate(tempDate.getDate() + 1);
|
|
295
|
-
if (tempDate.getHours() !== startDate.getHours()) {
|
|
296
|
-
tempDate.setHours(startDate.getHours());
|
|
297
|
-
}
|
|
298
|
-
compareTempDate = new Date(tempDate.getTime());
|
|
299
|
-
compareTempDate = resetTime(compareTempDate);
|
|
300
|
-
}
|
|
301
|
-
tempDate.setDate(tempDate.getDate() - 1);
|
|
302
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
tempDate.setDate((tempDate.getDate()) + 1 + ((interval - 1) * 7));
|
|
306
|
-
insertDataCollection(weekCollection, weekState, startDate, endDate, data, ruleObject);
|
|
307
|
-
weekCollection = [];
|
|
308
|
-
}
|
|
309
|
-
} else {
|
|
310
|
-
tempDate = getStartDateForWeek(startDate, ruleObject.day);
|
|
311
|
-
if (interval > 1 && dayIndex.indexOf(ruleObject.day[0]) < (startDate.getDay() - startDayOfWeek)) {
|
|
312
|
-
tempDate.setDate(tempDate.getDate() + ((interval - 1) * 7));
|
|
313
|
-
}
|
|
314
|
-
while (compareDates(tempDate, endDate)) {
|
|
315
|
-
weekState = validateRules(tempDate, ruleObject);
|
|
316
|
-
if (weekState && (expectedDays.indexOf(DAYINDEX[tempDate.getDay()]) > -1)) {
|
|
317
|
-
excludeDateHandler(data, tempDate.getTime());
|
|
318
|
-
}
|
|
319
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
320
|
-
break;
|
|
321
|
-
}
|
|
322
|
-
tempDate.setDate(tempDate.getDate() + (interval * 7));
|
|
323
|
-
}
|
|
324
|
-
insertDataCollection(weekCollection, weekState, startDate, endDate, data, ruleObject);
|
|
325
|
-
weekCollection = [];
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
/**
|
|
330
|
-
* Internal method for monthly type recurrence rule
|
|
331
|
-
*
|
|
332
|
-
* @param {Date} startDate Accepts the strat date
|
|
333
|
-
* @param {Date} endDate Accepts the end date
|
|
334
|
-
* @param {number[]} data Accepts the collection of dates
|
|
335
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
336
|
-
* @returns {void}
|
|
337
|
-
* @private
|
|
338
|
-
*/
|
|
339
|
-
function monthlyType(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
340
|
-
// Set monthday value if BYDAY, BYMONTH and Month day property is not set based on start date
|
|
341
|
-
if (!ruleObject.month.length && !ruleObject.day.length && !ruleObject.monthDay.length) {
|
|
342
|
-
ruleObject.monthDay.push(startDate.getDate());
|
|
343
|
-
if (ruleObject.freq === 'YEARLY') {
|
|
344
|
-
ruleObject.month.push(startDate.getMonth() + 1);
|
|
345
|
-
}
|
|
346
|
-
} else if (ruleObject.month.length > 0 && !ruleObject.day.length && !ruleObject.monthDay.length) {
|
|
347
|
-
ruleObject.monthDay.push(startDate.getDate());
|
|
348
|
-
}
|
|
349
|
-
const ruleType: MonthlyType = validateMonthlyRuleType(ruleObject);
|
|
350
|
-
switch (ruleType) {
|
|
351
|
-
case 'day':
|
|
352
|
-
switch (ruleObject.freq) {
|
|
353
|
-
case 'MONTHLY':
|
|
354
|
-
monthlyDayTypeProcessforMonthFreq(startDate, endDate, data, ruleObject);
|
|
355
|
-
break;
|
|
356
|
-
case 'YEARLY':
|
|
357
|
-
monthlyDayTypeProcess(startDate, endDate, data, ruleObject);
|
|
358
|
-
break;
|
|
359
|
-
}
|
|
360
|
-
break;
|
|
361
|
-
case 'both':
|
|
362
|
-
case 'date':
|
|
363
|
-
switch (ruleObject.freq) {
|
|
364
|
-
case 'MONTHLY':
|
|
365
|
-
monthlyDateTypeProcessforMonthFreq(startDate, endDate, data, ruleObject);
|
|
366
|
-
break;
|
|
367
|
-
case 'YEARLY':
|
|
368
|
-
monthlyDateTypeProcess(startDate, endDate, data, ruleObject);
|
|
369
|
-
break;
|
|
370
|
-
}
|
|
371
|
-
break;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Internal method for yearly type recurrence rule
|
|
377
|
-
*
|
|
378
|
-
* @param {Date} startDate Accepts the strat date
|
|
379
|
-
* @param {Date} endDate Accepts the end date
|
|
380
|
-
* @param {number[]} data Accepts the collection of dates
|
|
381
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
382
|
-
* @returns {void}
|
|
383
|
-
* @private
|
|
384
|
-
*/
|
|
385
|
-
function yearlyType(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
386
|
-
const typeValue: YearRuleType = checkYearlyType(ruleObject);
|
|
387
|
-
switch (typeValue) {
|
|
388
|
-
case 'MONTH':
|
|
389
|
-
monthlyType(startDate, endDate, data, ruleObject);
|
|
390
|
-
break;
|
|
391
|
-
case 'WEEKNO':
|
|
392
|
-
processWeekNo(startDate, endDate, data, ruleObject);
|
|
393
|
-
break;
|
|
394
|
-
case 'YEARDAY':
|
|
395
|
-
processYearDay(startDate, endDate, data, ruleObject);
|
|
396
|
-
break;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/**
|
|
401
|
-
* Internal method for process week no
|
|
402
|
-
*
|
|
403
|
-
* @param {Date} startDate Accepts the strat date
|
|
404
|
-
* @param {Date} endDate Accepts the end date
|
|
405
|
-
* @param {number[]} data Accepts the collection of dates
|
|
406
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
407
|
-
* @returns {void}
|
|
408
|
-
* @private
|
|
409
|
-
*/
|
|
410
|
-
function processWeekNo(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
411
|
-
let stDate: Date = calendarUtil.getYearLastDate(startDate, 0);
|
|
412
|
-
let tempDate: Date;
|
|
413
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
414
|
-
let state: boolean;
|
|
415
|
-
let startDay: number;
|
|
416
|
-
let firstWeekSpan: number;
|
|
417
|
-
const weekNos: number[] = ruleObject.weekNo;
|
|
418
|
-
let weekNo: number;
|
|
419
|
-
let maxDate: number;
|
|
420
|
-
let minDate: number;
|
|
421
|
-
let weekCollection: number[][] = [];
|
|
422
|
-
const expectedDays: string[] = ruleObject.day;
|
|
423
|
-
while (compareDates(stDate, endDate)) {
|
|
424
|
-
startDay = dayIndex.indexOf(DAYINDEX[stDate.getDay()]);
|
|
425
|
-
firstWeekSpan = (6 - startDay) + 1;
|
|
426
|
-
for (let index: number = 0; index < weekNos.length; index++) {
|
|
427
|
-
weekNo = weekNos[parseInt(index.toString(), 10)];
|
|
428
|
-
weekNo = (weekNo > 0) ? weekNo : 53 + weekNo + 1;
|
|
429
|
-
maxDate = (weekNo === 1) ? firstWeekSpan : firstWeekSpan + ((weekNo - 1) * 7);
|
|
430
|
-
minDate = (weekNo === 1) ? firstWeekSpan - 7 : firstWeekSpan + ((weekNo - 2) * 7);
|
|
431
|
-
while (minDate < maxDate) {
|
|
432
|
-
tempDate = new Date(stDate.getTime() + (MS_PER_DAY * minDate));
|
|
433
|
-
if (expectedDays.length === 0 || expectedDays.indexOf(DAYINDEX[tempDate.getDay()]) > -1) {
|
|
434
|
-
if (isNullOrUndefined(ruleObject.setPosition)) {
|
|
435
|
-
insertDateCollection(state, startDate, endDate, data, ruleObject, tempDate.getTime());
|
|
436
|
-
} else {
|
|
437
|
-
weekCollection.push([tempDate.getTime()]);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
minDate++;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
if (!isNullOrUndefined(ruleObject.setPosition)) {
|
|
444
|
-
insertDatasIntoExistingCollection(weekCollection, state, startDate, endDate, data, ruleObject);
|
|
445
|
-
}
|
|
446
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
stDate = calendarUtil.getYearLastDate(tempDate, ruleObject.interval);
|
|
450
|
-
weekCollection = [];
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Internal method for process year day
|
|
456
|
-
*
|
|
457
|
-
* @param {Date} startDate Accepts the strat date
|
|
458
|
-
* @param {Date} endDate Accepts the end date
|
|
459
|
-
* @param {number[]} data Accepts the collection of dates
|
|
460
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
461
|
-
* @returns {void}
|
|
462
|
-
* @private
|
|
463
|
-
*/
|
|
464
|
-
function processYearDay(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
465
|
-
let stDate: Date = calendarUtil.getYearLastDate(startDate, 0);
|
|
466
|
-
let tempDate: Date;
|
|
467
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
468
|
-
let state: boolean;
|
|
469
|
-
let dateCollection: number[][] = [];
|
|
470
|
-
let date: number;
|
|
471
|
-
const expectedDays: string[] = ruleObject.day;
|
|
472
|
-
while (compareDates(stDate, endDate)) {
|
|
473
|
-
for (let index: number = 0; index < ruleObject.yearDay.length; index++) {
|
|
474
|
-
date = ruleObject.yearDay[parseInt(index.toString(), 10)];
|
|
475
|
-
tempDate = new Date(stDate.getTime());
|
|
476
|
-
if ((date === calendarUtil.getLeapYearDaysCount() || date === -calendarUtil.getLeapYearDaysCount()) &&
|
|
477
|
-
(!calendarUtil.isLeapYear(calendarUtil.getFullYear(tempDate), 1))) {
|
|
478
|
-
tempDate.setDate(tempDate.getDate() + 1);
|
|
479
|
-
continue;
|
|
480
|
-
}
|
|
481
|
-
tempDate.setDate(tempDate.getDate() + ((date < 0) ?
|
|
482
|
-
calendarUtil.getYearDaysCount(tempDate, 1) + 1 + date : date));
|
|
483
|
-
if (expectedDays.length === 0 || expectedDays.indexOf(DAYINDEX[tempDate.getDay()]) > -1) {
|
|
484
|
-
if (ruleObject.setPosition == null) {
|
|
485
|
-
insertDateCollection(state, startDate, endDate, data, ruleObject, tempDate.getTime());
|
|
486
|
-
} else {
|
|
487
|
-
dateCollection.push([tempDate.getTime()]);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
if (!isNullOrUndefined(ruleObject.setPosition)) {
|
|
492
|
-
insertDatasIntoExistingCollection(dateCollection, state, startDate, endDate, data, ruleObject);
|
|
493
|
-
}
|
|
494
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
stDate = calendarUtil.getYearLastDate(tempDate, ruleObject.interval);
|
|
498
|
-
dateCollection = [];
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Internal method to check yearly type
|
|
504
|
-
*
|
|
505
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
506
|
-
* @returns {YearRuleType} Returns the Yearly rule type object
|
|
507
|
-
* @private
|
|
508
|
-
*/
|
|
509
|
-
function checkYearlyType(ruleObject: RecRule): YearRuleType {
|
|
510
|
-
if (ruleObject.yearDay.length) {
|
|
511
|
-
return 'YEARDAY';
|
|
512
|
-
} else if (ruleObject.weekNo.length) {
|
|
513
|
-
return 'WEEKNO';
|
|
514
|
-
}
|
|
515
|
-
return 'MONTH';
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Internal method to initialize recurrence rule variables
|
|
520
|
-
*
|
|
521
|
-
* @param {Date} startDate Accepts the start date
|
|
522
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
523
|
-
* @returns {RuleData} Return the rule data object
|
|
524
|
-
* @private
|
|
525
|
-
*/
|
|
526
|
-
function initializeRecRuleVariables(startDate: Date, ruleObject: RecRule): RuleData {
|
|
527
|
-
const ruleData: RuleData = {
|
|
528
|
-
monthCollection: [],
|
|
529
|
-
index: 0,
|
|
530
|
-
tempDate: new Date(startDate.getTime()),
|
|
531
|
-
mainDate: new Date(startDate.getTime()),
|
|
532
|
-
expectedCount: getDateCount(startDate, ruleObject),
|
|
533
|
-
monthInit: 0,
|
|
534
|
-
dateCollection: []
|
|
535
|
-
};
|
|
536
|
-
if (ruleObject.month.length) {
|
|
537
|
-
calendarUtil.setMonth(ruleData.tempDate, ruleObject.month[0], ruleData.tempDate.getDate());
|
|
538
|
-
}
|
|
539
|
-
return ruleData;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Internal method for process monthly date type recurrence rule
|
|
544
|
-
*
|
|
545
|
-
* @param {Date} startDate Accepts the strat date
|
|
546
|
-
* @param {Date} endDate Accepts the end date
|
|
547
|
-
* @param {number[]} data Accepts the collection of dates
|
|
548
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
549
|
-
* @returns {void}
|
|
550
|
-
* @private
|
|
551
|
-
*/
|
|
552
|
-
function monthlyDateTypeProcess(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
553
|
-
if (ruleObject.month.length) {
|
|
554
|
-
monthlyDateTypeProcessforMonthFreq(startDate, endDate, data, ruleObject);
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
const ruleData: RuleData = initializeRecRuleVariables(startDate, ruleObject);
|
|
558
|
-
let currentMonthDate: Date;
|
|
559
|
-
ruleData.tempDate = ruleData.mainDate = calendarUtil.getMonthStartDate(ruleData.tempDate);
|
|
560
|
-
while (compareDates(ruleData.tempDate, endDate)) {
|
|
561
|
-
currentMonthDate = new Date(ruleData.tempDate.getTime());
|
|
562
|
-
while (calendarUtil.isSameYear(currentMonthDate, ruleData.tempDate) &&
|
|
563
|
-
(ruleData.expectedCount && (data.length + ruleObject.recExceptionCount) <= ruleData.expectedCount)) {
|
|
564
|
-
if (ruleObject.month.length === 0 || (ruleObject.month.length > 0
|
|
565
|
-
&& !calendarUtil.checkMonth(ruleData.tempDate, ruleObject.month))) {
|
|
566
|
-
processDateCollectionForByMonthDay(ruleObject, ruleData, endDate, false);
|
|
567
|
-
ruleData.beginDate = new Date(ruleData.tempDate.getTime());
|
|
568
|
-
ruleData.monthInit = setNextValidDate(
|
|
569
|
-
ruleData.tempDate, ruleObject, ruleData.monthInit, ruleData.beginDate);
|
|
570
|
-
} else {
|
|
571
|
-
calendarUtil.setValidDate(ruleData.tempDate, 1, 1);
|
|
572
|
-
ruleData.tempDate = getStartDateForWeek(ruleData.tempDate, ruleObject.day);
|
|
573
|
-
break;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
ruleData.tempDate.setFullYear(currentMonthDate.getFullYear(), currentMonthDate.getMonth(), currentMonthDate.getDate());
|
|
577
|
-
insertDataCollection(ruleData.dateCollection, ruleData.state, startDate, endDate, data, ruleObject);
|
|
578
|
-
if (calendarUtil.isLastMonth(ruleData.tempDate)) {
|
|
579
|
-
calendarUtil.setValidDate(ruleData.tempDate, 1, 1);
|
|
580
|
-
ruleData.tempDate = getStartDateForWeek(ruleData.tempDate, ruleObject.day);
|
|
581
|
-
}
|
|
582
|
-
if (ruleData.expectedCount && (data.length + ruleObject.recExceptionCount) >= ruleData.expectedCount) {
|
|
583
|
-
return;
|
|
584
|
-
}
|
|
585
|
-
ruleData.tempDate.setFullYear(ruleData.tempDate.getFullYear() + ruleObject.interval - 1);
|
|
586
|
-
ruleData.tempDate = getStartDateForWeek(ruleData.tempDate, ruleObject.day);
|
|
587
|
-
ruleData.monthInit = setNextValidDate(
|
|
588
|
-
ruleData.tempDate, ruleObject, ruleData.monthInit, ruleData.beginDate);
|
|
589
|
-
ruleData.dateCollection = [];
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
/**
|
|
594
|
-
* Internal method for process monthly date type with month frequency from recurrence rule
|
|
595
|
-
*
|
|
596
|
-
* @param {Date} startDate Accepts the strat date
|
|
597
|
-
* @param {Date} endDate Accepts the end date
|
|
598
|
-
* @param {number[]} data Accepts the collection of dates
|
|
599
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
600
|
-
* @returns {void}
|
|
601
|
-
* @private
|
|
602
|
-
*/
|
|
603
|
-
function monthlyDateTypeProcessforMonthFreq(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
604
|
-
const ruleData: RuleData = initializeRecRuleVariables(startDate, ruleObject);
|
|
605
|
-
ruleData.tempDate = ruleData.mainDate = calendarUtil.getMonthStartDate(ruleData.tempDate);
|
|
606
|
-
if (((ruleObject.freq === 'MONTHLY' && ruleObject.interval === 12) || (ruleObject.freq === 'YEARLY')) &&
|
|
607
|
-
calendarUtil.getMonthDaysCount(startDate) < ruleObject.monthDay[0]) {
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
while (compareDates(ruleData.tempDate, endDate)) {
|
|
611
|
-
ruleData.beginDate = new Date(ruleData.tempDate.getTime());
|
|
612
|
-
processDateCollectionForByMonthDay(ruleObject, ruleData, endDate, true, startDate, data);
|
|
613
|
-
if (!isNullOrUndefined(ruleObject.setPosition)) {
|
|
614
|
-
insertDatasIntoExistingCollection(ruleData.dateCollection, ruleData.state, startDate, endDate, data, ruleObject);
|
|
615
|
-
}
|
|
616
|
-
if (ruleData.expectedCount && (data.length + ruleObject.recExceptionCount) >= ruleData.expectedCount) {
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
ruleData.monthInit = setNextValidDate(ruleData.tempDate, ruleObject, ruleData.monthInit, ruleData.beginDate);
|
|
620
|
-
ruleData.dateCollection = [];
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
/**
|
|
625
|
-
* To process date collection for Monthly & Yearly based on BYMONTH Day property
|
|
626
|
-
*
|
|
627
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
628
|
-
* @param {RuleData} recRuleVariables Accepts the rule data
|
|
629
|
-
* @param {Date} endDate Accepts the end date
|
|
630
|
-
* @param {boolean} isByMonth Accepts the boolean to validate either month or not
|
|
631
|
-
* @param {Date} startDate Accepts the start date
|
|
632
|
-
* @param {number[]} data Accepts the collection of dates
|
|
633
|
-
* @returns {void}
|
|
634
|
-
* @private
|
|
635
|
-
*/
|
|
636
|
-
function processDateCollectionForByMonthDay(ruleObject: RecRule, recRuleVariables: RuleData, endDate: Date, isByMonth?: boolean, startDate?: Date, data?: number[]): void {
|
|
637
|
-
for (let index: number = 0; index < ruleObject.monthDay.length; index++) {
|
|
638
|
-
recRuleVariables.date = ruleObject.monthDay[parseInt(index.toString(), 10)];
|
|
639
|
-
recRuleVariables.tempDate = calendarUtil.getMonthStartDate(recRuleVariables.tempDate);
|
|
640
|
-
const maxDate: number = calendarUtil.getMonthDaysCount(recRuleVariables.tempDate);
|
|
641
|
-
recRuleVariables.date = recRuleVariables.date > 0 ? recRuleVariables.date : (maxDate + recRuleVariables.date + 1);
|
|
642
|
-
if (validateProperDate(recRuleVariables.tempDate, recRuleVariables.date, recRuleVariables.mainDate)
|
|
643
|
-
&& (recRuleVariables.date > 0)) {
|
|
644
|
-
calendarUtil.setDate(recRuleVariables.tempDate, recRuleVariables.date);
|
|
645
|
-
if (endDate && recRuleVariables.tempDate > endDate) {
|
|
646
|
-
return;
|
|
647
|
-
}
|
|
648
|
-
if (ruleObject.day.length === 0 || ruleObject.day.indexOf(DAYINDEX[recRuleVariables.tempDate.getDay()]) > -1) {
|
|
649
|
-
if (isByMonth && isNullOrUndefined(ruleObject.setPosition) && (recRuleVariables.expectedCount
|
|
650
|
-
&& (data.length + ruleObject.recExceptionCount) < recRuleVariables.expectedCount)) {
|
|
651
|
-
insertDateCollection(recRuleVariables.state, startDate, endDate, data, ruleObject, recRuleVariables.tempDate.getTime());
|
|
652
|
-
} else {
|
|
653
|
-
recRuleVariables.dateCollection.push([recRuleVariables.tempDate.getTime()]);
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Internal method to set next valid date
|
|
662
|
-
*
|
|
663
|
-
* @param {Date} tempDate Accepts the date
|
|
664
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
665
|
-
* @param {number} monthInit Accepts the initial month
|
|
666
|
-
* @param {Date} beginDate Accepts the initial date
|
|
667
|
-
* @param {number} interval Accepts the interval duration
|
|
668
|
-
* @returns {number} Returnx the next valid date
|
|
669
|
-
* @private
|
|
670
|
-
*/
|
|
671
|
-
function setNextValidDate(tempDate: Date, ruleObject: RecRule, monthInit: number, beginDate: Date = null, interval?: number): number {
|
|
672
|
-
let monthData: number = beginDate ? beginDate.getMonth() : 0;
|
|
673
|
-
const startDate: Date = calendarUtil.getMonthStartDate(tempDate);
|
|
674
|
-
interval = isNullOrUndefined(interval) ? ruleObject.interval : interval;
|
|
675
|
-
tempDate.setFullYear(startDate.getFullYear());
|
|
676
|
-
tempDate.setMonth(startDate.getMonth());
|
|
677
|
-
tempDate.setDate(startDate.getDate());
|
|
678
|
-
if (ruleObject.month.length) {
|
|
679
|
-
monthInit++;
|
|
680
|
-
monthInit = monthInit % ruleObject.month.length;
|
|
681
|
-
calendarUtil.setMonth(tempDate, ruleObject.month[parseInt(monthInit.toString(), 10)], 1);
|
|
682
|
-
if (monthInit === 0) {
|
|
683
|
-
calendarUtil.addYears(tempDate, interval, ruleObject.month[0]);
|
|
684
|
-
}
|
|
685
|
-
} else {
|
|
686
|
-
if (beginDate && (beginDate.getFullYear() < tempDate.getFullYear())) {
|
|
687
|
-
monthData = tempDate.getMonth() - 1;
|
|
688
|
-
}
|
|
689
|
-
calendarUtil.setValidDate(tempDate, interval, 1, monthData, beginDate);
|
|
690
|
-
}
|
|
691
|
-
return monthInit;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* To get month collection when BYDAY property having more than one value in list.
|
|
696
|
-
*
|
|
697
|
-
* @param {Date} startDate Accepts the strat date
|
|
698
|
-
* @param {Date} endDate Accepts the end date
|
|
699
|
-
* @param {number[]} data Accepts the collection of dates
|
|
700
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
701
|
-
* @returns {void}
|
|
702
|
-
* @private
|
|
703
|
-
*/
|
|
704
|
-
function getMonthCollection(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
705
|
-
const expectedDays: string[] = ruleObject.day;
|
|
706
|
-
let tempDate: Date = new Date(startDate.getTime());
|
|
707
|
-
tempDate = calendarUtil.getMonthStartDate(tempDate);
|
|
708
|
-
let monthCollection: number[][] = [];
|
|
709
|
-
let dateCollection: number[][] = [];
|
|
710
|
-
let dates: number[] = [];
|
|
711
|
-
let index: number;
|
|
712
|
-
let state: boolean;
|
|
713
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
714
|
-
let monthInit: number = 0;
|
|
715
|
-
let beginDate: Date;
|
|
716
|
-
if (ruleObject.month.length) {
|
|
717
|
-
calendarUtil.setMonth(tempDate, ruleObject.month[0], 1);
|
|
718
|
-
}
|
|
719
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
720
|
-
while (compareDates(tempDate, endDate)
|
|
721
|
-
&& (expectedCount && (data.length + ruleObject.recExceptionCount) < expectedCount)) {
|
|
722
|
-
const currentMonthDate: Date = new Date(tempDate.getTime());
|
|
723
|
-
const isHavingNumber: boolean[] = expectedDays.map((item: string) => HASNUMBER.test(item));
|
|
724
|
-
if (isHavingNumber.indexOf(true) > -1) {
|
|
725
|
-
for (let j: number = 0; j <= expectedDays.length - 1; j++) {
|
|
726
|
-
const expectedDaysArray: string[] = expectedDays[parseInt(j.toString(), 10)].match(SPLITNUMBERANDSTRING);
|
|
727
|
-
const position: number = parseInt(expectedDaysArray[0], 10);
|
|
728
|
-
tempDate = new Date(tempDate.getTime());
|
|
729
|
-
tempDate = calendarUtil.getMonthStartDate(tempDate);
|
|
730
|
-
tempDate = getStartDateForWeek(tempDate, expectedDays);
|
|
731
|
-
currentMonthDate.setFullYear(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate());
|
|
732
|
-
while (calendarUtil.isSameYear(currentMonthDate, tempDate) && calendarUtil.isSameMonth(currentMonthDate, tempDate)) {
|
|
733
|
-
if (expectedDaysArray[expectedDaysArray.length - 1] === DAYINDEX[currentMonthDate.getDay()]) {
|
|
734
|
-
monthCollection.push([currentMonthDate.getTime()]);
|
|
735
|
-
}
|
|
736
|
-
currentMonthDate.setDate(currentMonthDate.getDate() + (1));
|
|
737
|
-
}
|
|
738
|
-
currentMonthDate.setDate(currentMonthDate.getDate() - (1));
|
|
739
|
-
if (expectedDaysArray[0].indexOf('-') > -1) {
|
|
740
|
-
index = monthCollection.length - (-1 * position);
|
|
741
|
-
} else {
|
|
742
|
-
index = position - 1;
|
|
743
|
-
}
|
|
744
|
-
index = isNaN(index) ? 0 : index;
|
|
745
|
-
if (monthCollection.length > 0) {
|
|
746
|
-
if (isNullOrUndefined(ruleObject.setPosition)) {
|
|
747
|
-
insertDatasIntoExistingCollection(monthCollection, state, startDate, endDate, data, ruleObject, index);
|
|
748
|
-
} else {
|
|
749
|
-
dateCollection = [(filterDateCollectionByIndex(monthCollection, index, dates))];
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
753
|
-
return;
|
|
754
|
-
}
|
|
755
|
-
monthCollection = [];
|
|
756
|
-
}
|
|
757
|
-
if (!isNullOrUndefined(ruleObject.setPosition)) {
|
|
758
|
-
insertDateCollectionBasedonBySetPos(dateCollection, state, startDate, endDate, data, ruleObject);
|
|
759
|
-
dates = [];
|
|
760
|
-
}
|
|
761
|
-
monthInit = setNextValidDate(tempDate, ruleObject, monthInit, beginDate);
|
|
762
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
763
|
-
monthCollection = [];
|
|
764
|
-
} else {
|
|
765
|
-
let weekCollection: number[] = [];
|
|
766
|
-
const dayCycleData: { [key: string]: number } = processWeekDays(expectedDays);
|
|
767
|
-
currentMonthDate.setFullYear(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate());
|
|
768
|
-
const initialDate: Date = new Date(tempDate.getTime());
|
|
769
|
-
beginDate = new Date(tempDate.getTime());
|
|
770
|
-
while (calendarUtil.isSameMonth(initialDate, tempDate)) {
|
|
771
|
-
weekCollection.push(tempDate.getTime());
|
|
772
|
-
if (expectedDays.indexOf(DAYINDEX[tempDate.getDay()]) > -1) {
|
|
773
|
-
monthCollection.push(weekCollection);
|
|
774
|
-
weekCollection = [];
|
|
775
|
-
}
|
|
776
|
-
tempDate.setDate(tempDate.getDate()
|
|
777
|
-
+ dayCycleData[DAYINDEX[tempDate.getDay()]]);
|
|
778
|
-
}
|
|
779
|
-
index = ((ruleObject.setPosition < 1) ? (monthCollection.length + ruleObject.setPosition) : ruleObject.setPosition - 1);
|
|
780
|
-
if (isNullOrUndefined(ruleObject.setPosition)) {
|
|
781
|
-
index = 0;
|
|
782
|
-
const datas: number[] = [];
|
|
783
|
-
for (let week: number = 0; week < monthCollection.length; week++) {
|
|
784
|
-
for (let row: number = 0; row < monthCollection[parseInt(week.toString(), 10)].length; row++) {
|
|
785
|
-
datas.push(monthCollection[parseInt(week.toString(), 10)][parseInt(row.toString(), 10)]);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
monthCollection = [datas];
|
|
789
|
-
}
|
|
790
|
-
if (monthCollection.length > 0) {
|
|
791
|
-
insertDatasIntoExistingCollection(monthCollection, state, startDate, endDate, data, ruleObject, index);
|
|
792
|
-
}
|
|
793
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
794
|
-
return;
|
|
795
|
-
}
|
|
796
|
-
monthInit = setNextValidDate(tempDate, ruleObject, monthInit, beginDate);
|
|
797
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
798
|
-
monthCollection = [];
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
/**
|
|
804
|
-
* To process monday day type for FREQ=MONTHLY
|
|
805
|
-
*
|
|
806
|
-
* @param {Date} startDate Accepts the strat date
|
|
807
|
-
* @param {Date} endDate Accepts the end date
|
|
808
|
-
* @param {number[]} data Accepts the collection of dates
|
|
809
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
810
|
-
* @returns {void}
|
|
811
|
-
* @private
|
|
812
|
-
*/
|
|
813
|
-
function monthlyDayTypeProcessforMonthFreq(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
814
|
-
const expectedDays: string[] = ruleObject.day;
|
|
815
|
-
// When BYDAY property having more than 1 value.
|
|
816
|
-
if (expectedDays.length > 1) {
|
|
817
|
-
getMonthCollection(startDate, endDate, data, ruleObject);
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
let tempDate: Date = new Date(startDate.getTime());
|
|
821
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
822
|
-
let monthCollection: number[][] = [];
|
|
823
|
-
let beginDate: Date;
|
|
824
|
-
let monthInit: number = 0;
|
|
825
|
-
tempDate = calendarUtil.getMonthStartDate(tempDate);
|
|
826
|
-
if (ruleObject.month.length) {
|
|
827
|
-
calendarUtil.setMonth(tempDate, ruleObject.month[0], 1);
|
|
828
|
-
}
|
|
829
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
830
|
-
while (compareDates(tempDate, endDate) && (expectedCount && (data.length + ruleObject.recExceptionCount) < expectedCount)) {
|
|
831
|
-
beginDate = new Date(tempDate.getTime());
|
|
832
|
-
const currentMonthDate: Date = new Date(tempDate.getTime());
|
|
833
|
-
while (calendarUtil.isSameMonth(tempDate, currentMonthDate)) {
|
|
834
|
-
monthCollection.push([currentMonthDate.getTime()]);
|
|
835
|
-
currentMonthDate.setDate(currentMonthDate.getDate() + (7));
|
|
836
|
-
}
|
|
837
|
-
// To filter date collection based on BYDAY Index, then BYSETPOS and to insert datas into existing collection
|
|
838
|
-
insertDateCollectionBasedonIndex(monthCollection, startDate, endDate, data, ruleObject);
|
|
839
|
-
monthInit = setNextValidDate(tempDate, ruleObject, monthInit, beginDate);
|
|
840
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
841
|
-
monthCollection = [];
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* To process monday day type for FREQ=YEARLY
|
|
847
|
-
*
|
|
848
|
-
* @param {Date} startDate Accepts the strat date
|
|
849
|
-
* @param {Date} endDate Accepts the end date
|
|
850
|
-
* @param {number[]} data Accepts the collection of dates
|
|
851
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
852
|
-
* @returns {void}
|
|
853
|
-
* @private
|
|
854
|
-
*/
|
|
855
|
-
function monthlyDayTypeProcess(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
856
|
-
const expectedDays: string[] = ruleObject.day;
|
|
857
|
-
const isHavingNumber: boolean[] = expectedDays.map((item: string) => HASNUMBER.test(item));
|
|
858
|
-
// If BYDAY property having more than 1 value in list
|
|
859
|
-
if (expectedDays.length > 1 && isHavingNumber.indexOf(true) > -1) {
|
|
860
|
-
processDateCollectionforByDayWithInteger(startDate, endDate, data, ruleObject);
|
|
861
|
-
return;
|
|
862
|
-
} else if (ruleObject.month.length && expectedDays.length === 1 && isHavingNumber.indexOf(true) > -1) {
|
|
863
|
-
monthlyDayTypeProcessforMonthFreq(startDate, endDate, data, ruleObject);
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
let tempDate: Date = new Date(startDate.getTime());
|
|
867
|
-
let currentMonthDate: Date;
|
|
868
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
869
|
-
const interval: number = ruleObject.interval;
|
|
870
|
-
let monthCollection: number[][] = [];
|
|
871
|
-
if (ruleObject.month.length) {
|
|
872
|
-
calendarUtil.setMonth(tempDate, ruleObject.month[0], tempDate.getDate());
|
|
873
|
-
}
|
|
874
|
-
// Set the date as start date of the yeear if yearly freq having ByDay property alone
|
|
875
|
-
if (isNullOrUndefined(ruleObject.setPosition) && ruleObject.month.length === 0 && ruleObject.weekNo.length === 0) {
|
|
876
|
-
tempDate.setFullYear(startDate.getFullYear(), 0, 1);
|
|
877
|
-
}
|
|
878
|
-
tempDate = calendarUtil.getMonthStartDate(tempDate);
|
|
879
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
880
|
-
while (compareDates(tempDate, endDate)) {
|
|
881
|
-
currentMonthDate = new Date(tempDate.getTime());
|
|
882
|
-
while (calendarUtil.isSameYear(currentMonthDate, tempDate) &&
|
|
883
|
-
(expectedCount && (data.length + ruleObject.recExceptionCount) <= expectedCount)) {
|
|
884
|
-
currentMonthDate = new Date(tempDate.getTime());
|
|
885
|
-
while (calendarUtil.isSameYear(currentMonthDate, tempDate)) {
|
|
886
|
-
if (ruleObject.month.length === 0 || (ruleObject.month.length > 0
|
|
887
|
-
&& !calendarUtil.checkMonth(tempDate, ruleObject.month))) {
|
|
888
|
-
if (expectedDays.length > 1) {
|
|
889
|
-
if (calendarUtil.compareMonth(currentMonthDate, tempDate)) {
|
|
890
|
-
calendarUtil.setValidDate(tempDate, 1, 1);
|
|
891
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
892
|
-
break;
|
|
893
|
-
}
|
|
894
|
-
if (expectedDays.indexOf(DAYINDEX[currentMonthDate.getDay()]) > -1) {
|
|
895
|
-
monthCollection.push([currentMonthDate.getTime()]);
|
|
896
|
-
}
|
|
897
|
-
currentMonthDate.setDate(currentMonthDate.getDate() + (1));
|
|
898
|
-
} else {
|
|
899
|
-
// If BYDAY property having 1 value in list
|
|
900
|
-
if (currentMonthDate.getFullYear() > tempDate.getFullYear()) {
|
|
901
|
-
calendarUtil.setValidDate(tempDate, 1, 1);
|
|
902
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
903
|
-
break;
|
|
904
|
-
}
|
|
905
|
-
const newstr: string = getDayString(expectedDays[0]);
|
|
906
|
-
if (DAYINDEX[currentMonthDate.getDay()] === newstr
|
|
907
|
-
&& new Date(currentMonthDate.getFullYear(), currentMonthDate.getMonth(), 0)
|
|
908
|
-
> new Date(startDate.getFullYear())) {
|
|
909
|
-
monthCollection.push([currentMonthDate.getTime()]);
|
|
910
|
-
}
|
|
911
|
-
currentMonthDate.setDate(currentMonthDate.getDate() + (7));
|
|
912
|
-
}
|
|
913
|
-
} else {
|
|
914
|
-
calendarUtil.setValidDate(tempDate, 1, 1);
|
|
915
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
916
|
-
break;
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
tempDate.setFullYear(currentMonthDate.getFullYear(), currentMonthDate.getMonth(), currentMonthDate.getDate());
|
|
921
|
-
// To filter date collection based on BYDAY Index, then BYSETPOS and to insert datas into existing collection
|
|
922
|
-
insertDateCollectionBasedonIndex(monthCollection, startDate, endDate, data, ruleObject);
|
|
923
|
-
if (calendarUtil.isLastMonth(tempDate)) {
|
|
924
|
-
calendarUtil.setValidDate(tempDate, 1, 1);
|
|
925
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
926
|
-
}
|
|
927
|
-
tempDate.setFullYear(tempDate.getFullYear() + interval - 1);
|
|
928
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
929
|
-
return;
|
|
930
|
-
}
|
|
931
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
932
|
-
monthCollection = [];
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
/**
|
|
937
|
-
* To process the recurrence rule when BYDAY property having values with integer
|
|
938
|
-
*
|
|
939
|
-
* @param {Date} startDate Accepts the strat date
|
|
940
|
-
* @param {Date} endDate Accepts the end date
|
|
941
|
-
* @param {number[]} data Accepts the collection of dates
|
|
942
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
943
|
-
* @returns {void}
|
|
944
|
-
* @private
|
|
945
|
-
*/
|
|
946
|
-
function processDateCollectionforByDayWithInteger(startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
947
|
-
const expectedDays: string[] = ruleObject.day;
|
|
948
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
949
|
-
let tempDate: Date = new Date(startDate.getTime());
|
|
950
|
-
const interval: number = ruleObject.interval;
|
|
951
|
-
let monthCollection: number[][] = [];
|
|
952
|
-
let dateCollection: number[][] = [];
|
|
953
|
-
let index: number;
|
|
954
|
-
let state: boolean;
|
|
955
|
-
let monthInit: number = 0;
|
|
956
|
-
let currentMonthDate: Date;
|
|
957
|
-
let currentDate: Date;
|
|
958
|
-
let beginDate: Date;
|
|
959
|
-
tempDate = calendarUtil.getMonthStartDate(tempDate);
|
|
960
|
-
let datas: number[] = [];
|
|
961
|
-
if (ruleObject.month.length) {
|
|
962
|
-
calendarUtil.setMonth(tempDate, ruleObject.month[0], 1);
|
|
963
|
-
}
|
|
964
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
965
|
-
while (compareDates(tempDate, endDate)) {
|
|
966
|
-
currentMonthDate = new Date(tempDate.getTime());
|
|
967
|
-
for (let i: number = 0; i <= ruleObject.month.length; i++) {
|
|
968
|
-
for (let j: number = 0; j <= expectedDays.length - 1; j++) {
|
|
969
|
-
tempDate = calendarUtil.getMonthStartDate(tempDate);
|
|
970
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
971
|
-
monthCollection = [];
|
|
972
|
-
while (calendarUtil.isSameYear(currentMonthDate, tempDate) &&
|
|
973
|
-
(expectedCount && (data.length + ruleObject.recExceptionCount) <= expectedCount)) {
|
|
974
|
-
while (calendarUtil.isSameYear(currentMonthDate, tempDate)) {
|
|
975
|
-
currentMonthDate = new Date(tempDate.getTime());
|
|
976
|
-
if (ruleObject.month.length === 0 ||
|
|
977
|
-
(ruleObject.month.length > 0 && ruleObject.month[parseInt(i.toString(), 10)] === calendarUtil.getMonth(currentMonthDate))) {
|
|
978
|
-
const expectedDaysArray: string[] = expectedDays[parseInt(j.toString(), 10)].match(SPLITNUMBERANDSTRING);
|
|
979
|
-
const position: number = parseInt(expectedDaysArray[0], 10);
|
|
980
|
-
currentDate = new Date(tempDate.getTime());
|
|
981
|
-
while (calendarUtil.isSameYear(currentDate, tempDate)
|
|
982
|
-
&& calendarUtil.isSameMonth(currentDate, tempDate)) {
|
|
983
|
-
if (expectedDaysArray[expectedDaysArray.length - 1] === DAYINDEX[currentDate.getDay()]) {
|
|
984
|
-
monthCollection.push([currentDate.getTime()]);
|
|
985
|
-
}
|
|
986
|
-
currentDate.setDate(currentDate.getDate() + (1));
|
|
987
|
-
}
|
|
988
|
-
currentDate.setDate(currentDate.getDate() - (1));
|
|
989
|
-
if (expectedDaysArray[0].indexOf('-') > -1) {
|
|
990
|
-
index = monthCollection.length - (-1 * position);
|
|
991
|
-
} else {
|
|
992
|
-
index = position - 1;
|
|
993
|
-
}
|
|
994
|
-
index = isNaN(index) ? 0 : index;
|
|
995
|
-
}
|
|
996
|
-
monthInit = setNextValidDate(tempDate, ruleObject, monthInit, beginDate, 1);
|
|
997
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
tempDate = j === 0 && currentDate ? new Date(currentDate.getTime()) : new Date(currentMonthDate.getTime());
|
|
1001
|
-
if (monthCollection.length > 0) {
|
|
1002
|
-
if (isNullOrUndefined(ruleObject.setPosition)) {
|
|
1003
|
-
insertDatasIntoExistingCollection(monthCollection, state, startDate, endDate, data, ruleObject, index);
|
|
1004
|
-
} else {
|
|
1005
|
-
dateCollection = [(filterDateCollectionByIndex(monthCollection, index, datas))];
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
if (expectedCount && (data.length + ruleObject.recExceptionCount) >= expectedCount) {
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
if (!isNullOrUndefined(ruleObject.setPosition)) {
|
|
1014
|
-
insertDateCollectionBasedonBySetPos(dateCollection, state, startDate, endDate, data, ruleObject);
|
|
1015
|
-
datas = [];
|
|
1016
|
-
}
|
|
1017
|
-
if (calendarUtil.isLastMonth(tempDate)) {
|
|
1018
|
-
calendarUtil.setValidDate(tempDate, 1, 1);
|
|
1019
|
-
tempDate.setFullYear(tempDate.getFullYear() + interval - 1);
|
|
1020
|
-
} else {
|
|
1021
|
-
tempDate.setFullYear(tempDate.getFullYear() + interval);
|
|
1022
|
-
}
|
|
1023
|
-
tempDate = getStartDateForWeek(tempDate, ruleObject.day);
|
|
1024
|
-
if (ruleObject.month.length) {
|
|
1025
|
-
calendarUtil.setMonth(tempDate, ruleObject.month[0], tempDate.getDate());
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1030
|
-
/**
|
|
1031
|
-
* To get recurrence collection if BYSETPOS is null
|
|
1032
|
-
*
|
|
1033
|
-
* @param {number[]} monthCollection Accepts the month collection dates
|
|
1034
|
-
* @param {string[]} expectedDays Accepts the exception dates
|
|
1035
|
-
* @returns {RuleData} Returns the rule data object
|
|
1036
|
-
* @private
|
|
1037
|
-
*/
|
|
1038
|
-
function getRecurrenceCollection(monthCollection: number[][], expectedDays: string[]): RuleData {
|
|
1039
|
-
let index: number;
|
|
1040
|
-
const recurrenceCollectionObject: RuleData = { monthCollection: [], index: 0 };
|
|
1041
|
-
if (expectedDays.length === 1) {
|
|
1042
|
-
// To split numeric value from BYDAY property value
|
|
1043
|
-
const expectedDaysArrays: string[] = expectedDays[0].match(SPLITNUMBERANDSTRING);
|
|
1044
|
-
let arrPosition: number;
|
|
1045
|
-
if (expectedDaysArrays.length > 1) {
|
|
1046
|
-
arrPosition = parseInt(expectedDaysArrays[0], 10);
|
|
1047
|
-
index = ((arrPosition < 1) ? (monthCollection.length + arrPosition) : arrPosition - 1);
|
|
1048
|
-
} else {
|
|
1049
|
-
index = 0;
|
|
1050
|
-
monthCollection = getDateCollectionforBySetPosNull(monthCollection);
|
|
1051
|
-
}
|
|
1052
|
-
} else {
|
|
1053
|
-
index = 0;
|
|
1054
|
-
monthCollection = getDateCollectionforBySetPosNull(monthCollection);
|
|
1055
|
-
}
|
|
1056
|
-
recurrenceCollectionObject.monthCollection = monthCollection;
|
|
1057
|
-
recurrenceCollectionObject.index = index;
|
|
1058
|
-
return recurrenceCollectionObject;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
/**
|
|
1062
|
-
* Internal method to process the data collections
|
|
1063
|
-
*
|
|
1064
|
-
* @param {number[]} dateCollection Accepts the date collections
|
|
1065
|
-
* @param {boolean} state Accepts the state
|
|
1066
|
-
* @param {Date} startDate Accepts the start date
|
|
1067
|
-
* @param {Date} endDate Accepts the end date
|
|
1068
|
-
* @param {number[]} data Accepts the collection of numbers
|
|
1069
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1070
|
-
* @returns {void}
|
|
1071
|
-
* @private
|
|
1072
|
-
*/
|
|
1073
|
-
function insertDataCollection(dateCollection: number[][], state: boolean, startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
1074
|
-
let index: number = ((ruleObject.setPosition < 1) ?
|
|
1075
|
-
(dateCollection.length + ruleObject.setPosition) : ruleObject.setPosition - 1);
|
|
1076
|
-
if (isNullOrUndefined(ruleObject.setPosition)) {
|
|
1077
|
-
index = 0;
|
|
1078
|
-
dateCollection = getDateCollectionforBySetPosNull(dateCollection);
|
|
1079
|
-
}
|
|
1080
|
-
if (dateCollection.length > 0) {
|
|
1081
|
-
insertDatasIntoExistingCollection(dateCollection, state, startDate, endDate, data, ruleObject, index);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
|
|
1085
|
-
/**
|
|
1086
|
-
* To process month collection if BYSETPOS is null
|
|
1087
|
-
*
|
|
1088
|
-
* @param {number[]} monthCollection Accepts the month date collections
|
|
1089
|
-
* @returns {number[]} Returns the month date collections
|
|
1090
|
-
* @private
|
|
1091
|
-
*/
|
|
1092
|
-
function getDateCollectionforBySetPosNull(monthCollection: number[][]): number[][] {
|
|
1093
|
-
const datas: number[] = [];
|
|
1094
|
-
for (let week: number = 0; week < monthCollection.length; week++) {
|
|
1095
|
-
for (let row: number = 0; row < monthCollection[parseInt(week.toString(), 10)].length; row++) {
|
|
1096
|
-
datas.push(new Date(monthCollection[parseInt(week.toString(), 10)][parseInt(row.toString(), 10)]).getTime());
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
monthCollection = datas.length > 0 ? [datas] : [];
|
|
1100
|
-
return monthCollection;
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
/**
|
|
1104
|
-
* To filter date collection based on BYDAY Index, then BYSETPOS and to insert datas into existing collection
|
|
1105
|
-
*
|
|
1106
|
-
* @param {number[]} monthCollection Accepts the month date collections
|
|
1107
|
-
* @param {Date} startDate Accepts the start date
|
|
1108
|
-
* @param {Date} endDate Accepts the end date
|
|
1109
|
-
* @param {number[]} data Accepts the date collections
|
|
1110
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1111
|
-
* @returns {void}
|
|
1112
|
-
* @private
|
|
1113
|
-
*/
|
|
1114
|
-
function insertDateCollectionBasedonIndex(monthCollection: number[][], startDate: Date, endDate: Date, data: number[], ruleObject: RecRule): void {
|
|
1115
|
-
const expectedDays: string[] = ruleObject.day;
|
|
1116
|
-
let state: boolean;
|
|
1117
|
-
let datas: number[] = [];
|
|
1118
|
-
let dateCollection: number[][] = [];
|
|
1119
|
-
const recurrenceCollections: RuleData = getRecurrenceCollection(monthCollection, expectedDays);
|
|
1120
|
-
monthCollection = recurrenceCollections.monthCollection;
|
|
1121
|
-
const index: number = recurrenceCollections.index;
|
|
1122
|
-
if (ruleObject.setPosition != null) {
|
|
1123
|
-
dateCollection = [(filterDateCollectionByIndex(monthCollection, index, datas))];
|
|
1124
|
-
insertDateCollectionBasedonBySetPos(dateCollection, state, startDate, endDate, data, ruleObject);
|
|
1125
|
-
|
|
1126
|
-
} else {
|
|
1127
|
-
if (monthCollection.length > 0) {
|
|
1128
|
-
insertDatasIntoExistingCollection(monthCollection, state, startDate, endDate, data, ruleObject, index);
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
datas = [];
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
/**
|
|
1135
|
-
* To filter date collection when BYDAY property having values with number
|
|
1136
|
-
*
|
|
1137
|
-
* @param {number[]} monthCollection Accepts the date collections
|
|
1138
|
-
* @param {number} index Accepts the index of date collections
|
|
1139
|
-
* @param {number[]} datas Accepts the collection of dates
|
|
1140
|
-
* @returns {number[]} Returns the collection of dates
|
|
1141
|
-
* @private
|
|
1142
|
-
*/
|
|
1143
|
-
function filterDateCollectionByIndex(monthCollection: number[][], index: number, datas: number[]): number[] {
|
|
1144
|
-
for (let week: number = 0; week < monthCollection[parseInt(index.toString(), 10)].length; week++) {
|
|
1145
|
-
datas.push(monthCollection[parseInt(index.toString(), 10)][parseInt(week.toString(), 10)]);
|
|
1146
|
-
}
|
|
1147
|
-
return datas;
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
/**
|
|
1151
|
-
* To insert processed date collection in final array element
|
|
1152
|
-
*
|
|
1153
|
-
* @param {boolean} state Accepts the state of the recurrence rule
|
|
1154
|
-
* @param {Date} startDate Accepts the start date
|
|
1155
|
-
* @param {Date} endDate Accepts the end date
|
|
1156
|
-
* @param {number[]} data Accepts the collection of date
|
|
1157
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1158
|
-
* @param {number} dayData Accepts the date index
|
|
1159
|
-
* @returns {void}
|
|
1160
|
-
* @private
|
|
1161
|
-
*/
|
|
1162
|
-
function insertDateCollection(state: boolean, startDate: Date, endDate: Date, data: number[], ruleObject: RecRule, dayData: number): void {
|
|
1163
|
-
const expectedCount: number = getDateCount(startDate, ruleObject);
|
|
1164
|
-
const chDate: Date = new Date(dayData);
|
|
1165
|
-
state = validateRules(chDate, ruleObject);
|
|
1166
|
-
if ((chDate >= startDate) && compareDates(chDate, endDate) && state
|
|
1167
|
-
&& expectedCount && (data.length + ruleObject.recExceptionCount) < expectedCount) {
|
|
1168
|
-
excludeDateHandler(data, dayData);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
/**
|
|
1173
|
-
* Return the last week number of given month and year.
|
|
1174
|
-
*
|
|
1175
|
-
* @param {number} year Accepts the Year in number format
|
|
1176
|
-
* @param {number} startDayOfWeek Accepts the start date
|
|
1177
|
-
* @param {number[]} monthCollection Accepts the collection of dates
|
|
1178
|
-
* @param {number} week Accepts the week in number format
|
|
1179
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1180
|
-
* @returns {number} returns week number
|
|
1181
|
-
* @private
|
|
1182
|
-
*/
|
|
1183
|
-
function weekCount(year: number, startDayOfWeek: number, monthCollection: number[][], week: number, ruleObject: RecRule): number {
|
|
1184
|
-
const firstDayOfWeek: number = startDayOfWeek || 0;
|
|
1185
|
-
const firstOfMonth: Date = new Date(year, ruleObject.month[0] - 1, 1);
|
|
1186
|
-
const lastOfMonth: Date = new Date(year, ruleObject.month[0], 0);
|
|
1187
|
-
const numberOfDaysInMonth: number = lastOfMonth.getDate();
|
|
1188
|
-
const firstWeekDay: number = (firstOfMonth.getDay() - firstDayOfWeek + 7) % 7;
|
|
1189
|
-
const used: number = firstWeekDay + numberOfDaysInMonth;
|
|
1190
|
-
const count: number = Math.ceil(used / 7) - 1;
|
|
1191
|
-
const dayData: number = monthCollection[parseInt(week.toString(), 10)][parseInt(count.toString(), 10)];
|
|
1192
|
-
const chDate: Date = new Date(dayData);
|
|
1193
|
-
const state: boolean = validateRules(chDate, ruleObject);
|
|
1194
|
-
return (state) ? count : count - 1;
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
/**
|
|
1198
|
-
* To process date collection based on Byset position after process the collection based on BYDAY property value index: EX:BYDAY=1SUm-1SU
|
|
1199
|
-
*
|
|
1200
|
-
* @param {number[]} monthCollection Accepts the collection of dates
|
|
1201
|
-
* @param {boolean} state Accepts the state of the recurrence rule
|
|
1202
|
-
* @param {Date} startDate Accepts the start date
|
|
1203
|
-
* @param {Date} endDate Accepts the end date
|
|
1204
|
-
* @param {number[]} data Accepts the collection of date
|
|
1205
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1206
|
-
* @returns {void}
|
|
1207
|
-
* @private
|
|
1208
|
-
*/
|
|
1209
|
-
function insertDateCollectionBasedonBySetPos
|
|
1210
|
-
(monthCollection: number[][], state: boolean, startDate: Date, endDate: Date, data: number[], ruleObject: RecRule)
|
|
1211
|
-
: void {
|
|
1212
|
-
if (monthCollection.length > 0) {
|
|
1213
|
-
for (let week: number = 0; week < monthCollection.length; week++) {
|
|
1214
|
-
monthCollection[parseInt(week.toString(), 10)].sort();
|
|
1215
|
-
const expectedDays: string[] = ruleObject.day;
|
|
1216
|
-
const isHavingNumber: boolean[] = expectedDays.map((item: string) => HASNUMBER.test(item));
|
|
1217
|
-
const weekIndex: number = (ruleObject.freq === 'YEARLY' && (ruleObject.validRules.indexOf('BYMONTH') > -1) &&
|
|
1218
|
-
!(isHavingNumber.indexOf(true) > -1)) ?
|
|
1219
|
-
weekCount(new Date(monthCollection[0][0]).getFullYear(), 0, monthCollection, week, ruleObject)
|
|
1220
|
-
: (monthCollection[parseInt(week.toString(), 10)].length + ruleObject.setPosition);
|
|
1221
|
-
const index: number = ((ruleObject.setPosition < 1) ? weekIndex : ruleObject.setPosition - 1);
|
|
1222
|
-
const dayData: number = monthCollection[parseInt(week.toString(), 10)][parseInt(index.toString(), 10)];
|
|
1223
|
-
insertDateCollection(state, startDate, endDate, data, ruleObject, dayData);
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
|
|
1228
|
-
/**
|
|
1229
|
-
* To insert datas into existing collection which is processed from previous loop.
|
|
1230
|
-
*
|
|
1231
|
-
* @param {number[]} monthCollection Accepts the collection of dates
|
|
1232
|
-
* @param {boolean} state Accepts the state of the recurrence rule
|
|
1233
|
-
* @param {Date} startDate Accepts the start date
|
|
1234
|
-
* @param {Date} endDate Accepts the end date
|
|
1235
|
-
* @param {number[]} data Accepts the collection of date
|
|
1236
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1237
|
-
* @param {number} index Accepts the index value
|
|
1238
|
-
* @returns {void}
|
|
1239
|
-
* @private
|
|
1240
|
-
*/
|
|
1241
|
-
function insertDatasIntoExistingCollection(monthCollection: number[][], state: boolean, startDate: Date, endDate: Date, data: number[], ruleObject: RecRule, index?: number): void {
|
|
1242
|
-
if (monthCollection.length > 0) {
|
|
1243
|
-
index = !isNullOrUndefined(index) ? index :
|
|
1244
|
-
((ruleObject.setPosition < 1)
|
|
1245
|
-
? (monthCollection.length + ruleObject.setPosition) : ruleObject.setPosition - 1);
|
|
1246
|
-
monthCollection[parseInt(index.toString(), 10)].sort();
|
|
1247
|
-
for (let week: number = 0; week < monthCollection[parseInt(index.toString(), 10)].length; week++) {
|
|
1248
|
-
const dayData: number = monthCollection[parseInt(index.toString(), 10)][parseInt(week.toString(), 10)];
|
|
1249
|
-
insertDateCollection(state, startDate, endDate, data, ruleObject, dayData);
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
/**
|
|
1255
|
-
* Internal method to compare dates
|
|
1256
|
-
*
|
|
1257
|
-
* @param {Date} startDate Accepts the start date
|
|
1258
|
-
* @param {Date} endDate Accepts the end date
|
|
1259
|
-
* @returns {boolean} Returns the result of checking start and end dates
|
|
1260
|
-
* @private
|
|
1261
|
-
*/
|
|
1262
|
-
function compareDates(startDate: Date, endDate: Date): boolean {
|
|
1263
|
-
return endDate ? (startDate <= endDate) : true;
|
|
1264
|
-
}
|
|
1265
|
-
|
|
1266
|
-
/**
|
|
1267
|
-
* Internal method to get day string
|
|
1268
|
-
*
|
|
1269
|
-
* @param {string} expectedDays Accepts the exception date string
|
|
1270
|
-
* @returns {string} Returns the valid string
|
|
1271
|
-
* @private
|
|
1272
|
-
*/
|
|
1273
|
-
function getDayString(expectedDays: string): string {
|
|
1274
|
-
// To get BYDAY value without numeric value
|
|
1275
|
-
const newstr: string = expectedDays.replace(REMOVENUMBERINSTRING, '');
|
|
1276
|
-
return newstr;
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
/**
|
|
1280
|
-
* Internal method to check day index
|
|
1281
|
-
*
|
|
1282
|
-
* @param {number} day Accepts the day index
|
|
1283
|
-
* @param {string[]} expectedDays Accepts the exception dates
|
|
1284
|
-
* @returns {boolean} Returns the index date
|
|
1285
|
-
* @private
|
|
1286
|
-
*/
|
|
1287
|
-
function checkDayIndex(day: number, expectedDays: string[]): boolean {
|
|
1288
|
-
const sortedExpectedDays: string[] = [];
|
|
1289
|
-
expectedDays.forEach((element: string) => {
|
|
1290
|
-
const expectedDaysNumberSplit: string[] = element.match(SPLITNUMBERANDSTRING);
|
|
1291
|
-
if (expectedDaysNumberSplit.length === 2) {
|
|
1292
|
-
sortedExpectedDays.push(expectedDaysNumberSplit[1]);
|
|
1293
|
-
} else {
|
|
1294
|
-
sortedExpectedDays.push(expectedDaysNumberSplit[0]);
|
|
1295
|
-
}
|
|
1296
|
-
});
|
|
1297
|
-
return (sortedExpectedDays.indexOf(DAYINDEX[parseInt(day.toString(), 10)]) === -1);
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
/**
|
|
1301
|
-
* Internal method to get start date of week
|
|
1302
|
-
*
|
|
1303
|
-
* @param {Date} startDate Accepts the start date
|
|
1304
|
-
* @param {string[]} expectedDays Accepts the exception dates
|
|
1305
|
-
* @returns {Date} Return the week start date
|
|
1306
|
-
* @private
|
|
1307
|
-
*/
|
|
1308
|
-
function getStartDateForWeek(startDate: Date, expectedDays: string[]): Date {
|
|
1309
|
-
const tempDate: Date = new Date(startDate.getTime());
|
|
1310
|
-
let newstr: string;
|
|
1311
|
-
if (expectedDays.length > 0) {
|
|
1312
|
-
const expectedDaysArr: string[] = [];
|
|
1313
|
-
for (let i: number = 0; i <= expectedDays.length - 1; i++) {
|
|
1314
|
-
newstr = getDayString(expectedDays[parseInt(i.toString(), 10)]);
|
|
1315
|
-
expectedDaysArr.push(newstr);
|
|
1316
|
-
}
|
|
1317
|
-
if (expectedDaysArr.indexOf(DAYINDEX[tempDate.getDay()]) === -1) {
|
|
1318
|
-
do {
|
|
1319
|
-
tempDate.setDate(tempDate.getDate() + 1);
|
|
1320
|
-
} while (expectedDaysArr.indexOf(DAYINDEX[tempDate.getDay()]) === -1);
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1323
|
-
return tempDate;
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
/**
|
|
1327
|
-
* Method to generate recurrence rule object from given rule
|
|
1328
|
-
*
|
|
1329
|
-
* @param {string} rules Accepts the recurrence rule
|
|
1330
|
-
* @returns {RecRule} Returns the recurrence rule object
|
|
1331
|
-
*/
|
|
1332
|
-
export function extractObjectFromRule(rules: string): RecRule {
|
|
1333
|
-
const ruleObject: RecRule = {
|
|
1334
|
-
freq: null,
|
|
1335
|
-
interval: 1,
|
|
1336
|
-
count: null,
|
|
1337
|
-
until: null,
|
|
1338
|
-
day: [],
|
|
1339
|
-
wkst: null,
|
|
1340
|
-
month: [],
|
|
1341
|
-
weekNo: [],
|
|
1342
|
-
monthDay: [],
|
|
1343
|
-
yearDay: [],
|
|
1344
|
-
setPosition: null,
|
|
1345
|
-
validRules: []
|
|
1346
|
-
};
|
|
1347
|
-
const rulesList: string[] = rules.split(';');
|
|
1348
|
-
let splitData: string[] = [];
|
|
1349
|
-
let temp: string;
|
|
1350
|
-
rulesList.forEach((data: string) => {
|
|
1351
|
-
splitData = data.split('=');
|
|
1352
|
-
switch (splitData[0]) {
|
|
1353
|
-
case 'UNTIL':
|
|
1354
|
-
temp = splitData[1];
|
|
1355
|
-
ruleObject.until = getDateFromRecurrenceDateString(temp);
|
|
1356
|
-
break;
|
|
1357
|
-
case 'BYDAY':
|
|
1358
|
-
ruleObject.day = splitData[1].split(',');
|
|
1359
|
-
ruleObject.validRules.push(splitData[0]);
|
|
1360
|
-
break;
|
|
1361
|
-
case 'BYMONTHDAY':
|
|
1362
|
-
ruleObject.monthDay = splitData[1].split(',').map(Number);
|
|
1363
|
-
ruleObject.validRules.push(splitData[0]);
|
|
1364
|
-
break;
|
|
1365
|
-
case 'BYMONTH':
|
|
1366
|
-
ruleObject.month = splitData[1].split(',').map(Number);
|
|
1367
|
-
ruleObject.validRules.push(splitData[0]);
|
|
1368
|
-
break;
|
|
1369
|
-
case 'BYYEARDAY':
|
|
1370
|
-
ruleObject.yearDay = splitData[1].split(',').map(Number);
|
|
1371
|
-
ruleObject.validRules.push(splitData[0]);
|
|
1372
|
-
break;
|
|
1373
|
-
case 'BYWEEKNO':
|
|
1374
|
-
ruleObject.weekNo = splitData[1].split(',').map(Number);
|
|
1375
|
-
ruleObject.validRules.push(splitData[0]);
|
|
1376
|
-
break;
|
|
1377
|
-
case 'INTERVAL':
|
|
1378
|
-
ruleObject.interval = parseInt(splitData[1], 10);
|
|
1379
|
-
break;
|
|
1380
|
-
case 'COUNT':
|
|
1381
|
-
ruleObject.count = parseInt(splitData[1], 10);
|
|
1382
|
-
break;
|
|
1383
|
-
case 'BYSETPOS':
|
|
1384
|
-
ruleObject.setPosition = parseInt(splitData[1], 10) > 4 ? -1 : parseInt(splitData[1], 10);
|
|
1385
|
-
break;
|
|
1386
|
-
case 'FREQ':
|
|
1387
|
-
ruleObject.freq = <FreqType>splitData[1];
|
|
1388
|
-
break;
|
|
1389
|
-
case 'WKST':
|
|
1390
|
-
ruleObject.wkst = splitData[1];
|
|
1391
|
-
break;
|
|
1392
|
-
}
|
|
1393
|
-
});
|
|
1394
|
-
if ((ruleObject.freq === 'MONTHLY') && (ruleObject.monthDay.length === 0)) {
|
|
1395
|
-
const index: number = ruleObject.validRules.indexOf('BYDAY');
|
|
1396
|
-
ruleObject.validRules.splice(index, 1);
|
|
1397
|
-
}
|
|
1398
|
-
return ruleObject;
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
/**
|
|
1402
|
-
* Internal method to validate proper date
|
|
1403
|
-
*
|
|
1404
|
-
* @param {Date} tempDate Accepts the date value
|
|
1405
|
-
* @param {number} data Accepts the data value
|
|
1406
|
-
* @param {Date} startDate Accepts the start date
|
|
1407
|
-
* @returns {boolean} Returns the result of date validate
|
|
1408
|
-
* @private
|
|
1409
|
-
*/
|
|
1410
|
-
function validateProperDate(tempDate: Date, data: number, startDate: Date): boolean {
|
|
1411
|
-
const maxDate: number = calendarUtil.getMonthDaysCount(tempDate);
|
|
1412
|
-
return (data <= maxDate) && (tempDate >= startDate);
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
/**
|
|
1416
|
-
* Internal method to process week days
|
|
1417
|
-
*
|
|
1418
|
-
* @param {string[]} expectedDays Accepts the expection dates
|
|
1419
|
-
* @returns {Object} Returns the weekdays object
|
|
1420
|
-
* @private
|
|
1421
|
-
*/
|
|
1422
|
-
function processWeekDays(expectedDays: string[]): { [key: string]: number } {
|
|
1423
|
-
const dayCycle: { [key: string]: number } = {};
|
|
1424
|
-
expectedDays.forEach((element: string, index: number) => {
|
|
1425
|
-
if (index === expectedDays.length - 1) {
|
|
1426
|
-
const startIndex: number = dayIndex.indexOf(element);
|
|
1427
|
-
let temp: number = startIndex;
|
|
1428
|
-
while (temp % 7 !== dayIndex.indexOf(expectedDays[0])) {
|
|
1429
|
-
temp++;
|
|
1430
|
-
}
|
|
1431
|
-
dayCycle[`${element}`] = temp - startIndex;
|
|
1432
|
-
} else {
|
|
1433
|
-
dayCycle[`${element}`] = dayIndex.indexOf(expectedDays[(<number>index + 1)]) - dayIndex.indexOf(element);
|
|
1434
|
-
}
|
|
1435
|
-
});
|
|
1436
|
-
return dayCycle;
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
/**
|
|
1440
|
-
* Internal method to check date
|
|
1441
|
-
*
|
|
1442
|
-
* @param {Date} tempDate Accepts the date value
|
|
1443
|
-
* @param {number[]} expectedDate Accepts the exception dates
|
|
1444
|
-
* @returns {boolean} Returns the boolean value
|
|
1445
|
-
* @private
|
|
1446
|
-
*/
|
|
1447
|
-
function checkDate(tempDate: Date, expectedDate: number[]): boolean {
|
|
1448
|
-
const temp: number[] = expectedDate.slice(0);
|
|
1449
|
-
let data: number;
|
|
1450
|
-
const maxDate: number = calendarUtil.getMonthDaysCount(tempDate);
|
|
1451
|
-
data = temp.shift();
|
|
1452
|
-
while (data) {
|
|
1453
|
-
if (data < 0) {
|
|
1454
|
-
data = <number>data + maxDate + 1;
|
|
1455
|
-
}
|
|
1456
|
-
if (data === tempDate.getDate()) {
|
|
1457
|
-
return false;
|
|
1458
|
-
}
|
|
1459
|
-
data = temp.shift();
|
|
1460
|
-
}
|
|
1461
|
-
return true;
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
/**
|
|
1465
|
-
* Internal method to check the year value
|
|
1466
|
-
*
|
|
1467
|
-
* @param {Date} tempDate Accepts the date value
|
|
1468
|
-
* @param {number[]} expectedyearDay Accepts the exception dates in year
|
|
1469
|
-
* @returns {boolean} Returns the boolean value
|
|
1470
|
-
* @private
|
|
1471
|
-
*/
|
|
1472
|
-
function checkYear(tempDate: Date, expectedyearDay: number[]): boolean {
|
|
1473
|
-
const temp: number[] = expectedyearDay.slice(0);
|
|
1474
|
-
let data: number;
|
|
1475
|
-
const yearDay: number = getYearDay(tempDate);
|
|
1476
|
-
data = temp.shift();
|
|
1477
|
-
while (data) {
|
|
1478
|
-
if (data < 0) {
|
|
1479
|
-
data = <number>data + calendarUtil.getYearDaysCount(tempDate, 0) + 1;
|
|
1480
|
-
}
|
|
1481
|
-
if (data === yearDay) {
|
|
1482
|
-
return false;
|
|
1483
|
-
}
|
|
1484
|
-
data = temp.shift();
|
|
1485
|
-
}
|
|
1486
|
-
return true;
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
/**
|
|
1490
|
-
* Internal method to get the year day
|
|
1491
|
-
*
|
|
1492
|
-
* @param {Date} currentDate Accepts the date value
|
|
1493
|
-
* @returns {number} Returns the boolean value
|
|
1494
|
-
* @private
|
|
1495
|
-
*/
|
|
1496
|
-
function getYearDay(currentDate: Date): number {
|
|
1497
|
-
if (!startDateCollection[calendarUtil.getFullYear(currentDate)]) {
|
|
1498
|
-
startDateCollection[calendarUtil.getFullYear(currentDate)] = calendarUtil.getYearLastDate(currentDate, 0);
|
|
1499
|
-
}
|
|
1500
|
-
const tempDate: Date = startDateCollection[calendarUtil.getFullYear(currentDate)];
|
|
1501
|
-
const diff: number = currentDate.getTime() - tempDate.getTime();
|
|
1502
|
-
return Math.ceil(diff / MS_PER_DAY);
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
/**
|
|
1506
|
-
* Internal method to validate monthly rule type
|
|
1507
|
-
*
|
|
1508
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1509
|
-
* @returns {MonthlyType} Returns the monthly type object
|
|
1510
|
-
* @private
|
|
1511
|
-
*/
|
|
1512
|
-
function validateMonthlyRuleType(ruleObject: RecRule): MonthlyType {
|
|
1513
|
-
if (ruleObject.monthDay.length && !ruleObject.day.length) {
|
|
1514
|
-
return 'date';
|
|
1515
|
-
} else if (!ruleObject.monthDay.length && ruleObject.day.length) {
|
|
1516
|
-
return 'day';
|
|
1517
|
-
}
|
|
1518
|
-
return 'both';
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
/**
|
|
1522
|
-
* Internal method to re-order the week days based on first day of week
|
|
1523
|
-
*
|
|
1524
|
-
* @param {string[]} days Accepts the week days value
|
|
1525
|
-
* @returns {void}
|
|
1526
|
-
* @private
|
|
1527
|
-
*/
|
|
1528
|
-
function rotate(days: string[]): void {
|
|
1529
|
-
const data: string = days.shift();
|
|
1530
|
-
days.push(data);
|
|
1531
|
-
}
|
|
1532
|
-
|
|
1533
|
-
/**
|
|
1534
|
-
* Internal method to set first day of week
|
|
1535
|
-
*
|
|
1536
|
-
* @param {string} day Accepts the first day string
|
|
1537
|
-
* @returns {void}
|
|
1538
|
-
* @private
|
|
1539
|
-
*/
|
|
1540
|
-
function setFirstDayOfWeek(day: string): void {
|
|
1541
|
-
while (dayIndex[0] !== day) {
|
|
1542
|
-
rotate(dayIndex);
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
/**
|
|
1547
|
-
* Internal method to validate recurrence rule
|
|
1548
|
-
*
|
|
1549
|
-
* @param {Date} tempDate Accepts the date value
|
|
1550
|
-
* @param {RecRule} ruleObject Accepts the recurrence rule object
|
|
1551
|
-
* @returns {boolean} Returns the boolean value
|
|
1552
|
-
* @private
|
|
1553
|
-
*/
|
|
1554
|
-
function validateRules(tempDate: Date, ruleObject: RecRule): boolean {
|
|
1555
|
-
let state: boolean = true;
|
|
1556
|
-
const expectedDays: string[] = ruleObject.day;
|
|
1557
|
-
const expectedMonth: number[] = ruleObject.month;
|
|
1558
|
-
const expectedDate: number[] = calendarUtil.getExpectedDays(tempDate, ruleObject.monthDay);
|
|
1559
|
-
const expectedyearDay: number[] = ruleObject.yearDay;
|
|
1560
|
-
ruleObject.validRules.forEach((rule: string) => {
|
|
1561
|
-
switch (rule) {
|
|
1562
|
-
case 'BYDAY':
|
|
1563
|
-
if (checkDayIndex(tempDate.getDay(), expectedDays)) {
|
|
1564
|
-
state = false;
|
|
1565
|
-
}
|
|
1566
|
-
break;
|
|
1567
|
-
case 'BYMONTH':
|
|
1568
|
-
if (calendarUtil.checkMonth(tempDate, expectedMonth)) {
|
|
1569
|
-
state = false;
|
|
1570
|
-
}
|
|
1571
|
-
break;
|
|
1572
|
-
case 'BYMONTHDAY':
|
|
1573
|
-
if (checkDate(tempDate, expectedDate)) {
|
|
1574
|
-
state = false;
|
|
1575
|
-
}
|
|
1576
|
-
break;
|
|
1577
|
-
case 'BYYEARDAY':
|
|
1578
|
-
if (checkYear(tempDate, expectedyearDay)) {
|
|
1579
|
-
state = false;
|
|
1580
|
-
}
|
|
1581
|
-
break;
|
|
1582
|
-
}
|
|
1583
|
-
});
|
|
1584
|
-
return state;
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
/**
|
|
1588
|
-
* Internal method to get calendar util
|
|
1589
|
-
*
|
|
1590
|
-
* @param {CalendarType} calendarMode Accepts the calendar type object
|
|
1591
|
-
* @returns {CalendarUtil} Returns the calendar util object
|
|
1592
|
-
* @private
|
|
1593
|
-
*/
|
|
1594
|
-
export function getCalendarUtil(calendarMode: CalendarType): CalendarUtil {
|
|
1595
|
-
if (calendarMode === 'Islamic') {
|
|
1596
|
-
return new Islamic();
|
|
1597
|
-
}
|
|
1598
|
-
return new Gregorian();
|
|
1599
|
-
}
|
|
1600
|
-
|
|
1601
|
-
const startDateCollection: { [key: string]: Date } = {};
|
|
1602
|
-
|
|
1603
|
-
/** @private */
|
|
1604
|
-
export interface RecRule {
|
|
1605
|
-
freq: FreqType;
|
|
1606
|
-
interval: number;
|
|
1607
|
-
count: number;
|
|
1608
|
-
until: Date;
|
|
1609
|
-
day: string[];
|
|
1610
|
-
wkst: string;
|
|
1611
|
-
month: number[];
|
|
1612
|
-
weekNo: number[];
|
|
1613
|
-
monthDay: number[];
|
|
1614
|
-
yearDay: number[];
|
|
1615
|
-
setPosition: number;
|
|
1616
|
-
validRules: string[];
|
|
1617
|
-
recExceptionCount?: number;
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
// Variables which are used for recurrence date generation
|
|
1621
|
-
interface RuleData {
|
|
1622
|
-
monthCollection?: number[][];
|
|
1623
|
-
index?: number;
|
|
1624
|
-
tempDate?: Date;
|
|
1625
|
-
mainDate?: Date;
|
|
1626
|
-
expectedCount?: number;
|
|
1627
|
-
monthInit?: number;
|
|
1628
|
-
date?: number;
|
|
1629
|
-
dateCollection?: number[][];
|
|
1630
|
-
beginDate?: Date;
|
|
1631
|
-
state?: boolean;
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
/** @private */
|
|
1635
|
-
export type FreqType = 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
|
|
1636
|
-
type MonthlyType = 'date' | 'day' | 'both';
|
|
1637
|
-
type YearRuleType = 'MONTH' | 'WEEKNO' | 'YEARDAY';
|
|
1638
|
-
let tempExcludeDate: number[];
|
|
1639
|
-
const dayIndex: string[] = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];
|
|
1640
|
-
let maxOccurrence: number;
|
|
1641
|
-
let tempViewDate: Date;
|
|
1642
|
-
let calendarUtil: CalendarUtil;
|
|
1643
|
-
const DAYINDEX: string[] = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];
|
|
1644
|
-
const MAXOCCURRENCE: number = 43;
|
|
1645
|
-
const WEEKPOS: string[] = ['first', 'second', 'third', 'fourth', 'last'];
|
|
1646
|
-
const TIMES: string = 'summaryTimes';
|
|
1647
|
-
const ON: string = 'summaryOn';
|
|
1648
|
-
const EVERY: string = 'every';
|
|
1649
|
-
const UNTIL: string = 'summaryUntil';
|
|
1650
|
-
const DAYS: string = 'summaryDay';
|
|
1651
|
-
const WEEKS: string = 'summaryWeek';
|
|
1652
|
-
const MONTHS: string = 'summaryMonth';
|
|
1653
|
-
const YEARS: string = 'summaryYear';
|
|
1654
|
-
const DAYINDEXOBJECT: { [key: string]: string } = {
|
|
1655
|
-
SU: 'sun',
|
|
1656
|
-
MO: 'mon',
|
|
1657
|
-
TU: 'tue',
|
|
1658
|
-
WE: 'wed',
|
|
1659
|
-
TH: 'thu',
|
|
1660
|
-
FR: 'fri',
|
|
1661
|
-
SA: 'sat'
|
|
1662
|
-
};
|
|
1663
|
-
|
|
1664
|
-
// To check string has number
|
|
1665
|
-
const HASNUMBER: RegExp = /\d/;
|
|
1666
|
-
|
|
1667
|
-
// To find the numbers in string
|
|
1668
|
-
const REMOVENUMBERINSTRING: RegExp = /[^A-Z]+/;
|
|
1669
|
-
|
|
1670
|
-
// To split number and string
|
|
1671
|
-
const SPLITNUMBERANDSTRING: RegExp = /[a-z]+|[^a-z]+/gi;
|
|
1672
|
-
|
|
1673
|
-
/**
|
|
1674
|
-
* Method to generate string from date
|
|
1675
|
-
*
|
|
1676
|
-
* @param {Date} date Accepts the date value
|
|
1677
|
-
* @returns {string} Returns the string value
|
|
1678
|
-
*/
|
|
1679
|
-
export function getRecurrenceStringFromDate(date: Date): string {
|
|
1680
|
-
return [date.getUTCFullYear(),
|
|
1681
|
-
roundDateValues(date.getUTCMonth() + 1),
|
|
1682
|
-
roundDateValues(date.getUTCDate()),
|
|
1683
|
-
'T',
|
|
1684
|
-
roundDateValues(date.getUTCHours()),
|
|
1685
|
-
roundDateValues(date.getUTCMinutes()),
|
|
1686
|
-
roundDateValues(date.getUTCSeconds()),
|
|
1687
|
-
'Z'].join('');
|
|
1688
|
-
}
|
|
1689
|
-
|
|
1690
|
-
/**
|
|
1691
|
-
* Internal method to round the date values
|
|
1692
|
-
*
|
|
1693
|
-
* @param {string | number} date Accepts the date value in either string or number format
|
|
1694
|
-
* @returns {string} Returns the date value in string format
|
|
1695
|
-
* @private
|
|
1696
|
-
*/
|
|
1697
|
-
function roundDateValues(date: string | number): string {
|
|
1698
|
-
return ('0' + date).slice(-2);
|
|
1699
|
-
}
|