• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IgniteUI / igniteui-angular / 26023601418

18 May 2026 08:57AM UTC coverage: 4.854% (-85.3%) from 90.174%
26023601418

Pull #17281

github

web-flow
Merge e7ce7a18e into 5a85df190
Pull Request #17281: feat: Added virtual scroll component and sample implementation

400 of 17347 branches covered (2.31%)

Branch coverage included in aggregate %.

63 of 222 new or added lines in 4 files covered. (28.38%)

27932 existing lines in 341 files now uncovered.

2022 of 32547 relevant lines covered (6.21%)

0.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

30.3
/projects/igniteui-angular/core/src/date-common/util/model.ts
1
import { isDate } from '../../core/utils';
2

3
/* eslint-disable @typescript-eslint/consistent-type-definitions */
4
export type DayParameter = CalendarDay | Date;
5

6
export type CalendarRangeParams = {
7
    start: DayParameter;
8
    end: DayParameter | number;
9
    unit?: DayInterval;
10
    inclusive?: boolean;
11
};
12

13
type CalendarDayParams = {
14
    year: number;
15
    month: number;
16
    date?: number;
17
};
18

19
export type DayInterval = "year" | "quarter" | "month" | "week" | "day";
20

21
export const daysInWeek = 7;
3✔
22
const millisecondsInDay = 86400000;
3✔
23

24
export function toCalendarDay(date: DayParameter) {
UNCOV
25
    return isDate(date) ? CalendarDay.from(date) : date;
×
26
}
27

28
function checkRollover(original: CalendarDay, modified: CalendarDay) {
29
    return original.date !== modified.date
9!
30
        ? modified.set({ date: 0 })
31
        : modified;
32
}
33

