Project

General

Profile

1 61381 k.triantaf
import { Injectable } from "@angular/core";
2
import { IMyDate } from "../interfaces/my-date.interface";
3
import { IMyDateRange } from "../interfaces/my-date-range.interface";
4
import { IMyMonth } from "../interfaces/my-month.interface";
5
import { IMyMonthLabels } from "../interfaces/my-month-labels.interface";
6
7
@Injectable()
8
export class UtilService {
9
    isDateValid(dateStr: string, dateFormat: string, minYear: number, maxYear: number, disableUntil: IMyDate, disableSince: IMyDate, disableWeekends: boolean, disableDays: Array<IMyDate>, disableDateRange: IMyDateRange, monthLabels: IMyMonthLabels, enableDays: Array<IMyDate>): IMyDate {
10
        let returnDate: IMyDate = {day: 0, month: 0, year: 0};
11
        let daysInMonth: Array<number> = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
12
        let isMonthStr: boolean = this.getDatePartIndex(dateFormat, "mmm") !== -1;
13
14
        if (dateStr.length !== dateFormat.length) {
15
            return returnDate;
16
        }
17
18
        let separator: string = this.getDateFormatSeparator(dateFormat);
19
20
        let parts: Array<string> = dateStr.split(separator);
21
        if (parts.length !== 3) {
22
            return returnDate;
23
        }
24
25
        let day: number = this.parseDatePartNumber(dateFormat, dateStr, "dd");
26
        let month: number = isMonthStr ? this.parseDatePartMonthName(dateFormat, dateStr, "mmm", monthLabels) : this.parseDatePartNumber(dateFormat, dateStr, "mm");
27
        let year: number = this.parseDatePartNumber(dateFormat, dateStr, "yyyy");
28
29
        if (day !== -1 && month !== -1 && year !== -1) {
30
            if (year < minYear || year > maxYear || month < 1 || month > 12) {
31
                return returnDate;
32
            }
33
34
            let date: IMyDate = {year: year, month: month, day: day};
35
36
            if (this.isDisabledDay(date, disableUntil, disableSince, disableWeekends, disableDays, disableDateRange, enableDays)) {
37
                return returnDate;
38
            }
39
40
            if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
41
                daysInMonth[1] = 29;
42
            }
43
44
            if (day < 1 || day > daysInMonth[month - 1]) {
45
                return returnDate;
46
            }
47
48
            // Valid date
49
            return date;
50
        }
51
        return returnDate;
52
    }
53
54
    getDateFormatSeparator(dateFormat: string): string {
55
        return dateFormat.replace(/[dmy]/g, "")[0];
56
    }
57
58
    isMonthLabelValid(monthLabel: string, monthLabels: IMyMonthLabels): number {
59
        for (let key = 1; key <= 12; key++) {
60
            if (monthLabel.toLowerCase() === monthLabels[key].toLowerCase()) {
61
                return key;
62
            }
63
        }
64
        return -1;
65
    }
66
67
    isYearLabelValid(yearLabel: number, minYear: number, maxYear: number): number {
68
        if (yearLabel >= minYear && yearLabel <= maxYear) {
69
            return yearLabel;
70
        }
71
        return -1;
72
    }
73
74
    parseDatePartNumber(dateFormat: string, dateString: string, datePart: string): number {
75
        let pos: number = this.getDatePartIndex(dateFormat, datePart);
76
        if (pos !== -1) {
77
            let value: string = dateString.substring(pos, pos + datePart.length);
78
            if (!/^\d+$/.test(value)) {
79
                return -1;
80
            }
81
            return parseInt(value);
82
        }
83
        return -1;
84
    }
85
86
    parseDatePartMonthName(dateFormat: string, dateString: string, datePart: string, monthLabels: IMyMonthLabels): number {
87
        let pos: number = this.getDatePartIndex(dateFormat, datePart);
88
        if (pos !== -1) {
89
            return this.isMonthLabelValid(dateString.substring(pos, pos + datePart.length), monthLabels);
90
        }
91
        return -1;
92
    }
93
94
    getDatePartIndex(dateFormat: string, datePart: string): number {
95
        return dateFormat.indexOf(datePart);
96
    }
97
98
    parseDefaultMonth(monthString: string): IMyMonth {
99
        let month: IMyMonth = {monthTxt: "", monthNbr: 0, year: 0};
100
        if (monthString !== "") {
101
            let split = monthString.split(monthString.match(/[^0-9]/)[0]);
102
            month.monthNbr = split[0].length === 2 ? parseInt(split[0]) : parseInt(split[1]);
103
            month.year = split[0].length === 2 ? parseInt(split[1]) : parseInt(split[0]);
104
        }
105
        return month;
106
    }
107
108
    isDisabledDay(date: IMyDate, disableUntil: IMyDate, disableSince: IMyDate, disableWeekends: boolean, disableDays: Array<IMyDate>, disableDateRange: IMyDateRange, enableDays: Array<IMyDate>): boolean {
109
        for (let obj of enableDays) {
110
            if (obj.year === date.year && obj.month === date.month && obj.day === date.day) {
111
                return false;
112
            }
113
        }
114
115
        let dateMs: number = this.getTimeInMilliseconds(date);
116
        if (this.isInitializedDate(disableUntil) && dateMs <= this.getTimeInMilliseconds(disableUntil)) {
117
            return true;
118
        }
119
120
        if (this.isInitializedDate(disableSince) && dateMs >= this.getTimeInMilliseconds(disableSince)) {
121
            return true;
122
        }
123
124
        if (disableWeekends) {
125
            let dayNbr = this.getDayNumber(date);
126
            if (dayNbr === 0 || dayNbr === 6) {
127
                return true;
128
            }
129
        }
130
131
        for (let obj of disableDays) {
132
            if (obj.year === date.year && obj.month === date.month && obj.day === date.day) {
133
                return true;
134
            }
135
        }
136
137
        if (this.isInitializedDate(disableDateRange.begin) && this.isInitializedDate(disableDateRange.end) && dateMs >= this.getTimeInMilliseconds(disableDateRange.begin) && dateMs <= this.getTimeInMilliseconds(disableDateRange.end)) {
138
            return true;
139
        }
140
        return false;
141
    }
142
143
    getWeekNumber(date: IMyDate): number {
144
        let d: Date = new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0);
145
        d.setDate(d.getDate() + (d.getDay() === 0 ? -3 : 4 - d.getDay()));
146
        return Math.round(((d.getTime() - new Date(d.getFullYear(), 0, 4).getTime()) / 86400000) / 7) + 1;
147
    }
148
149
    isMonthDisabledByDisableUntil(date: IMyDate, disableUntil: IMyDate): boolean {
150
        return this.isInitializedDate(disableUntil) && this.getTimeInMilliseconds(date) <= this.getTimeInMilliseconds(disableUntil);
151
    }
152
153
    isMonthDisabledByDisableSince(date: IMyDate, disableSince: IMyDate): boolean {
154
        return this.isInitializedDate(disableSince) && this.getTimeInMilliseconds(date) >= this.getTimeInMilliseconds(disableSince);
155
    }
156
157
    isInitializedDate(date: IMyDate): boolean {
158
        return date.year !== 0 && date.month !== 0 && date.day !== 0;
159
    }
160
161
    getTimeInMilliseconds(date: IMyDate): number {
162
        return new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0).getTime();
163
    }
164
165
    getDayNumber(date: IMyDate): number {
166
        let d: Date = new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0);
167
        return d.getDay();
168
    }
169
}