ts-time-utils 1.1.0 → 2.0.0
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/README.md +458 -12
- package/dist/calculate.d.ts +7 -2
- package/dist/calculate.d.ts.map +1 -1
- package/dist/calculate.js +13 -3
- package/dist/calendar.d.ts +103 -0
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +224 -0
- package/dist/compare.d.ts +217 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/compare.js +417 -0
- package/dist/cron.d.ts +82 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +294 -0
- package/dist/esm/calculate.d.ts +7 -2
- package/dist/esm/calculate.d.ts.map +1 -1
- package/dist/esm/calculate.js +13 -3
- package/dist/esm/calendar.d.ts +103 -0
- package/dist/esm/calendar.d.ts.map +1 -1
- package/dist/esm/calendar.js +224 -0
- package/dist/esm/compare.d.ts +217 -0
- package/dist/esm/compare.d.ts.map +1 -0
- package/dist/esm/compare.js +417 -0
- package/dist/esm/cron.d.ts +82 -0
- package/dist/esm/cron.d.ts.map +1 -0
- package/dist/esm/cron.js +294 -0
- package/dist/esm/fiscal.d.ts +195 -0
- package/dist/esm/fiscal.d.ts.map +1 -0
- package/dist/esm/fiscal.js +295 -0
- package/dist/esm/format.d.ts +65 -0
- package/dist/esm/format.d.ts.map +1 -1
- package/dist/esm/format.js +202 -0
- package/dist/esm/index.d.ts +13 -6
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -6
- package/dist/esm/iterate.d.ts +212 -0
- package/dist/esm/iterate.d.ts.map +1 -0
- package/dist/esm/iterate.js +409 -0
- package/dist/esm/parse.d.ts +45 -0
- package/dist/esm/parse.d.ts.map +1 -1
- package/dist/esm/parse.js +207 -0
- package/dist/esm/timezone.d.ts +52 -0
- package/dist/esm/timezone.d.ts.map +1 -1
- package/dist/esm/timezone.js +171 -0
- package/dist/esm/validate.d.ts +51 -0
- package/dist/esm/validate.d.ts.map +1 -1
- package/dist/esm/validate.js +92 -0
- package/dist/esm/workingHours.d.ts +70 -0
- package/dist/esm/workingHours.d.ts.map +1 -1
- package/dist/esm/workingHours.js +161 -0
- package/dist/fiscal.d.ts +195 -0
- package/dist/fiscal.d.ts.map +1 -0
- package/dist/fiscal.js +295 -0
- package/dist/format.d.ts +65 -0
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +202 -0
- package/dist/index.d.ts +13 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -6
- package/dist/iterate.d.ts +212 -0
- package/dist/iterate.d.ts.map +1 -0
- package/dist/iterate.js +409 -0
- package/dist/parse.d.ts +45 -0
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +207 -0
- package/dist/timezone.d.ts +52 -0
- package/dist/timezone.d.ts.map +1 -1
- package/dist/timezone.js +171 -0
- package/dist/validate.d.ts +51 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +92 -0
- package/dist/workingHours.d.ts +70 -0
- package/dist/workingHours.d.ts.map +1 -1
- package/dist/workingHours.js +161 -0
- package/package.json +30 -11
package/dist/index.js
CHANGED
|
@@ -3,25 +3,25 @@
|
|
|
3
3
|
* Re-exports all functions from individual modules for convenience
|
|
4
4
|
*/
|
|
5
5
|
// Format utilities
|
|
6
|
-
export { formatDuration, timeAgo, formatTime, parseDuration } from './format.js';
|
|
6
|
+
export { formatDuration, timeAgo, formatTime, parseDuration, formatDate, formatDateRange, formatOrdinal, formatDayOrdinal, formatDurationCompact, formatCalendarDate } from './format.js';
|
|
7
7
|
// Calculation utilities
|
|
8
8
|
export { differenceInUnits, addTime, subtractTime, startOf, endOf, isBetween, businessDaysBetween } from './calculate.js';
|
|
9
9
|
// Validation utilities
|
|
10
|
-
export { isValidDate, isLeapYear, isPast, isFuture, isToday, isYesterday, isTomorrow, isSameDay, isWeekend, isWeekday, isValidTimeString, isValidISOString } from './validate.js';
|
|
10
|
+
export { isValidDate, isLeapYear, isPast, isFuture, isToday, isYesterday, isTomorrow, isSameDay, isSameWeek, isSameMonth, isSameYear, isThisWeek, isThisMonth, isThisYear, isWeekend, isWeekday, isBusinessDay, isInLastNDays, isInNextNDays, isValidTimeString, isValidISOString } from './validate.js';
|
|
11
11
|
// Age utilities
|
|
12
12
|
export { calculateAge, getAgeInUnits, getLifeStage, getNextBirthday, getDaysUntilBirthday, isBirthday } from './age.js';
|
|
13
13
|
// Calendar utilities
|
|
14
|
-
export { getWeekNumber, getWeekOfMonth, getQuarter, getDayOfYear, getWeeksInYear, getDaysInMonth, getDaysInYear, getEaster, getMonthsInYear, getDaysInMonthArray, getWeekdaysInMonth, getFirstDayOfMonth, getLastDayOfMonth, getFirstDayOfYear, getLastDayOfYear } from './calendar.js';
|
|
14
|
+
export { getWeekNumber, getWeekOfMonth, getQuarter, getDayOfYear, getWeeksInYear, getDaysInMonth, getDaysInYear, getEaster, getMonthsInYear, getDaysInMonthArray, getWeekdaysInMonth, getFirstDayOfMonth, getLastDayOfMonth, getFirstDayOfYear, getLastDayOfYear, getNthDayOfMonth, getNewYearsDay, getMLKDay, getPresidentsDay, getMemorialDay, getIndependenceDay, getLaborDay, getColumbusDay, getVeteransDay, getThanksgivingDay, getChristmasDay, getGoodFriday, getUSHolidays, isUSHoliday, getUSHolidayName, getStartOfWeek, getEndOfWeek, getWeeksInMonth } from './calendar.js';
|
|
15
15
|
// Parse utilities
|
|
16
|
-
export { parseDate, parseRelativeDate, parseTimeAgo, parseCustomFormat, parseManyFormats } from './parse.js';
|
|
16
|
+
export { parseDate, parseRelativeDate, parseTimeAgo, parseCustomFormat, parseManyFormats, parseISO8601Duration, parseISO8601DurationToMs, parseTime, guessDateFormat, parseAutoFormat, parseRangeEndpoint } from './parse.js';
|
|
17
17
|
// Performance utilities
|
|
18
18
|
export { sleep, timeout, debounce, throttle, retry, createStopwatch, measureTime, measureAsync, benchmark, Stopwatch } from './performance.js';
|
|
19
19
|
// Interval utilities
|
|
20
20
|
export { createInterval, isValidInterval, intervalDuration, intervalContains, intervalsOverlap, intervalIntersection, mergeIntervals, subtractInterval, splitIntervalByDay, totalIntervalCoverage, normalizeIntervals } from './interval.js';
|
|
21
21
|
// Timezone utilities
|
|
22
|
-
export { getTimezoneOffset, formatInTimeZone, getZonedTime, convertDateToZone, isValidTimeZone, COMMON_TIMEZONES, getLocalOffset, compareZoneOffsets, reinterpretAsZone } from './timezone.js';
|
|
22
|
+
export { getTimezoneOffset, formatInTimeZone, getZonedTime, convertDateToZone, isValidTimeZone, COMMON_TIMEZONES, getLocalOffset, compareZoneOffsets, reinterpretAsZone, isDST, getNextDSTTransition, findCommonWorkingHours, getTimezoneAbbreviation, convertBetweenZones, getTimezoneDifferenceHours, isSameTimezone } from './timezone.js';
|
|
23
23
|
// Working hours utilities
|
|
24
|
-
export { DEFAULT_WORKING_HOURS, isWorkingDay, isWorkingTime, nextWorkingTime, workingTimeBetween, addWorkingHours } from './workingHours.js';
|
|
24
|
+
export { DEFAULT_WORKING_HOURS, isWorkingDay, isWorkingTime, nextWorkingTime, workingTimeBetween, addWorkingHours, addWorkingDays, subtractWorkingDays, getNextWorkingDay, getPreviousWorkingDay, getWorkingDaysInMonth, getWorkingDaysInMonthArray, workingDaysBetween, isBreakTime, getWorkDayStart, getWorkDayEnd, getWorkingHoursPerDay } from './workingHours.js';
|
|
25
25
|
// Range preset utilities
|
|
26
26
|
export { today, yesterday, tomorrow, lastNDays, nextNDays, thisWeek, lastWeek, nextWeek, thisMonth, lastMonth, nextMonth, thisYear, lastYear, nextYear, rollingWindowDays, quarterRange, lastQuarter, nextQuarter, RANGE_PRESETS } from './rangePresets.js';
|
|
27
27
|
// Duration utilities
|
|
@@ -42,3 +42,11 @@ export { dateRangeOverlap, hasOverlappingRanges, mergeDateRanges, findGaps, spli
|
|
|
42
42
|
export { parseNaturalDate, parseRelativePhrase, extractDatesFromText, suggestDateFromContext } from './naturalLanguage.js';
|
|
43
43
|
// Constants and types
|
|
44
44
|
export { MILLISECONDS_PER_SECOND, MILLISECONDS_PER_MINUTE, MILLISECONDS_PER_HOUR, MILLISECONDS_PER_DAY, MILLISECONDS_PER_WEEK, MILLISECONDS_PER_MONTH, MILLISECONDS_PER_YEAR, SECONDS_PER_MINUTE, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK } from './constants.js';
|
|
45
|
+
// Cron expression utilities
|
|
46
|
+
export { parseCronExpression, parseCronField, matchesCron, getNextCronDate, getNextCronDates, getPreviousCronDate, isValidCron, describeCron, CRON_PRESETS } from './cron.js';
|
|
47
|
+
// Fiscal year utilities
|
|
48
|
+
export { getFiscalYear, getFiscalQuarter, getFiscalYearStart, getFiscalYearEnd, getFiscalQuarterStart, getFiscalQuarterEnd, isSameFiscalYear, isSameFiscalQuarter, getFiscalMonth, getDaysRemainingInFiscalYear, getDaysElapsedInFiscalYear, getFiscalYearProgress, getFiscalWeek, formatFiscalYear, formatFiscalQuarter, getFiscalPeriodInfo, FISCAL_PRESETS } from './fiscal.js';
|
|
49
|
+
// Date comparison and sorting utilities
|
|
50
|
+
export { compareDates, compareDatesDesc, sortDates, minDate, maxDate, dateExtent, uniqueDates, closestDate, closestFutureDate, closestPastDate, clampDate, isDateInRange, filterDatesInRange, groupDates, groupDatesByYear, groupDatesByMonth, groupDatesByDay, groupDatesByDayOfWeek, medianDate, averageDate, roundDate, snapDate, isChronological, dateSpan, partitionDates, nthDate } from './compare.js';
|
|
51
|
+
// Date iteration utilities
|
|
52
|
+
export { eachDay, eachWeekday, eachWeekend, eachWeek, eachMonth, eachQuarter, eachYear, eachHour, eachMinute, eachDayOfWeek, eachInterval, countDays, countWeekdays, countWeekendDays, countWeeks, countMonths, iterateDates, iterateDays, iterateWeekdays, iterateMonths, filterDays, eachMonthEnd, eachNthDayOfMonth } from './iterate.js';
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Date iteration utilities for generating date sequences
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate an array of dates for each day in a range
|
|
6
|
+
* @param start - Start date (inclusive)
|
|
7
|
+
* @param end - End date (inclusive)
|
|
8
|
+
* @returns Array of dates, one per day
|
|
9
|
+
* @example
|
|
10
|
+
* eachDay(new Date('2024-01-01'), new Date('2024-01-05'))
|
|
11
|
+
* // [Jan 1, Jan 2, Jan 3, Jan 4, Jan 5]
|
|
12
|
+
*/
|
|
13
|
+
export declare function eachDay(start: Date, end: Date): Date[];
|
|
14
|
+
/**
|
|
15
|
+
* Generate an array of dates for each weekday (Mon-Fri) in a range
|
|
16
|
+
* @param start - Start date (inclusive)
|
|
17
|
+
* @param end - End date (inclusive)
|
|
18
|
+
* @returns Array of weekday dates
|
|
19
|
+
* @example
|
|
20
|
+
* eachWeekday(new Date('2024-01-01'), new Date('2024-01-07'))
|
|
21
|
+
* // [Jan 1 (Mon), Jan 2 (Tue), Jan 3 (Wed), Jan 4 (Thu), Jan 5 (Fri)]
|
|
22
|
+
*/
|
|
23
|
+
export declare function eachWeekday(start: Date, end: Date): Date[];
|
|
24
|
+
/**
|
|
25
|
+
* Generate an array of dates for each weekend day (Sat-Sun) in a range
|
|
26
|
+
* @param start - Start date (inclusive)
|
|
27
|
+
* @param end - End date (inclusive)
|
|
28
|
+
* @returns Array of weekend dates
|
|
29
|
+
*/
|
|
30
|
+
export declare function eachWeekend(start: Date, end: Date): Date[];
|
|
31
|
+
/**
|
|
32
|
+
* Generate an array of dates for each week start in a range
|
|
33
|
+
* @param start - Start date (inclusive)
|
|
34
|
+
* @param end - End date (inclusive)
|
|
35
|
+
* @param weekStartsOn - Day week starts on (0=Sunday, 1=Monday, default: 0)
|
|
36
|
+
* @returns Array of week start dates
|
|
37
|
+
* @example
|
|
38
|
+
* eachWeek(new Date('2024-01-01'), new Date('2024-01-31'))
|
|
39
|
+
* // [Jan 7, Jan 14, Jan 21, Jan 28] (Sundays)
|
|
40
|
+
*/
|
|
41
|
+
export declare function eachWeek(start: Date, end: Date, weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6): Date[];
|
|
42
|
+
/**
|
|
43
|
+
* Generate an array of dates for the first day of each month in a range
|
|
44
|
+
* @param start - Start date (inclusive)
|
|
45
|
+
* @param end - End date (inclusive)
|
|
46
|
+
* @returns Array of first-of-month dates
|
|
47
|
+
* @example
|
|
48
|
+
* eachMonth(new Date('2024-01-15'), new Date('2024-04-15'))
|
|
49
|
+
* // [Feb 1, Mar 1, Apr 1]
|
|
50
|
+
*/
|
|
51
|
+
export declare function eachMonth(start: Date, end: Date): Date[];
|
|
52
|
+
/**
|
|
53
|
+
* Generate an array of dates for the first day of each quarter in a range
|
|
54
|
+
* @param start - Start date (inclusive)
|
|
55
|
+
* @param end - End date (inclusive)
|
|
56
|
+
* @returns Array of quarter start dates
|
|
57
|
+
*/
|
|
58
|
+
export declare function eachQuarter(start: Date, end: Date): Date[];
|
|
59
|
+
/**
|
|
60
|
+
* Generate an array of dates for January 1st of each year in a range
|
|
61
|
+
* @param start - Start date (inclusive)
|
|
62
|
+
* @param end - End date (inclusive)
|
|
63
|
+
* @returns Array of year start dates
|
|
64
|
+
*/
|
|
65
|
+
export declare function eachYear(start: Date, end: Date): Date[];
|
|
66
|
+
/**
|
|
67
|
+
* Generate an array of dates at regular hour intervals
|
|
68
|
+
* @param start - Start date/time (inclusive)
|
|
69
|
+
* @param end - End date/time (inclusive)
|
|
70
|
+
* @param step - Hour interval (default: 1)
|
|
71
|
+
* @returns Array of dates at each interval
|
|
72
|
+
* @example
|
|
73
|
+
* eachHour(new Date('2024-01-01T09:00'), new Date('2024-01-01T12:00'))
|
|
74
|
+
* // [9:00, 10:00, 11:00, 12:00]
|
|
75
|
+
*/
|
|
76
|
+
export declare function eachHour(start: Date, end: Date, step?: number): Date[];
|
|
77
|
+
/**
|
|
78
|
+
* Generate an array of dates at regular minute intervals
|
|
79
|
+
* @param start - Start date/time (inclusive)
|
|
80
|
+
* @param end - End date/time (inclusive)
|
|
81
|
+
* @param step - Minute interval (default: 1)
|
|
82
|
+
* @returns Array of dates at each interval
|
|
83
|
+
* @example
|
|
84
|
+
* eachMinute(new Date('2024-01-01T09:00'), new Date('2024-01-01T09:05'))
|
|
85
|
+
* // [9:00, 9:01, 9:02, 9:03, 9:04, 9:05]
|
|
86
|
+
*/
|
|
87
|
+
export declare function eachMinute(start: Date, end: Date, step?: number): Date[];
|
|
88
|
+
/**
|
|
89
|
+
* Generate an array of dates for a specific day of the week in a range
|
|
90
|
+
* @param start - Start date (inclusive)
|
|
91
|
+
* @param end - End date (inclusive)
|
|
92
|
+
* @param dayOfWeek - Day of week (0=Sunday, 1=Monday, ..., 6=Saturday)
|
|
93
|
+
* @returns Array of dates for that day of week
|
|
94
|
+
* @example
|
|
95
|
+
* eachDayOfWeek(new Date('2024-01-01'), new Date('2024-01-31'), 1)
|
|
96
|
+
* // All Mondays in January 2024
|
|
97
|
+
*/
|
|
98
|
+
export declare function eachDayOfWeek(start: Date, end: Date, dayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6): Date[];
|
|
99
|
+
/**
|
|
100
|
+
* Generate dates at a custom interval
|
|
101
|
+
* @param start - Start date (inclusive)
|
|
102
|
+
* @param end - End date (inclusive)
|
|
103
|
+
* @param interval - Interval configuration
|
|
104
|
+
* @returns Array of dates at each interval
|
|
105
|
+
* @example
|
|
106
|
+
* eachInterval(start, end, { days: 3 }) // Every 3 days
|
|
107
|
+
* eachInterval(start, end, { weeks: 2 }) // Every 2 weeks
|
|
108
|
+
* eachInterval(start, end, { hours: 6 }) // Every 6 hours
|
|
109
|
+
*/
|
|
110
|
+
export declare function eachInterval(start: Date, end: Date, interval: {
|
|
111
|
+
years?: number;
|
|
112
|
+
months?: number;
|
|
113
|
+
weeks?: number;
|
|
114
|
+
days?: number;
|
|
115
|
+
hours?: number;
|
|
116
|
+
minutes?: number;
|
|
117
|
+
seconds?: number;
|
|
118
|
+
}): Date[];
|
|
119
|
+
/**
|
|
120
|
+
* Count the number of days in a range
|
|
121
|
+
* @param start - Start date (inclusive)
|
|
122
|
+
* @param end - End date (inclusive)
|
|
123
|
+
* @returns Number of days
|
|
124
|
+
*/
|
|
125
|
+
export declare function countDays(start: Date, end: Date): number;
|
|
126
|
+
/**
|
|
127
|
+
* Count the number of weekdays in a range
|
|
128
|
+
* @param start - Start date (inclusive)
|
|
129
|
+
* @param end - End date (inclusive)
|
|
130
|
+
* @returns Number of weekdays
|
|
131
|
+
*/
|
|
132
|
+
export declare function countWeekdays(start: Date, end: Date): number;
|
|
133
|
+
/**
|
|
134
|
+
* Count the number of weekend days in a range
|
|
135
|
+
* @param start - Start date (inclusive)
|
|
136
|
+
* @param end - End date (inclusive)
|
|
137
|
+
* @returns Number of weekend days
|
|
138
|
+
*/
|
|
139
|
+
export declare function countWeekendDays(start: Date, end: Date): number;
|
|
140
|
+
/**
|
|
141
|
+
* Count the number of weeks (complete or partial) in a range
|
|
142
|
+
* @param start - Start date (inclusive)
|
|
143
|
+
* @param end - End date (inclusive)
|
|
144
|
+
* @returns Number of weeks
|
|
145
|
+
*/
|
|
146
|
+
export declare function countWeeks(start: Date, end: Date): number;
|
|
147
|
+
/**
|
|
148
|
+
* Count the number of months in a range
|
|
149
|
+
* @param start - Start date (inclusive)
|
|
150
|
+
* @param end - End date (inclusive)
|
|
151
|
+
* @returns Number of months (partial months count as 1)
|
|
152
|
+
*/
|
|
153
|
+
export declare function countMonths(start: Date, end: Date): number;
|
|
154
|
+
/**
|
|
155
|
+
* Iterator for lazy date generation (memory efficient for large ranges)
|
|
156
|
+
* @param start - Start date (inclusive)
|
|
157
|
+
* @param end - End date (inclusive)
|
|
158
|
+
* @param step - Step function to advance the date
|
|
159
|
+
* @yields Date objects
|
|
160
|
+
*/
|
|
161
|
+
export declare function iterateDates(start: Date, end: Date, step?: (current: Date) => void): Generator<Date, void, unknown>;
|
|
162
|
+
/**
|
|
163
|
+
* Create a lazy day iterator
|
|
164
|
+
* @param start - Start date
|
|
165
|
+
* @param end - End date
|
|
166
|
+
* @yields Each day in the range
|
|
167
|
+
*/
|
|
168
|
+
export declare function iterateDays(start: Date, end: Date): Generator<Date, void, unknown>;
|
|
169
|
+
/**
|
|
170
|
+
* Create a lazy weekday iterator
|
|
171
|
+
* @param start - Start date
|
|
172
|
+
* @param end - End date
|
|
173
|
+
* @yields Each weekday in the range
|
|
174
|
+
*/
|
|
175
|
+
export declare function iterateWeekdays(start: Date, end: Date): Generator<Date, void, unknown>;
|
|
176
|
+
/**
|
|
177
|
+
* Create a lazy month iterator
|
|
178
|
+
* @param start - Start date
|
|
179
|
+
* @param end - End date
|
|
180
|
+
* @yields First day of each month in the range
|
|
181
|
+
*/
|
|
182
|
+
export declare function iterateMonths(start: Date, end: Date): Generator<Date, void, unknown>;
|
|
183
|
+
/**
|
|
184
|
+
* Generate dates by applying a filter to a range
|
|
185
|
+
* @param start - Start date
|
|
186
|
+
* @param end - End date
|
|
187
|
+
* @param filter - Filter function (return true to include date)
|
|
188
|
+
* @returns Array of filtered dates
|
|
189
|
+
* @example
|
|
190
|
+
* // Get all 15th days of each month
|
|
191
|
+
* filterDays(start, end, d => d.getDate() === 15)
|
|
192
|
+
*/
|
|
193
|
+
export declare function filterDays(start: Date, end: Date, filter: (date: Date) => boolean): Date[];
|
|
194
|
+
/**
|
|
195
|
+
* Generate the last day of each month in a range
|
|
196
|
+
* @param start - Start date
|
|
197
|
+
* @param end - End date
|
|
198
|
+
* @returns Array of last-of-month dates
|
|
199
|
+
*/
|
|
200
|
+
export declare function eachMonthEnd(start: Date, end: Date): Date[];
|
|
201
|
+
/**
|
|
202
|
+
* Generate specific day of each month in a range
|
|
203
|
+
* @param start - Start date
|
|
204
|
+
* @param end - End date
|
|
205
|
+
* @param dayOfMonth - Day of month (1-31, will cap at month's max)
|
|
206
|
+
* @returns Array of dates
|
|
207
|
+
* @example
|
|
208
|
+
* eachNthDayOfMonth(start, end, 15) // 15th of each month
|
|
209
|
+
* eachNthDayOfMonth(start, end, 31) // Last day of short months, 31st otherwise
|
|
210
|
+
*/
|
|
211
|
+
export declare function eachNthDayOfMonth(start: Date, end: Date, dayOfMonth: number): Date[];
|
|
212
|
+
//# sourceMappingURL=iterate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iterate.d.ts","sourceRoot":"","sources":["../src/iterate.ts"],"names":[],"mappings":"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"}
|
package/dist/iterate.js
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Date iteration utilities for generating date sequences
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Generate an array of dates for each day in a range
|
|
6
|
+
* @param start - Start date (inclusive)
|
|
7
|
+
* @param end - End date (inclusive)
|
|
8
|
+
* @returns Array of dates, one per day
|
|
9
|
+
* @example
|
|
10
|
+
* eachDay(new Date('2024-01-01'), new Date('2024-01-05'))
|
|
11
|
+
* // [Jan 1, Jan 2, Jan 3, Jan 4, Jan 5]
|
|
12
|
+
*/
|
|
13
|
+
export function eachDay(start, end) {
|
|
14
|
+
const result = [];
|
|
15
|
+
const current = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
16
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
17
|
+
while (current <= endDate) {
|
|
18
|
+
result.push(new Date(current));
|
|
19
|
+
current.setDate(current.getDate() + 1);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Generate an array of dates for each weekday (Mon-Fri) in a range
|
|
25
|
+
* @param start - Start date (inclusive)
|
|
26
|
+
* @param end - End date (inclusive)
|
|
27
|
+
* @returns Array of weekday dates
|
|
28
|
+
* @example
|
|
29
|
+
* eachWeekday(new Date('2024-01-01'), new Date('2024-01-07'))
|
|
30
|
+
* // [Jan 1 (Mon), Jan 2 (Tue), Jan 3 (Wed), Jan 4 (Thu), Jan 5 (Fri)]
|
|
31
|
+
*/
|
|
32
|
+
export function eachWeekday(start, end) {
|
|
33
|
+
const result = [];
|
|
34
|
+
const current = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
35
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
36
|
+
while (current <= endDate) {
|
|
37
|
+
const day = current.getDay();
|
|
38
|
+
if (day !== 0 && day !== 6) {
|
|
39
|
+
result.push(new Date(current));
|
|
40
|
+
}
|
|
41
|
+
current.setDate(current.getDate() + 1);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generate an array of dates for each weekend day (Sat-Sun) in a range
|
|
47
|
+
* @param start - Start date (inclusive)
|
|
48
|
+
* @param end - End date (inclusive)
|
|
49
|
+
* @returns Array of weekend dates
|
|
50
|
+
*/
|
|
51
|
+
export function eachWeekend(start, end) {
|
|
52
|
+
const result = [];
|
|
53
|
+
const current = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
54
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
55
|
+
while (current <= endDate) {
|
|
56
|
+
const day = current.getDay();
|
|
57
|
+
if (day === 0 || day === 6) {
|
|
58
|
+
result.push(new Date(current));
|
|
59
|
+
}
|
|
60
|
+
current.setDate(current.getDate() + 1);
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate an array of dates for each week start in a range
|
|
66
|
+
* @param start - Start date (inclusive)
|
|
67
|
+
* @param end - End date (inclusive)
|
|
68
|
+
* @param weekStartsOn - Day week starts on (0=Sunday, 1=Monday, default: 0)
|
|
69
|
+
* @returns Array of week start dates
|
|
70
|
+
* @example
|
|
71
|
+
* eachWeek(new Date('2024-01-01'), new Date('2024-01-31'))
|
|
72
|
+
* // [Jan 7, Jan 14, Jan 21, Jan 28] (Sundays)
|
|
73
|
+
*/
|
|
74
|
+
export function eachWeek(start, end, weekStartsOn = 0) {
|
|
75
|
+
const result = [];
|
|
76
|
+
const current = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
77
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
78
|
+
// Move to first week start on or after start date
|
|
79
|
+
const dayDiff = (current.getDay() - weekStartsOn + 7) % 7;
|
|
80
|
+
if (dayDiff > 0) {
|
|
81
|
+
current.setDate(current.getDate() + (7 - dayDiff));
|
|
82
|
+
}
|
|
83
|
+
while (current <= endDate) {
|
|
84
|
+
result.push(new Date(current));
|
|
85
|
+
current.setDate(current.getDate() + 7);
|
|
86
|
+
}
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Generate an array of dates for the first day of each month in a range
|
|
91
|
+
* @param start - Start date (inclusive)
|
|
92
|
+
* @param end - End date (inclusive)
|
|
93
|
+
* @returns Array of first-of-month dates
|
|
94
|
+
* @example
|
|
95
|
+
* eachMonth(new Date('2024-01-15'), new Date('2024-04-15'))
|
|
96
|
+
* // [Feb 1, Mar 1, Apr 1]
|
|
97
|
+
*/
|
|
98
|
+
export function eachMonth(start, end) {
|
|
99
|
+
const result = [];
|
|
100
|
+
const current = new Date(start.getFullYear(), start.getMonth() + 1, 1);
|
|
101
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
102
|
+
while (current <= endDate) {
|
|
103
|
+
result.push(new Date(current));
|
|
104
|
+
current.setMonth(current.getMonth() + 1);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Generate an array of dates for the first day of each quarter in a range
|
|
110
|
+
* @param start - Start date (inclusive)
|
|
111
|
+
* @param end - End date (inclusive)
|
|
112
|
+
* @returns Array of quarter start dates
|
|
113
|
+
*/
|
|
114
|
+
export function eachQuarter(start, end) {
|
|
115
|
+
const result = [];
|
|
116
|
+
// Start from beginning of next quarter after start date
|
|
117
|
+
const startMonth = start.getMonth();
|
|
118
|
+
const nextQuarterMonth = Math.ceil((startMonth + 1) / 3) * 3;
|
|
119
|
+
const current = new Date(nextQuarterMonth > 11 ? start.getFullYear() + 1 : start.getFullYear(), nextQuarterMonth % 12, 1);
|
|
120
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
121
|
+
while (current <= endDate) {
|
|
122
|
+
result.push(new Date(current));
|
|
123
|
+
current.setMonth(current.getMonth() + 3);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Generate an array of dates for January 1st of each year in a range
|
|
129
|
+
* @param start - Start date (inclusive)
|
|
130
|
+
* @param end - End date (inclusive)
|
|
131
|
+
* @returns Array of year start dates
|
|
132
|
+
*/
|
|
133
|
+
export function eachYear(start, end) {
|
|
134
|
+
const result = [];
|
|
135
|
+
const startYear = start.getMonth() === 0 && start.getDate() === 1
|
|
136
|
+
? start.getFullYear()
|
|
137
|
+
: start.getFullYear() + 1;
|
|
138
|
+
const endYear = end.getFullYear();
|
|
139
|
+
for (let year = startYear; year <= endYear; year++) {
|
|
140
|
+
result.push(new Date(year, 0, 1));
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Generate an array of dates at regular hour intervals
|
|
146
|
+
* @param start - Start date/time (inclusive)
|
|
147
|
+
* @param end - End date/time (inclusive)
|
|
148
|
+
* @param step - Hour interval (default: 1)
|
|
149
|
+
* @returns Array of dates at each interval
|
|
150
|
+
* @example
|
|
151
|
+
* eachHour(new Date('2024-01-01T09:00'), new Date('2024-01-01T12:00'))
|
|
152
|
+
* // [9:00, 10:00, 11:00, 12:00]
|
|
153
|
+
*/
|
|
154
|
+
export function eachHour(start, end, step = 1) {
|
|
155
|
+
const result = [];
|
|
156
|
+
const current = new Date(start);
|
|
157
|
+
current.setMinutes(0, 0, 0);
|
|
158
|
+
while (current <= end) {
|
|
159
|
+
result.push(new Date(current));
|
|
160
|
+
current.setHours(current.getHours() + step);
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Generate an array of dates at regular minute intervals
|
|
166
|
+
* @param start - Start date/time (inclusive)
|
|
167
|
+
* @param end - End date/time (inclusive)
|
|
168
|
+
* @param step - Minute interval (default: 1)
|
|
169
|
+
* @returns Array of dates at each interval
|
|
170
|
+
* @example
|
|
171
|
+
* eachMinute(new Date('2024-01-01T09:00'), new Date('2024-01-01T09:05'))
|
|
172
|
+
* // [9:00, 9:01, 9:02, 9:03, 9:04, 9:05]
|
|
173
|
+
*/
|
|
174
|
+
export function eachMinute(start, end, step = 1) {
|
|
175
|
+
const result = [];
|
|
176
|
+
const current = new Date(start);
|
|
177
|
+
current.setSeconds(0, 0);
|
|
178
|
+
while (current <= end) {
|
|
179
|
+
result.push(new Date(current));
|
|
180
|
+
current.setMinutes(current.getMinutes() + step);
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Generate an array of dates for a specific day of the week in a range
|
|
186
|
+
* @param start - Start date (inclusive)
|
|
187
|
+
* @param end - End date (inclusive)
|
|
188
|
+
* @param dayOfWeek - Day of week (0=Sunday, 1=Monday, ..., 6=Saturday)
|
|
189
|
+
* @returns Array of dates for that day of week
|
|
190
|
+
* @example
|
|
191
|
+
* eachDayOfWeek(new Date('2024-01-01'), new Date('2024-01-31'), 1)
|
|
192
|
+
* // All Mondays in January 2024
|
|
193
|
+
*/
|
|
194
|
+
export function eachDayOfWeek(start, end, dayOfWeek) {
|
|
195
|
+
const result = [];
|
|
196
|
+
const current = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
197
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
198
|
+
// Move to first occurrence of dayOfWeek
|
|
199
|
+
const diff = (dayOfWeek - current.getDay() + 7) % 7;
|
|
200
|
+
current.setDate(current.getDate() + diff);
|
|
201
|
+
while (current <= endDate) {
|
|
202
|
+
result.push(new Date(current));
|
|
203
|
+
current.setDate(current.getDate() + 7);
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Generate dates at a custom interval
|
|
209
|
+
* @param start - Start date (inclusive)
|
|
210
|
+
* @param end - End date (inclusive)
|
|
211
|
+
* @param interval - Interval configuration
|
|
212
|
+
* @returns Array of dates at each interval
|
|
213
|
+
* @example
|
|
214
|
+
* eachInterval(start, end, { days: 3 }) // Every 3 days
|
|
215
|
+
* eachInterval(start, end, { weeks: 2 }) // Every 2 weeks
|
|
216
|
+
* eachInterval(start, end, { hours: 6 }) // Every 6 hours
|
|
217
|
+
*/
|
|
218
|
+
export function eachInterval(start, end, interval) {
|
|
219
|
+
const result = [];
|
|
220
|
+
const current = new Date(start);
|
|
221
|
+
while (current <= end) {
|
|
222
|
+
result.push(new Date(current));
|
|
223
|
+
if (interval.years) {
|
|
224
|
+
current.setFullYear(current.getFullYear() + interval.years);
|
|
225
|
+
}
|
|
226
|
+
if (interval.months) {
|
|
227
|
+
current.setMonth(current.getMonth() + interval.months);
|
|
228
|
+
}
|
|
229
|
+
if (interval.weeks) {
|
|
230
|
+
current.setDate(current.getDate() + interval.weeks * 7);
|
|
231
|
+
}
|
|
232
|
+
if (interval.days) {
|
|
233
|
+
current.setDate(current.getDate() + interval.days);
|
|
234
|
+
}
|
|
235
|
+
if (interval.hours) {
|
|
236
|
+
current.setHours(current.getHours() + interval.hours);
|
|
237
|
+
}
|
|
238
|
+
if (interval.minutes) {
|
|
239
|
+
current.setMinutes(current.getMinutes() + interval.minutes);
|
|
240
|
+
}
|
|
241
|
+
if (interval.seconds) {
|
|
242
|
+
current.setSeconds(current.getSeconds() + interval.seconds);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Count the number of days in a range
|
|
249
|
+
* @param start - Start date (inclusive)
|
|
250
|
+
* @param end - End date (inclusive)
|
|
251
|
+
* @returns Number of days
|
|
252
|
+
*/
|
|
253
|
+
export function countDays(start, end) {
|
|
254
|
+
const startDay = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
255
|
+
const endDay = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
256
|
+
return Math.round((endDay.getTime() - startDay.getTime()) / 86400000) + 1;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Count the number of weekdays in a range
|
|
260
|
+
* @param start - Start date (inclusive)
|
|
261
|
+
* @param end - End date (inclusive)
|
|
262
|
+
* @returns Number of weekdays
|
|
263
|
+
*/
|
|
264
|
+
export function countWeekdays(start, end) {
|
|
265
|
+
return eachWeekday(start, end).length;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Count the number of weekend days in a range
|
|
269
|
+
* @param start - Start date (inclusive)
|
|
270
|
+
* @param end - End date (inclusive)
|
|
271
|
+
* @returns Number of weekend days
|
|
272
|
+
*/
|
|
273
|
+
export function countWeekendDays(start, end) {
|
|
274
|
+
return eachWeekend(start, end).length;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Count the number of weeks (complete or partial) in a range
|
|
278
|
+
* @param start - Start date (inclusive)
|
|
279
|
+
* @param end - End date (inclusive)
|
|
280
|
+
* @returns Number of weeks
|
|
281
|
+
*/
|
|
282
|
+
export function countWeeks(start, end) {
|
|
283
|
+
const days = countDays(start, end);
|
|
284
|
+
return Math.ceil(days / 7);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Count the number of months in a range
|
|
288
|
+
* @param start - Start date (inclusive)
|
|
289
|
+
* @param end - End date (inclusive)
|
|
290
|
+
* @returns Number of months (partial months count as 1)
|
|
291
|
+
*/
|
|
292
|
+
export function countMonths(start, end) {
|
|
293
|
+
const yearDiff = end.getFullYear() - start.getFullYear();
|
|
294
|
+
const monthDiff = end.getMonth() - start.getMonth();
|
|
295
|
+
return yearDiff * 12 + monthDiff + 1;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Iterator for lazy date generation (memory efficient for large ranges)
|
|
299
|
+
* @param start - Start date (inclusive)
|
|
300
|
+
* @param end - End date (inclusive)
|
|
301
|
+
* @param step - Step function to advance the date
|
|
302
|
+
* @yields Date objects
|
|
303
|
+
*/
|
|
304
|
+
export function* iterateDates(start, end, step = (d) => d.setDate(d.getDate() + 1)) {
|
|
305
|
+
const current = new Date(start);
|
|
306
|
+
while (current <= end) {
|
|
307
|
+
yield new Date(current);
|
|
308
|
+
step(current);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Create a lazy day iterator
|
|
313
|
+
* @param start - Start date
|
|
314
|
+
* @param end - End date
|
|
315
|
+
* @yields Each day in the range
|
|
316
|
+
*/
|
|
317
|
+
export function* iterateDays(start, end) {
|
|
318
|
+
yield* iterateDates(start, end, (d) => d.setDate(d.getDate() + 1));
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Create a lazy weekday iterator
|
|
322
|
+
* @param start - Start date
|
|
323
|
+
* @param end - End date
|
|
324
|
+
* @yields Each weekday in the range
|
|
325
|
+
*/
|
|
326
|
+
export function* iterateWeekdays(start, end) {
|
|
327
|
+
const current = new Date(start.getFullYear(), start.getMonth(), start.getDate());
|
|
328
|
+
while (current <= end) {
|
|
329
|
+
const day = current.getDay();
|
|
330
|
+
if (day !== 0 && day !== 6) {
|
|
331
|
+
yield new Date(current);
|
|
332
|
+
}
|
|
333
|
+
current.setDate(current.getDate() + 1);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Create a lazy month iterator
|
|
338
|
+
* @param start - Start date
|
|
339
|
+
* @param end - End date
|
|
340
|
+
* @yields First day of each month in the range
|
|
341
|
+
*/
|
|
342
|
+
export function* iterateMonths(start, end) {
|
|
343
|
+
const current = new Date(start.getFullYear(), start.getMonth(), 1);
|
|
344
|
+
while (current <= end) {
|
|
345
|
+
yield new Date(current);
|
|
346
|
+
current.setMonth(current.getMonth() + 1);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Generate dates by applying a filter to a range
|
|
351
|
+
* @param start - Start date
|
|
352
|
+
* @param end - End date
|
|
353
|
+
* @param filter - Filter function (return true to include date)
|
|
354
|
+
* @returns Array of filtered dates
|
|
355
|
+
* @example
|
|
356
|
+
* // Get all 15th days of each month
|
|
357
|
+
* filterDays(start, end, d => d.getDate() === 15)
|
|
358
|
+
*/
|
|
359
|
+
export function filterDays(start, end, filter) {
|
|
360
|
+
const result = [];
|
|
361
|
+
for (const date of iterateDays(start, end)) {
|
|
362
|
+
if (filter(date)) {
|
|
363
|
+
result.push(date);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return result;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Generate the last day of each month in a range
|
|
370
|
+
* @param start - Start date
|
|
371
|
+
* @param end - End date
|
|
372
|
+
* @returns Array of last-of-month dates
|
|
373
|
+
*/
|
|
374
|
+
export function eachMonthEnd(start, end) {
|
|
375
|
+
const result = [];
|
|
376
|
+
const current = new Date(start.getFullYear(), start.getMonth() + 1, 0);
|
|
377
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
378
|
+
while (current <= endDate) {
|
|
379
|
+
result.push(new Date(current));
|
|
380
|
+
current.setMonth(current.getMonth() + 2);
|
|
381
|
+
current.setDate(0); // Last day of previous month
|
|
382
|
+
}
|
|
383
|
+
return result;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Generate specific day of each month in a range
|
|
387
|
+
* @param start - Start date
|
|
388
|
+
* @param end - End date
|
|
389
|
+
* @param dayOfMonth - Day of month (1-31, will cap at month's max)
|
|
390
|
+
* @returns Array of dates
|
|
391
|
+
* @example
|
|
392
|
+
* eachNthDayOfMonth(start, end, 15) // 15th of each month
|
|
393
|
+
* eachNthDayOfMonth(start, end, 31) // Last day of short months, 31st otherwise
|
|
394
|
+
*/
|
|
395
|
+
export function eachNthDayOfMonth(start, end, dayOfMonth) {
|
|
396
|
+
const result = [];
|
|
397
|
+
let current = new Date(start.getFullYear(), start.getMonth(), 1);
|
|
398
|
+
const endDate = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
399
|
+
while (current <= endDate) {
|
|
400
|
+
const daysInMonth = new Date(current.getFullYear(), current.getMonth() + 1, 0).getDate();
|
|
401
|
+
const actualDay = Math.min(dayOfMonth, daysInMonth);
|
|
402
|
+
const date = new Date(current.getFullYear(), current.getMonth(), actualDay);
|
|
403
|
+
if (date >= start && date <= endDate) {
|
|
404
|
+
result.push(date);
|
|
405
|
+
}
|
|
406
|
+
current.setMonth(current.getMonth() + 1);
|
|
407
|
+
}
|
|
408
|
+
return result;
|
|
409
|
+
}
|