34
export class CalendarDay {
35
    private _date!: Date;
36

37
    /** Constructs and returns the current day. */
38
    public static get today() {
39
        return CalendarDay.from(new Date());
27✔
40
    }
41

42
    /** Constructs a new CalendarDay instance from a Date object. */
43
    public static from(date: Date) {
44
        return new CalendarDay({
78✔
45
            year: date.getFullYear(),
46
            month: date.getMonth(),
47
            date: date.getDate(),
48
        });
49
    }
50

51
    constructor(args: CalendarDayParams) {
52
        this._date = new Date(args.year, args.month, args.date ?? 1);
96!
53
    }
54

55
    /** Returns a copy of this instance. */
56
    public clone() {
57
        return CalendarDay.from(this._date);
45✔
58
    }
59

60
    /**
61
     * Returns a new instance with values replaced.
62
     */
63
    public set(args: Partial<CalendarDayParams>) {
64
        return new CalendarDay({
9✔
65
            year: args.year ?? this.year,
18✔
66
            month: args.month ?? this.month,
18✔
67
            date: args.date ?? this.date,
9!
68
        });
69
    }
70

71
    public add(unit: DayInterval, value: number) {
72
        const result = this.clone();
45✔
73
        switch (unit) {
45!
74
            case "year":
UNCOV
75
                result._date.setFullYear(result.year + value);
×
UNCOV
76
                return checkRollover(this, result);
×
77
            case "quarter":
UNCOV
78
                result._date.setMonth(result.month + 3 * value);
×
UNCOV
79
                return checkRollover(this, result);
×
80
            case "month":
81
                result._date.setMonth(result.month + value);
9✔
82
                return checkRollover(this, result);
9✔
83
            case "week":
84
                result._date.setDate(result.date + 7 * value);
6✔
85
                return result;
6✔
86
            case "day":
87
                result._date.setDate(result.date + value);
30✔
88
                return result;
30✔
89
            default:
90
                throw new Error("Invalid interval");
×
91
        }
92
    }
93

94
    /** Returns the day of the week (Sunday = 0). */
95
    public get day() {
UNCOV
96
        return this._date.getDay();
×
97
    }
98

99
    /** Returns the full year. */
100
    public get year() {
101
        return this._date.getFullYear();
9✔
102
    }
103

104
    /** Returns the month. */
105
    public get month() {
106
        return this._date.getMonth();
18✔
107
    }
108

109
    /** Returns the date */
110
    public get date() {
111
        return this._date.getDate();
54✔
112
    }
113

114
    /** Returns the timestamp since epoch in milliseconds. */
115
    public get timestamp() {
UNCOV
116
        return this._date.getTime();
×
117
    }
118

119
    /** Returns the ISO 8601 week number. */
120
    public get week() {
UNCOV
121
        return this.getWeekNumber();
×
122
    }
123

124
    /**
125
     * Gets the week number based on week start day.
126
     * Uses ISO 8601 (first Thursday rule) only when weekStart is Monday (1).
127
     * For other week starts, uses simple counting from January 1st.
128
     */
129
    public getWeekNumber(weekStart: number = 1): number {
×
UNCOV
130
        if (weekStart === 1) {
×
UNCOV
131
            return this.calculateISO8601WeekNumber();
×
132
        } else {
UNCOV
133
            return this.calculateSimpleWeekNumber(weekStart);
×
134
        }
135
    }
136

137
    /**
138
     * Calculates week number using ISO 8601 standard (Monday start, first Thursday rule).
139
     */
140
    private calculateISO8601WeekNumber(): number {
UNCOV
141
        const currentThursday = this.getThursdayOfWeek();
×
UNCOV
142
        const firstWeekThursday = this.getFirstWeekThursday(currentThursday.year);
×
143

UNCOV
144
        const weeksDifference = this.getWeeksDifference(currentThursday, firstWeekThursday);
×
UNCOV
145
        const weekNumber = weeksDifference + 1;
×
146

147
        // Handle dates that belong to the previous year's last week
UNCOV
148
        if (weekNumber <= 0) {
×
149
            return this.getPreviousYearLastWeek(currentThursday.year - 1);
×
150
        }
151

UNCOV
152
        return weekNumber;
×
153
    }
154

155
    /**
156
     * Calculates week number using simple counting from January 1st.
157
     */
158
    private calculateSimpleWeekNumber(weekStart: number): number {
UNCOV
159
        const yearStart = new CalendarDay({ year: this.year, month: 0, date: 1 });
×
UNCOV
160
        const yearStartDay = yearStart.day;
×
161

UNCOV
162
        const daysUntilFirstWeek = (weekStart - yearStartDay + 7) % 7;
×
163

UNCOV
164
        if (daysUntilFirstWeek > 0) {
×
UNCOV
165
            const firstWeekStart = yearStart.add('day', daysUntilFirstWeek);
×
166

UNCOV
167
            if (this.timestamp < firstWeekStart.timestamp) {
×
UNCOV
168
                const prevYear = this.year - 1;
×
UNCOV
169
                const prevYearDec31 = new CalendarDay({ year: prevYear, month: 11, date: 31 });
×
UNCOV
170
                return prevYearDec31.calculateSimpleWeekNumber(weekStart);
×
171
            }
172

UNCOV
173
            const daysSinceFirstWeek = Math.round((this.timestamp - firstWeekStart.timestamp) / millisecondsInDay);
×
UNCOV
174
            return Math.floor(daysSinceFirstWeek / 7) + 1;
×
175
        } else {
UNCOV
176
            const daysSinceYearStart = Math.round((this.timestamp - yearStart.timestamp) / millisecondsInDay);
×
UNCOV
177
            return Math.floor(daysSinceYearStart / 7) + 1;
×
178
        }
179
    }
180

181
    /**
182
     * Gets the Thursday of the current date's week (ISO 8601 helper).
183
     */
184
    private getThursdayOfWeek(): CalendarDay {
UNCOV
185
        const dayOffset = (this.day - 1 + 7) % 7; // Monday start
×
UNCOV
186
        const thursdayOffset = 3; // Thursday is 3 days from Monday
×
UNCOV
187
        return this.add('day', thursdayOffset - dayOffset);
×
188
    }
189

190
    /**
191
     * Gets the Thursday of the first week of the given year (ISO 8601 helper).
192
     */
193
    private getFirstWeekThursday(year: number): CalendarDay {
UNCOV
194
        const january4th = new CalendarDay({ year, month: 0, date: 4 });
×
UNCOV
195
        const dayOffset = (january4th.day - 1 + 7) % 7; // Monday start
×
UNCOV
196
        const thursdayOffset = 3; // Thursday is 3 days from Monday
×
UNCOV
197
        return january4th.add('day', thursdayOffset - dayOffset);
×
198
    }
199

200
    /**
201
     * Calculates the number of weeks between two Thursday dates (ISO 8601 helper).
202
     */
203
    private getWeeksDifference(currentThursday: CalendarDay, firstWeekThursday: CalendarDay): number {
UNCOV
204
        const daysDifference = Math.round((currentThursday.timestamp - firstWeekThursday.timestamp) / millisecondsInDay);
×
UNCOV
205
        return Math.floor(daysDifference / 7);
×
206
    }
207

208
    /**
209
     * Gets the last week number of the previous year (ISO 8601 helper).
210
     */
211
    private getPreviousYearLastWeek(previousYear: number): number {
212
        const december31st = new CalendarDay({ year: previousYear, month: 11, date: 31 });
×
213
        const lastWeekThursday = december31st.getThursdayOfWeek();
×
214
        const firstWeekThursday = this.getFirstWeekThursday(previousYear);
×
215

216
        return this.getWeeksDifference(lastWeekThursday, firstWeekThursday) + 1;
×
217
    }
218

219
    /** Returns the underlying native date instance. */
220
    public get native() {
221
        return new Date(this._date);
39✔
222
    }
223

224
    /**
225
     * Whether the current date is a weekend day.
226
     *
227
     * @remarks
228
     * This is naive, since it does not account for locale specifics.
229
     */
230
    public get weekend() {
UNCOV
231
        return this.day < 1 || this.day > 5;
×
232
    }
233

234
    public equalTo(value: DayParameter) {
UNCOV
235
        return this.timestamp === toCalendarDay(value).timestamp;
×
236
    }
237

238
    public greaterThan(value: DayParameter) {
UNCOV
239
        return this.timestamp > toCalendarDay(value).timestamp;
×
240
    }
241
    public greaterThanOrEqual(value: DayParameter) {
242
        return this.timestamp >= toCalendarDay(value).timestamp;
×
243
    }
244

245
    public lessThan(value: DayParameter) {
UNCOV
246
        return this.timestamp < toCalendarDay(value).timestamp;
×
247
    }
248

249
    public lessThanOrEqual(value: DayParameter) {
UNCOV
250
        return this.timestamp <= toCalendarDay(value).timestamp;
×
251
    }
252

253
    public toString() {
254
        return `${this.native}`;
×
255
    }
256
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc