ts-time-utils 2.0.0 â 3.0.4
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 +335 -1239
- package/dist/chain.d.ts +269 -0
- package/dist/chain.d.ts.map +1 -0
- package/dist/chain.js +422 -0
- package/dist/esm/chain.d.ts +269 -0
- package/dist/esm/chain.d.ts.map +1 -0
- package/dist/esm/chain.js +422 -0
- package/dist/esm/holidays.d.ts +62 -0
- package/dist/esm/holidays.d.ts.map +1 -0
- package/dist/esm/holidays.js +793 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +6 -0
- package/dist/esm/plugins.d.ts +129 -0
- package/dist/esm/plugins.d.ts.map +1 -0
- package/dist/esm/plugins.js +173 -0
- package/dist/holidays.d.ts +62 -0
- package/dist/holidays.d.ts.map +1 -0
- package/dist/holidays.js +793 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/plugins.d.ts +129 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +173 -0
- package/package.json +35 -10
package/README.md
CHANGED
|
@@ -1,1378 +1,474 @@
|
|
|
1
1
|
# ts-time-utils
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- Full support for count and until limits
|
|
21
|
-
|
|
22
|
-
### â˛ď¸ Countdown & Timer utilities **(NEW!)**
|
|
23
|
-
|
|
24
|
-
- Real-time countdown timers with callbacks
|
|
25
|
-
- Get remaining time broken down by units
|
|
26
|
-
- Format countdowns as human-readable strings
|
|
27
|
-
- Check if dates are expired
|
|
28
|
-
- Calculate progress percentage between dates
|
|
29
|
-
- Deadline tracking with helper methods
|
|
30
|
-
|
|
31
|
-
### đ Date Range utilities **(NEW!)**
|
|
32
|
-
|
|
33
|
-
- Advanced range operations (overlap, intersection, union)
|
|
34
|
-
- Merge overlapping ranges
|
|
35
|
-
- Find gaps between ranges
|
|
36
|
-
- Split ranges into chunks
|
|
37
|
-
- Expand and shrink ranges
|
|
38
|
-
- Subtract ranges from each other
|
|
39
|
-
- Check containment and sort ranges
|
|
40
|
-
|
|
41
|
-
### đŹ Natural Language Parsing **(NEW!)**
|
|
42
|
-
|
|
43
|
-
- Parse human-friendly date strings ("tomorrow", "next Friday", "in 2 weeks")
|
|
44
|
-
- Extract dates from text automatically
|
|
45
|
-
- Context-aware date suggestions ("end of month", "EOY")
|
|
46
|
-
- Support for relative phrases and absolute dates
|
|
47
|
-
- Confidence scoring for extracted dates
|
|
48
|
-
|
|
49
|
-
### âąď¸ Duration utilities
|
|
50
|
-
|
|
51
|
-
- Immutable Duration class with arithmetic operations
|
|
52
|
-
- Create durations from various units and string formats
|
|
53
|
-
- Add, subtract, multiply, divide durations
|
|
54
|
-
- Compare durations and check relationships
|
|
55
|
-
- Format to human-readable strings
|
|
56
|
-
- Utility functions for arrays of durations
|
|
57
|
-
|
|
58
|
-
### đž Serialization utilities
|
|
59
|
-
|
|
60
|
-
- Safe JSON date serialization and deserialization
|
|
61
|
-
- Multiple format support (ISO, epoch, object, custom)
|
|
62
|
-
- Automatic date reviver and replacer functions
|
|
63
|
-
- Timezone-aware serialization options
|
|
64
|
-
- Cross-platform date interchange utilities
|
|
65
|
-
- Validation for ISO strings and epoch timestamps
|
|
66
|
-
|
|
67
|
-
### đ¨ Format utilities
|
|
68
|
-
|
|
69
|
-
- Format milliseconds to human-readable durations
|
|
70
|
-
- Get human-friendly "time ago" strings
|
|
71
|
-
- Parse duration strings back to milliseconds
|
|
72
|
-
- Format time in 12h/24h/ISO formats
|
|
73
|
-
- Custom date formatting with pattern strings (YYYY-MM-DD, etc.)
|
|
74
|
-
- Format date ranges and ordinals
|
|
75
|
-
- Calendar-friendly date formatting ("Today", "Tomorrow", "Monday")
|
|
76
|
-
|
|
77
|
-
### đ§Ž Calculation utilities
|
|
78
|
-
|
|
79
|
-
- Calculate difference between dates in any unit
|
|
80
|
-
- Add/subtract time from dates
|
|
81
|
-
- Get start/end of time periods
|
|
82
|
-
- Business days calculations
|
|
83
|
-
- Check if date is between two dates
|
|
84
|
-
|
|
85
|
-
### â
Validation utilities
|
|
86
|
-
|
|
87
|
-
- Validate dates and time strings
|
|
88
|
-
- Check for leap years, weekends, past/future dates
|
|
89
|
-
- Compare dates (same day, same week, same month, same year)
|
|
90
|
-
- Check relative periods (isThisWeek, isThisMonth, isThisYear)
|
|
91
|
-
- Business day validation with holiday support
|
|
92
|
-
- Check if date is within last/next N days
|
|
93
|
-
|
|
94
|
-
### đ Age utilities
|
|
95
|
-
|
|
96
|
-
- Calculate precise age with years, months, and days
|
|
97
|
-
- Get life stage classifications (infant, child, adult, etc.)
|
|
98
|
-
- Birthday calculations and next birthday finder
|
|
99
|
-
- Check if today is someone's birthday
|
|
100
|
-
|
|
101
|
-
### đ
Calendar utilities
|
|
102
|
-
|
|
103
|
-
- ISO week numbers and week-based calculations
|
|
104
|
-
- Quarter operations and fiscal year support
|
|
105
|
-
- Holiday calculations (Easter, US federal holidays)
|
|
106
|
-
- Days in month/year calculations
|
|
107
|
-
- Get nth occurrence of weekday in month
|
|
108
|
-
- US holiday functions (Thanksgiving, Memorial Day, Labor Day, etc.)
|
|
109
|
-
- Week start/end calculations
|
|
110
|
-
- Calendar grid generation
|
|
111
|
-
|
|
112
|
-
### đ Parse utilities
|
|
113
|
-
|
|
114
|
-
- Advanced date parsing from multiple formats
|
|
115
|
-
- Relative date parsing ("tomorrow", "next week")
|
|
116
|
-
- Custom format parsing with flexible patterns
|
|
117
|
-
- Smart date interpretation
|
|
118
|
-
- ISO 8601 duration parsing (P1Y2M3DT4H5M6S)
|
|
119
|
-
- Time string parsing (14:30, 2:30 PM)
|
|
120
|
-
- Auto-detect date format
|
|
121
|
-
- Parse range endpoints ("end of month", "start of year")
|
|
122
|
-
|
|
123
|
-
### ⥠Performance utilities
|
|
124
|
-
|
|
125
|
-
- Async utilities (sleep, timeout, retry)
|
|
126
|
-
- Performance measurement and benchmarking
|
|
127
|
-
- Stopwatch for timing operations
|
|
128
|
-
- Function utilities (debounce, throttle, memoize)
|
|
129
|
-
|
|
130
|
-
### đ Interval utilities
|
|
131
|
-
|
|
132
|
-
- Create and validate intervals
|
|
133
|
-
- Overlap, intersection, merge, subtraction
|
|
134
|
-
- Split by day and total coverage
|
|
135
|
-
- Normalize and compute durations
|
|
136
|
-
|
|
137
|
-
### đ Timezone utilities
|
|
138
|
-
|
|
139
|
-
- Validate IANA timezones
|
|
140
|
-
- Get offsets and compare zones
|
|
141
|
-
- Format in specific timezone
|
|
142
|
-
- Convert absolute moment to zone components
|
|
143
|
-
- Reinterpret wall-clock times
|
|
144
|
-
- Daylight Saving Time detection
|
|
145
|
-
- Find next DST transition
|
|
146
|
-
- Find common working hours across timezones
|
|
147
|
-
- Convert dates between timezones
|
|
148
|
-
|
|
149
|
-
### đ Working hours utilities
|
|
150
|
-
|
|
151
|
-
- Define working day patterns and breaks
|
|
152
|
-
- Check working day/time
|
|
153
|
-
- Compute working time between dates
|
|
154
|
-
- Add/subtract working hours and days
|
|
155
|
-
- Find next/previous working day
|
|
156
|
-
- Get working days in month
|
|
157
|
-
- Count working days between dates
|
|
158
|
-
- Break time detection
|
|
159
|
-
- Work day start/end times
|
|
160
|
-
|
|
161
|
-
### đŻ Range preset utilities
|
|
162
|
-
|
|
163
|
-
- Today / yesterday / tomorrow
|
|
164
|
-
- Last/next N days windows
|
|
165
|
-
- This/last/next week, month, quarter, year
|
|
166
|
-
- Rolling windows and quarter helpers
|
|
167
|
-
|
|
168
|
-
### đ Locale utilities
|
|
169
|
-
|
|
170
|
-
- Multi-language relative time formatting
|
|
171
|
-
- Locale-specific date and time formatting
|
|
172
|
-
- Support for 40+ locales with built-in configurations
|
|
173
|
-
- Auto-detection of system/browser locale
|
|
174
|
-
- Custom locale registration
|
|
175
|
-
- Internationalization (i18n) support
|
|
176
|
-
- **Locale conversions** - Convert between different locales and detect locale from text
|
|
177
|
-
|
|
178
|
-
### â° Cron utilities **(NEW!)**
|
|
179
|
-
|
|
180
|
-
- Parse and validate cron expressions (5-field format)
|
|
181
|
-
- Check if a date matches a cron expression
|
|
182
|
-
- Get next/previous occurrence dates
|
|
183
|
-
- Get multiple future occurrences
|
|
184
|
-
- Human-readable cron descriptions
|
|
185
|
-
- Common cron presets (every minute, hourly, daily, weekly, etc.)
|
|
186
|
-
- Support for wildcards, ranges, steps, and lists
|
|
187
|
-
|
|
188
|
-
### đ
Fiscal Year utilities **(NEW!)**
|
|
189
|
-
|
|
190
|
-
- Configurable fiscal year start month (calendar, UK/India April, Australia July, US Federal October)
|
|
191
|
-
- Get fiscal year, quarter, month, and week for any date
|
|
192
|
-
- Calculate fiscal year/quarter start and end dates
|
|
193
|
-
- Track fiscal year progress and days elapsed/remaining
|
|
194
|
-
- Format fiscal years and quarters (FY2024, Q1 FY2024, FY2023/24)
|
|
195
|
-
- Common fiscal presets: CALENDAR, UK_INDIA, AUSTRALIA, US_FEDERAL
|
|
196
|
-
|
|
197
|
-
### đ Date Comparison & Sorting **(NEW!)**
|
|
198
|
-
|
|
199
|
-
- Sort date arrays ascending or descending
|
|
200
|
-
- Find min/max/median/average dates in arrays
|
|
201
|
-
- Find closest date to a target (past, future, or any)
|
|
202
|
-
- Clamp dates to ranges
|
|
203
|
-
- Remove duplicate dates with precision control
|
|
204
|
-
- Group dates by year, month, day, or day of week
|
|
205
|
-
- Round and snap dates to intervals (e.g., nearest 15 minutes)
|
|
206
|
-
- Check if dates are in chronological order
|
|
207
|
-
- Partition dates by predicate
|
|
208
|
-
|
|
209
|
-
### đ Date Iteration utilities **(NEW!)**
|
|
210
|
-
|
|
211
|
-
- Generate arrays of dates: `eachDay()`, `eachWeekday()`, `eachWeekend()`
|
|
212
|
-
- Iterate by period: `eachWeek()`, `eachMonth()`, `eachQuarter()`, `eachYear()`
|
|
213
|
-
- Time iteration: `eachHour()`, `eachMinute()`, `eachInterval()`
|
|
214
|
-
- Get specific days: `eachDayOfWeek()`, `eachNthDayOfMonth()`, `eachMonthEnd()`
|
|
215
|
-
- Count functions: `countDays()`, `countWeekdays()`, `countWeekendDays()`
|
|
216
|
-
- Lazy iterators for memory efficiency: `iterateDays()`, `iterateWeekdays()`, `iterateMonths()`
|
|
217
|
-
- Custom filtering with `filterDays()`
|
|
218
|
-
|
|
219
|
-
### đ§ą Constants
|
|
220
|
-
|
|
221
|
-
- Milliseconds & seconds per unit
|
|
222
|
-
- Time unit and formatting option types
|
|
223
|
-
|
|
224
|
-
## đŚ Installation
|
|
3
|
+
A comprehensive TypeScript utility library for time, dates, durations, and calendar operations. Zero dependencies, full tree-shaking support, 320+ functions across 26 categories.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/ts-time-utils)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
**[Live Playground & Docs](https://ts-time-utils.h8frad.work)** | [GitHub](https://github.com/hatefrad/ts-time-utils)
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- **Lightweight** â Import only what you need with tree-shaking support
|
|
13
|
+
- **Zero dependencies** â Pure TypeScript, no external packages
|
|
14
|
+
- **Type-safe** â Full TypeScript support with IntelliSense
|
|
15
|
+
- **Comprehensive** â 320+ functions across 26 utility categories
|
|
16
|
+
- **Fluent API** â Chain operations with the `chain()` API
|
|
17
|
+
- **Extensible** â Plugin system for custom functionality
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
225
20
|
|
|
226
21
|
```bash
|
|
227
22
|
npm install ts-time-utils
|
|
228
23
|
```
|
|
229
24
|
|
|
230
|
-
##
|
|
231
|
-
|
|
232
|
-
### Import everything (not recommended for production)
|
|
25
|
+
## Quick Start
|
|
233
26
|
|
|
234
27
|
```ts
|
|
235
|
-
import { formatDuration, timeAgo,
|
|
236
|
-
```
|
|
28
|
+
import { formatDuration, timeAgo, Duration } from 'ts-time-utils';
|
|
237
29
|
|
|
238
|
-
|
|
30
|
+
// Format milliseconds to readable duration
|
|
31
|
+
formatDuration(3661000); // "1 hour, 1 minute, 1 second"
|
|
239
32
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
import { differenceInUnits, addTime } from "ts-time-utils/calculate";
|
|
243
|
-
import { isValidDate, isLeapYear, isSameWeek } from "ts-time-utils/validate";
|
|
244
|
-
import { calculateAge, getNextBirthday } from "ts-time-utils/age";
|
|
245
|
-
import {
|
|
246
|
-
getWeekNumber,
|
|
247
|
-
getQuarter,
|
|
248
|
-
getUSHolidays,
|
|
249
|
-
} from "ts-time-utils/calendar";
|
|
250
|
-
import { parseDate, parseRelativeDate, parseTime } from "ts-time-utils/parse";
|
|
251
|
-
import { sleep, benchmark, Stopwatch } from "ts-time-utils/performance";
|
|
252
|
-
import { createInterval, mergeIntervals } from "ts-time-utils/interval";
|
|
253
|
-
import { formatInTimeZone, isDST } from "ts-time-utils/timezone";
|
|
254
|
-
import { isWorkingTime, addWorkingDays } from "ts-time-utils/workingHours";
|
|
255
|
-
import { today, lastNDays } from "ts-time-utils/rangePresets";
|
|
256
|
-
import { Duration, createDuration } from "ts-time-utils/duration";
|
|
257
|
-
import { serializeDate, parseJSONWithDates } from "ts-time-utils/serialize";
|
|
258
|
-
import {
|
|
259
|
-
formatRelativeTime,
|
|
260
|
-
formatDateLocale,
|
|
261
|
-
detectLocale,
|
|
262
|
-
} from "ts-time-utils/locale";
|
|
263
|
-
import { createRecurrence, getNextOccurrence } from "ts-time-utils/recurrence";
|
|
264
|
-
import { createCountdown, getRemainingTime } from "ts-time-utils/countdown";
|
|
265
|
-
import { mergeDateRanges, findGaps } from "ts-time-utils/dateRange";
|
|
266
|
-
import {
|
|
267
|
-
parseNaturalDate,
|
|
268
|
-
extractDatesFromText,
|
|
269
|
-
} from "ts-time-utils/naturalLanguage";
|
|
270
|
-
// NEW: Cron utilities
|
|
271
|
-
import {
|
|
272
|
-
matchesCron,
|
|
273
|
-
getNextCronDate,
|
|
274
|
-
isValidCron,
|
|
275
|
-
CRON_PRESETS,
|
|
276
|
-
} from "ts-time-utils/cron";
|
|
277
|
-
// NEW: Fiscal year utilities
|
|
278
|
-
import {
|
|
279
|
-
getFiscalYear,
|
|
280
|
-
getFiscalQuarter,
|
|
281
|
-
getFiscalPeriodInfo,
|
|
282
|
-
FISCAL_PRESETS,
|
|
283
|
-
} from "ts-time-utils/fiscal";
|
|
284
|
-
// NEW: Date comparison & sorting
|
|
285
|
-
import {
|
|
286
|
-
sortDates,
|
|
287
|
-
closestDate,
|
|
288
|
-
groupDatesByMonth,
|
|
289
|
-
snapDate,
|
|
290
|
-
} from "ts-time-utils/compare";
|
|
291
|
-
// NEW: Date iteration
|
|
292
|
-
import {
|
|
293
|
-
eachDay,
|
|
294
|
-
eachWeekday,
|
|
295
|
-
countWeekdays,
|
|
296
|
-
iterateDays,
|
|
297
|
-
} from "ts-time-utils/iterate";
|
|
298
|
-
```
|
|
33
|
+
// Get "time ago" strings
|
|
34
|
+
timeAgo(new Date(Date.now() - 3600000)); // "1 hour ago"
|
|
299
35
|
|
|
300
|
-
|
|
36
|
+
// Duration arithmetic
|
|
37
|
+
const meeting = Duration.fromMinutes(45);
|
|
38
|
+
const buffer = Duration.fromMinutes(15);
|
|
39
|
+
meeting.add(buffer).toString(); // "1h"
|
|
40
|
+
```
|
|
301
41
|
|
|
302
|
-
###
|
|
42
|
+
### Tree-shaking (recommended)
|
|
303
43
|
|
|
304
44
|
```ts
|
|
305
|
-
import {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
frequency: "daily",
|
|
310
|
-
interval: 2,
|
|
311
|
-
startDate: new Date("2024-01-01"),
|
|
312
|
-
count: 10,
|
|
313
|
-
});
|
|
45
|
+
import { formatDuration } from 'ts-time-utils/format';
|
|
46
|
+
import { differenceInUnits } from 'ts-time-utils/calculate';
|
|
47
|
+
import { isValidDate } from 'ts-time-utils/validate';
|
|
48
|
+
```
|
|
314
49
|
|
|
315
|
-
|
|
316
|
-
const allOccurrences = daily.getAllOccurrences();
|
|
50
|
+
---
|
|
317
51
|
|
|
318
|
-
|
|
319
|
-
const weekly = createRecurrence({
|
|
320
|
-
frequency: "weekly",
|
|
321
|
-
interval: 1,
|
|
322
|
-
startDate: new Date("2024-01-01"),
|
|
323
|
-
byWeekday: [1, 3, 5], // Monday, Wednesday, Friday
|
|
324
|
-
});
|
|
52
|
+
## Utility Categories
|
|
325
53
|
|
|
326
|
-
|
|
327
|
-
// "Every week on Monday, Wednesday, Friday"
|
|
54
|
+
### Format
|
|
328
55
|
|
|
329
|
-
|
|
330
|
-
const monthly = createRecurrence({
|
|
331
|
-
frequency: "monthly",
|
|
332
|
-
interval: 1,
|
|
333
|
-
startDate: new Date("2024-01-01"),
|
|
334
|
-
byMonthDay: [15],
|
|
335
|
-
until: new Date("2024-12-31"),
|
|
336
|
-
});
|
|
56
|
+
Format durations, time ago strings, and custom date formats.
|
|
337
57
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
);
|
|
58
|
+
```ts
|
|
59
|
+
import { formatDuration, timeAgo, parseDuration } from 'ts-time-utils/format';
|
|
60
|
+
|
|
61
|
+
formatDuration(65000); // "1 minute, 5 seconds"
|
|
62
|
+
formatDuration(65000, { short: true }); // "1m 5s"
|
|
63
|
+
timeAgo(new Date(Date.now() - 60000)); // "1 minute ago"
|
|
64
|
+
parseDuration('1h 30m'); // 5400000 (ms)
|
|
342
65
|
```
|
|
343
66
|
|
|
344
|
-
###
|
|
67
|
+
### Calculate
|
|
68
|
+
|
|
69
|
+
Date arithmetic, differences, and business day calculations.
|
|
345
70
|
|
|
346
71
|
```ts
|
|
347
|
-
import {
|
|
348
|
-
createCountdown,
|
|
349
|
-
getRemainingTime,
|
|
350
|
-
formatCountdown,
|
|
351
|
-
} from "ts-time-utils/countdown";
|
|
352
|
-
|
|
353
|
-
// Create a countdown timer
|
|
354
|
-
const countdown = createCountdown(new Date("2024-12-31T23:59:59"), {
|
|
355
|
-
onTick: (remaining) => {
|
|
356
|
-
console.log(`${remaining.days}d ${remaining.hours}h ${remaining.minutes}m`);
|
|
357
|
-
},
|
|
358
|
-
onComplete: () => {
|
|
359
|
-
console.log("Happy New Year!");
|
|
360
|
-
},
|
|
361
|
-
interval: 1000, // Update every second
|
|
362
|
-
});
|
|
72
|
+
import { differenceInUnits, addTime, startOf, endOf } from 'ts-time-utils/calculate';
|
|
363
73
|
|
|
364
|
-
|
|
365
|
-
//
|
|
366
|
-
|
|
74
|
+
differenceInUnits(date1, date2, 'days'); // 10
|
|
75
|
+
addTime(new Date(), 5, 'hours'); // 5 hours from now
|
|
76
|
+
startOf(new Date(), 'day'); // 00:00:00 today
|
|
77
|
+
endOf(new Date(), 'month'); // Last moment of month
|
|
78
|
+
```
|
|
367
79
|
|
|
368
|
-
|
|
369
|
-
const remaining = getRemainingTime(new Date("2024-12-31"));
|
|
370
|
-
console.log(`${remaining.days} days, ${remaining.hours} hours remaining`);
|
|
80
|
+
### Validate
|
|
371
81
|
|
|
372
|
-
|
|
373
|
-
const formatted = formatCountdown(new Date("2024-12-31"), {
|
|
374
|
-
units: ["days", "hours", "minutes"],
|
|
375
|
-
short: true,
|
|
376
|
-
});
|
|
377
|
-
// "45d 12h 30m"
|
|
82
|
+
Date validation, checks, and comparisons.
|
|
378
83
|
|
|
379
|
-
|
|
380
|
-
import {
|
|
84
|
+
```ts
|
|
85
|
+
import { isValidDate, isLeapYear, isWeekend, isSameDay } from 'ts-time-utils/validate';
|
|
381
86
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
);
|
|
387
|
-
console.log(`${progress}% complete`); // ~50%
|
|
87
|
+
isValidDate(new Date('2025-13-01')); // false
|
|
88
|
+
isLeapYear(2024); // true
|
|
89
|
+
isWeekend(new Date('2025-09-13')); // true (Saturday)
|
|
90
|
+
isSameDay(date1, date2); // boolean
|
|
388
91
|
```
|
|
389
92
|
|
|
390
|
-
###
|
|
93
|
+
### Duration
|
|
94
|
+
|
|
95
|
+
Immutable Duration class with arithmetic operations.
|
|
391
96
|
|
|
392
97
|
```ts
|
|
393
|
-
import {
|
|
394
|
-
mergeDateRanges,
|
|
395
|
-
findGaps,
|
|
396
|
-
dateRangeOverlap,
|
|
397
|
-
splitRange,
|
|
398
|
-
} from "ts-time-utils/dateRange";
|
|
399
|
-
|
|
400
|
-
// Merge overlapping ranges
|
|
401
|
-
const ranges = [
|
|
402
|
-
{ start: new Date("2024-01-01"), end: new Date("2024-01-10") },
|
|
403
|
-
{ start: new Date("2024-01-05"), end: new Date("2024-01-15") },
|
|
404
|
-
{ start: new Date("2024-01-20"), end: new Date("2024-01-25") },
|
|
405
|
-
];
|
|
98
|
+
import { Duration } from 'ts-time-utils/duration';
|
|
406
99
|
|
|
407
|
-
const
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
// { start: Date('2024-01-20'), end: Date('2024-01-25') }
|
|
411
|
-
// ]
|
|
100
|
+
const d1 = Duration.fromHours(2.5);
|
|
101
|
+
const d2 = Duration.fromString('1h 30m 45s');
|
|
102
|
+
const d3 = Duration.between(startDate, endDate);
|
|
412
103
|
|
|
413
|
-
//
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
{ start: new Date("2024-01-01T14:00"), end: new Date("2024-01-01T16:00") },
|
|
417
|
-
];
|
|
418
|
-
|
|
419
|
-
const gaps = findGaps(busyTimes, {
|
|
420
|
-
start: new Date("2024-01-01T08:00"),
|
|
421
|
-
end: new Date("2024-01-01T18:00"),
|
|
422
|
-
});
|
|
423
|
-
// Returns available time slots
|
|
424
|
-
|
|
425
|
-
// Split into chunks
|
|
426
|
-
const range = {
|
|
427
|
-
start: new Date("2024-01-01"),
|
|
428
|
-
end: new Date("2024-01-31"),
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
const weeks = splitRange(range, 1, "week");
|
|
432
|
-
// Splits January into weekly chunks
|
|
433
|
-
|
|
434
|
-
// Check overlap
|
|
435
|
-
const overlap = dateRangeOverlap(
|
|
436
|
-
{ start: new Date("2024-01-01"), end: new Date("2024-01-15") },
|
|
437
|
-
{ start: new Date("2024-01-10"), end: new Date("2024-01-20") }
|
|
438
|
-
); // true
|
|
104
|
+
d1.add(d2).toString(); // "4h 0m 45s"
|
|
105
|
+
d1.greaterThan(d2); // true
|
|
106
|
+
d1.multiply(2).hours; // 5
|
|
439
107
|
```
|
|
440
108
|
|
|
441
|
-
###
|
|
109
|
+
### Chain API
|
|
442
110
|
|
|
443
|
-
|
|
444
|
-
import {
|
|
445
|
-
parseNaturalDate,
|
|
446
|
-
extractDatesFromText,
|
|
447
|
-
suggestDateFromContext,
|
|
448
|
-
} from "ts-time-utils/naturalLanguage";
|
|
449
|
-
|
|
450
|
-
// Parse natural language dates
|
|
451
|
-
parseNaturalDate("tomorrow at 3pm");
|
|
452
|
-
// Returns Date for tomorrow at 15:00
|
|
453
|
-
|
|
454
|
-
parseNaturalDate("next Friday");
|
|
455
|
-
// Returns Date for next Friday
|
|
456
|
-
|
|
457
|
-
parseNaturalDate("in 2 weeks");
|
|
458
|
-
// Returns Date 2 weeks from now
|
|
459
|
-
|
|
460
|
-
parseNaturalDate("3 days ago");
|
|
461
|
-
// Returns Date 3 days ago
|
|
462
|
-
|
|
463
|
-
// Extract dates from text
|
|
464
|
-
const text = "Meeting tomorrow at 3pm and lunch next Friday at noon";
|
|
465
|
-
const dates = extractDatesFromText(text);
|
|
466
|
-
// [
|
|
467
|
-
// { date: Date(...), text: 'tomorrow at 3pm', index: 8, confidence: 0.9 },
|
|
468
|
-
// { date: Date(...), text: 'next Friday at noon', index: 35, confidence: 0.85 }
|
|
469
|
-
// ]
|
|
470
|
-
|
|
471
|
-
// Context-aware suggestions
|
|
472
|
-
const suggestions = suggestDateFromContext("deadline is end of month");
|
|
473
|
-
// [{ date: Date(last day of current month), text: 'end of month', confidence: 0.85 }]
|
|
474
|
-
|
|
475
|
-
// Supported phrases:
|
|
476
|
-
// - "tomorrow", "yesterday", "today"
|
|
477
|
-
// - "next Monday", "last Friday"
|
|
478
|
-
// - "in 2 hours", "5 days ago"
|
|
479
|
-
// - "end of month/week/year" (or EOM/EOW/EOY)
|
|
480
|
-
// - "beginning of month/year"
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
### Duration Utilities
|
|
111
|
+
Fluent chainable API for date operations.
|
|
484
112
|
|
|
485
113
|
```ts
|
|
486
|
-
import {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
//
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
// Arithmetic operations
|
|
499
|
-
const sum = duration1.add(duration2); // 4 hours
|
|
500
|
-
const diff = duration1.subtract(duration2); // 1 hour
|
|
501
|
-
const doubled = duration1.multiply(2); // 5 hours
|
|
502
|
-
const half = duration1.divide(2); // 1.25 hours
|
|
503
|
-
|
|
504
|
-
// Comparisons
|
|
505
|
-
duration1.equals(duration2); // false
|
|
506
|
-
duration1.greaterThan(duration2); // true
|
|
507
|
-
duration1.compareTo(duration2); // 1
|
|
508
|
-
|
|
509
|
-
// Conversions and formatting
|
|
510
|
-
duration1.hours; // 2.5
|
|
511
|
-
duration1.minutes; // 150
|
|
512
|
-
duration1.toString(); // "2h 30m"
|
|
513
|
-
formatDurationString(duration1, { long: true }); // "2 hours, 30 minutes"
|
|
514
|
-
|
|
515
|
-
// Utility functions with arrays
|
|
516
|
-
const durations = [duration1, duration2, duration3];
|
|
517
|
-
const max = maxDuration(...durations);
|
|
518
|
-
const total = sumDurations(...durations);
|
|
519
|
-
const average = averageDuration(...durations);
|
|
114
|
+
import { chain } from 'ts-time-utils/chain';
|
|
115
|
+
|
|
116
|
+
chain(new Date())
|
|
117
|
+
.startOf('day')
|
|
118
|
+
.add(9, 'hours')
|
|
119
|
+
.add(30, 'minutes')
|
|
120
|
+
.toDate(); // Today at 9:30am
|
|
121
|
+
|
|
122
|
+
chain(new Date())
|
|
123
|
+
.add(1, 'week')
|
|
124
|
+
.startOf('week')
|
|
125
|
+
.format('YYYY-MM-DD'); // Next week Monday
|
|
520
126
|
```
|
|
521
127
|
|
|
522
|
-
###
|
|
128
|
+
### Timezone
|
|
129
|
+
|
|
130
|
+
Timezone conversions, DST handling, and zone comparisons.
|
|
523
131
|
|
|
524
132
|
```ts
|
|
525
|
-
import {
|
|
526
|
-
serializeDate,
|
|
527
|
-
deserializeDate,
|
|
528
|
-
parseJSONWithDates,
|
|
529
|
-
stringifyWithDates,
|
|
530
|
-
toEpochTimestamp,
|
|
531
|
-
fromEpochTimestamp,
|
|
532
|
-
toDateObject,
|
|
533
|
-
fromDateObject,
|
|
534
|
-
} from "ts-time-utils/serialize";
|
|
535
|
-
|
|
536
|
-
// Serialize dates in different formats
|
|
537
|
-
const date = new Date("2025-09-14T12:30:45.123Z");
|
|
538
|
-
|
|
539
|
-
const isoString = serializeDate(date, { format: "iso" }); // "2025-09-14T12:30:45.123Z"
|
|
540
|
-
const epochMs = serializeDate(date, { format: "epoch" }); // 1757853045123
|
|
541
|
-
const dateObj = serializeDate(date, { format: "object" }); // {year: 2025, month: 9, ...}
|
|
542
|
-
const custom = serializeDate(date, {
|
|
543
|
-
format: "custom",
|
|
544
|
-
customFormat: "YYYY-MM-DD HH:mm:ss",
|
|
545
|
-
}); // "2025-09-14 12:30:45"
|
|
546
|
-
|
|
547
|
-
// Deserialize from various formats
|
|
548
|
-
const fromISO = deserializeDate("2025-09-14T12:30:45.123Z");
|
|
549
|
-
const fromEpoch = deserializeDate(1757853045123);
|
|
550
|
-
const fromObj = deserializeDate({
|
|
551
|
-
year: 2025,
|
|
552
|
-
month: 9,
|
|
553
|
-
day: 14,
|
|
554
|
-
hour: 12,
|
|
555
|
-
minute: 30,
|
|
556
|
-
second: 45,
|
|
557
|
-
millisecond: 123,
|
|
558
|
-
});
|
|
133
|
+
import { formatInTimeZone, isDST, convertTimezone } from 'ts-time-utils/timezone';
|
|
559
134
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
updatedAt: new Date(),
|
|
565
|
-
metadata: "other data",
|
|
566
|
-
};
|
|
567
|
-
|
|
568
|
-
// Stringify with automatic date serialization
|
|
569
|
-
const jsonString = stringifyWithDates(data, ["createdAt", "updatedAt"], {
|
|
570
|
-
format: "epoch",
|
|
571
|
-
});
|
|
572
|
-
// {"name":"User","createdAt":1757853045123,"updatedAt":1757853045123,"metadata":"other data"}
|
|
135
|
+
formatInTimeZone(date, 'America/New_York');
|
|
136
|
+
isDST(new Date('2025-07-14'), 'America/New_York'); // true
|
|
137
|
+
convertTimezone(date, 'UTC', 'Asia/Tokyo');
|
|
138
|
+
```
|
|
573
139
|
|
|
574
|
-
|
|
575
|
-
const parsed = parseJSONWithDates(jsonString, ["createdAt", "updatedAt"]);
|
|
576
|
-
// parsed.createdAt and parsed.updatedAt are Date objects
|
|
140
|
+
### Calendar
|
|
577
141
|
|
|
578
|
-
|
|
579
|
-
const timestamp = toEpochTimestamp(date, "seconds"); // 1757853045
|
|
580
|
-
const restoredDate = fromEpochTimestamp(timestamp, "seconds");
|
|
142
|
+
ISO weeks, quarters, holidays, and calendar grids.
|
|
581
143
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
144
|
+
```ts
|
|
145
|
+
import { getWeekNumber, getQuarter, getEaster, getUSHolidays } from 'ts-time-utils/calendar';
|
|
146
|
+
|
|
147
|
+
getWeekNumber(new Date('2025-09-14')); // 37
|
|
148
|
+
getQuarter(new Date('2025-07-15')); // 3
|
|
149
|
+
getEaster(2025); // Easter Sunday 2025
|
|
150
|
+
getUSHolidays(2025); // Array of US federal holidays
|
|
585
151
|
```
|
|
586
152
|
|
|
587
|
-
###
|
|
153
|
+
### Date Range
|
|
588
154
|
|
|
589
|
-
|
|
590
|
-
import { formatDuration, timeAgo, parseDuration } from "ts-time-utils/format";
|
|
155
|
+
Date range operations: overlap, gaps, merge, split.
|
|
591
156
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
formatDuration(65000, { short: true }); // "1m 5s"
|
|
595
|
-
formatDuration(90061000, { maxUnits: 2 }); // "1 day, 1 hour"
|
|
157
|
+
```ts
|
|
158
|
+
import { mergeDateRanges, findGaps, dateRangeOverlap } from 'ts-time-utils/dateRange';
|
|
596
159
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
160
|
+
const ranges = [
|
|
161
|
+
{ start: new Date('2024-01-01'), end: new Date('2024-01-10') },
|
|
162
|
+
{ start: new Date('2024-01-05'), end: new Date('2024-01-15') },
|
|
163
|
+
];
|
|
600
164
|
|
|
601
|
-
//
|
|
602
|
-
|
|
603
|
-
|
|
165
|
+
mergeDateRanges(ranges); // Merged into single range
|
|
166
|
+
findGaps(busyTimes, workday); // Available time slots
|
|
167
|
+
dateRangeOverlap(range1, range2); // true/false
|
|
604
168
|
```
|
|
605
169
|
|
|
606
|
-
###
|
|
170
|
+
### Recurrence
|
|
171
|
+
|
|
172
|
+
RRULE-inspired recurring event patterns.
|
|
607
173
|
|
|
608
174
|
```ts
|
|
609
|
-
import {
|
|
175
|
+
import { createRecurrence, recurrenceToString } from 'ts-time-utils/recurrence';
|
|
610
176
|
|
|
611
|
-
|
|
612
|
-
|
|
177
|
+
const weekly = createRecurrence({
|
|
178
|
+
frequency: 'weekly',
|
|
179
|
+
interval: 1,
|
|
180
|
+
startDate: new Date('2025-01-01'),
|
|
181
|
+
byWeekday: [1, 3, 5], // Mon, Wed, Fri
|
|
182
|
+
});
|
|
613
183
|
|
|
614
|
-
|
|
615
|
-
|
|
184
|
+
weekly.getNextOccurrence(new Date());
|
|
185
|
+
weekly.getAllOccurrences();
|
|
186
|
+
recurrenceToString(weekly.rule); // "Every week on Monday, Wednesday, Friday"
|
|
616
187
|
```
|
|
617
188
|
|
|
618
|
-
###
|
|
189
|
+
### Cron
|
|
190
|
+
|
|
191
|
+
Parse and match cron expressions.
|
|
619
192
|
|
|
620
193
|
```ts
|
|
621
|
-
import {
|
|
194
|
+
import { matchesCron, getNextCronDate, describeCron, CRON_PRESETS } from 'ts-time-utils/cron';
|
|
622
195
|
|
|
623
|
-
//
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
196
|
+
matchesCron('0 9 * * 1-5', date); // true if weekday 9am
|
|
197
|
+
getNextCronDate('0 9 * * *'); // Next 9am
|
|
198
|
+
describeCron('0 9 * * 1-5'); // "At 09:00 on Monday through Friday"
|
|
199
|
+
CRON_PRESETS.DAILY; // "0 0 * * *"
|
|
627
200
|
```
|
|
628
201
|
|
|
629
|
-
###
|
|
202
|
+
### Fiscal Year
|
|
203
|
+
|
|
204
|
+
Fiscal year utilities with configurable start month.
|
|
630
205
|
|
|
631
206
|
```ts
|
|
632
|
-
import {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// Age calculations
|
|
640
|
-
calculateAge(new Date("1990-05-15")); // { years: 34, months: 4, days: 2 }
|
|
641
|
-
getLifeStage(25); // "adult"
|
|
642
|
-
getNextBirthday(new Date("1990-05-15")); // Next May 15th
|
|
643
|
-
isBirthday(new Date("1990-05-15"), new Date("2025-05-15")); // true
|
|
207
|
+
import { getFiscalYear, getFiscalQuarter, FISCAL_PRESETS } from 'ts-time-utils/fiscal';
|
|
208
|
+
|
|
209
|
+
getFiscalYear(date, FISCAL_PRESETS.UK_INDIA); // April start
|
|
210
|
+
getFiscalYear(date, FISCAL_PRESETS.AUSTRALIA); // July start
|
|
211
|
+
getFiscalYear(date, FISCAL_PRESETS.US_FEDERAL); // October start
|
|
212
|
+
getFiscalQuarter(date, { startMonth: 4 }); // Q2 for UK fiscal
|
|
644
213
|
```
|
|
645
214
|
|
|
646
|
-
###
|
|
215
|
+
### Compare & Sort
|
|
216
|
+
|
|
217
|
+
Sort, group, and analyze date arrays.
|
|
647
218
|
|
|
648
219
|
```ts
|
|
649
|
-
import {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
// Calendar operations
|
|
657
|
-
getWeekNumber(new Date("2025-01-15")); // 3
|
|
658
|
-
getQuarter(new Date("2025-07-15")); // 3
|
|
659
|
-
getEaster(2025); // Date object for Easter Sunday 2025
|
|
660
|
-
getDaysInMonth(2, 2024); // 29 (leap year)
|
|
220
|
+
import { sortDates, closestDate, groupDatesByMonth, snapDate } from 'ts-time-utils/compare';
|
|
221
|
+
|
|
222
|
+
sortDates(dates, 'desc');
|
|
223
|
+
closestDate(target, candidates);
|
|
224
|
+
groupDatesByMonth(dates); // Map by YYYY-MM
|
|
225
|
+
snapDate(date, 15, 'minutes'); // Snap to 15-min grid
|
|
661
226
|
```
|
|
662
227
|
|
|
663
|
-
###
|
|
228
|
+
### Iterate
|
|
229
|
+
|
|
230
|
+
Iterate through date sequences and count dates.
|
|
664
231
|
|
|
665
232
|
```ts
|
|
666
|
-
import {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
// Advanced parsing
|
|
673
|
-
parseDate("2025-02-30"); // null (invalid date)
|
|
674
|
-
parseDate("Dec 25, 2025"); // Date object
|
|
675
|
-
parseRelativeDate("tomorrow"); // Date for tomorrow
|
|
676
|
-
parseCustomFormat("25/12/2025", "DD/MM/YYYY"); // Date object
|
|
233
|
+
import { eachDay, eachWeekday, countWeekdays, filterDays } from 'ts-time-utils/iterate';
|
|
234
|
+
|
|
235
|
+
eachDay(start, end); // Array of each day
|
|
236
|
+
eachWeekday(start, end); // Weekdays only (Mon-Fri)
|
|
237
|
+
countWeekdays(start, end); // Number of weekdays
|
|
238
|
+
filterDays(start, end, d => d.getDate() === 15); // 15th of each month
|
|
677
239
|
```
|
|
678
240
|
|
|
679
|
-
###
|
|
241
|
+
### Natural Language
|
|
242
|
+
|
|
243
|
+
Parse human-friendly date strings.
|
|
680
244
|
|
|
681
245
|
```ts
|
|
682
|
-
import {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
} from "ts-time-utils/performance";
|
|
689
|
-
|
|
690
|
-
// Async utilities
|
|
691
|
-
await sleep(1000); // Wait 1 second
|
|
692
|
-
await timeout(promise, 5000); // Timeout after 5 seconds
|
|
693
|
-
|
|
694
|
-
// Performance measurement
|
|
695
|
-
const result = await benchmark(() => heavyOperation(), 10); // Run 10 times
|
|
696
|
-
const stopwatch = new Stopwatch();
|
|
697
|
-
stopwatch.start();
|
|
698
|
-
// ... operations
|
|
699
|
-
console.log(stopwatch.getElapsed()); // Get elapsed time
|
|
246
|
+
import { parseNaturalDate, extractDatesFromText } from 'ts-time-utils/naturalLanguage';
|
|
247
|
+
|
|
248
|
+
parseNaturalDate('tomorrow');
|
|
249
|
+
parseNaturalDate('next Friday');
|
|
250
|
+
parseNaturalDate('in 2 weeks');
|
|
251
|
+
parseNaturalDate('end of month');
|
|
700
252
|
|
|
701
|
-
|
|
702
|
-
|
|
253
|
+
extractDatesFromText('Meeting tomorrow at 3pm');
|
|
254
|
+
// [{ date: Date, text: 'tomorrow at 3pm', confidence: 0.9 }]
|
|
703
255
|
```
|
|
704
256
|
|
|
705
|
-
###
|
|
257
|
+
### International Holidays
|
|
258
|
+
|
|
259
|
+
Public holidays for 10 countries.
|
|
706
260
|
|
|
707
261
|
```ts
|
|
708
|
-
import {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
intervalsOverlap(a!, b!); // true
|
|
717
|
-
const merged = mergeIntervals([a!, b!]);
|
|
262
|
+
import { getHolidays, isHoliday, getNextHoliday } from 'ts-time-utils/holidays';
|
|
263
|
+
|
|
264
|
+
getHolidays(2025, 'UK'); // UK bank holidays
|
|
265
|
+
getHolidays(2025, 'DE'); // German holidays
|
|
266
|
+
isHoliday(date, 'CA'); // Is Canadian holiday?
|
|
267
|
+
getNextHoliday(date, 'AU'); // Next Australian holiday
|
|
268
|
+
|
|
269
|
+
// Supported: UK, NL, DE, CA, AU, IT, ES, CN, IN, US
|
|
718
270
|
```
|
|
719
271
|
|
|
720
|
-
###
|
|
272
|
+
### Locale
|
|
273
|
+
|
|
274
|
+
Multi-language formatting with 40+ locales.
|
|
721
275
|
|
|
722
276
|
```ts
|
|
723
|
-
import {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
277
|
+
import { formatRelativeTime, formatDateLocale, detectLocale } from 'ts-time-utils/locale';
|
|
278
|
+
|
|
279
|
+
formatRelativeTime(pastDate, { locale: 'es' }); // "hace 2 horas"
|
|
280
|
+
formatRelativeTime(pastDate, { locale: 'de' }); // "vor 2 Stunden"
|
|
281
|
+
formatDateLocale(date, 'fr', 'long'); // "15 janvier 2024"
|
|
282
|
+
detectLocale(); // Auto-detect system locale
|
|
729
283
|
```
|
|
730
284
|
|
|
731
|
-
### Working Hours
|
|
285
|
+
### Working Hours
|
|
286
|
+
|
|
287
|
+
Business hours calculations with break support.
|
|
732
288
|
|
|
733
289
|
```ts
|
|
734
|
-
import { isWorkingTime,
|
|
290
|
+
import { isWorkingTime, addWorkingDays, workingDaysBetween } from 'ts-time-utils/workingHours';
|
|
735
291
|
|
|
736
|
-
isWorkingTime(
|
|
737
|
-
|
|
292
|
+
isWorkingTime(date, config);
|
|
293
|
+
addWorkingDays(date, 5, config);
|
|
294
|
+
workingDaysBetween(start, end, config);
|
|
738
295
|
```
|
|
739
296
|
|
|
740
|
-
###
|
|
297
|
+
### Serialization
|
|
298
|
+
|
|
299
|
+
Safe JSON date serialization and deserialization.
|
|
741
300
|
|
|
742
301
|
```ts
|
|
743
|
-
import {
|
|
302
|
+
import { serializeDate, parseJSONWithDates, stringifyWithDates } from 'ts-time-utils/serialize';
|
|
744
303
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
304
|
+
serializeDate(date, { format: 'iso' }); // "2025-09-14T12:30:45.123Z"
|
|
305
|
+
serializeDate(date, { format: 'epoch' }); // 1757853045123
|
|
306
|
+
|
|
307
|
+
const json = stringifyWithDates(data, ['createdAt']);
|
|
308
|
+
const parsed = parseJSONWithDates(json, ['createdAt']);
|
|
748
309
|
```
|
|
749
310
|
|
|
750
|
-
###
|
|
311
|
+
### Performance
|
|
312
|
+
|
|
313
|
+
Async utilities, benchmarking, and timing.
|
|
751
314
|
|
|
752
315
|
```ts
|
|
753
|
-
import {
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
const parsed = parseCronExpression("0 9 * * 1-5"); // 9 AM weekdays
|
|
765
|
-
// { minute: [0], hour: [9], dayOfMonth: [1-31], month: [1-12], dayOfWeek: [1,2,3,4,5] }
|
|
766
|
-
|
|
767
|
-
// Check if a date matches a cron expression
|
|
768
|
-
matchesCron("0 9 * * *", new Date("2024-01-15T09:00:00")); // true (9 AM daily)
|
|
769
|
-
matchesCron("0 9 * * *", new Date("2024-01-15T10:00:00")); // false
|
|
770
|
-
|
|
771
|
-
// Get next scheduled date
|
|
772
|
-
getNextCronDate("0 9 * * *"); // Next 9 AM
|
|
773
|
-
getNextCronDate("0 0 1 * *"); // Next 1st of month at midnight
|
|
774
|
-
|
|
775
|
-
// Get multiple upcoming dates
|
|
776
|
-
getNextCronDates("0 9 * * 1-5", 5); // Next 5 weekday 9 AMs
|
|
777
|
-
|
|
778
|
-
// Human-readable descriptions
|
|
779
|
-
describeCron("0 9 * * *"); // "At 09:00"
|
|
780
|
-
describeCron("0 9 * * 1-5"); // "At 09:00 on Monday through Friday"
|
|
781
|
-
describeCron("0 0 1 * *"); // "At 00:00 on day 1 of every month"
|
|
782
|
-
|
|
783
|
-
// Validate cron expressions
|
|
784
|
-
isValidCron("0 9 * * *"); // true
|
|
785
|
-
isValidCron("invalid"); // false
|
|
786
|
-
|
|
787
|
-
// Common presets
|
|
788
|
-
CRON_PRESETS.EVERY_MINUTE; // "* * * * *"
|
|
789
|
-
CRON_PRESETS.HOURLY; // "0 * * * *"
|
|
790
|
-
CRON_PRESETS.DAILY; // "0 0 * * *"
|
|
791
|
-
CRON_PRESETS.WEEKLY; // "0 0 * * 0"
|
|
792
|
-
CRON_PRESETS.MONTHLY; // "0 0 1 * *"
|
|
793
|
-
CRON_PRESETS.WEEKDAYS; // "0 0 * * 1-5"
|
|
316
|
+
import { sleep, benchmark, Stopwatch, debounce } from 'ts-time-utils/performance';
|
|
317
|
+
|
|
318
|
+
await sleep(1000);
|
|
319
|
+
await benchmark(() => heavyOperation(), 10);
|
|
320
|
+
|
|
321
|
+
const stopwatch = new Stopwatch();
|
|
322
|
+
stopwatch.start();
|
|
323
|
+
// ... operations
|
|
324
|
+
stopwatch.getElapsed();
|
|
325
|
+
|
|
326
|
+
const debouncedFn = debounce(fn, 300);
|
|
794
327
|
```
|
|
795
328
|
|
|
796
|
-
###
|
|
329
|
+
### Age
|
|
330
|
+
|
|
331
|
+
Age calculations and birthday utilities.
|
|
797
332
|
|
|
798
333
|
```ts
|
|
799
|
-
import {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
getFiscalPeriodInfo,
|
|
805
|
-
formatFiscalYear,
|
|
806
|
-
FISCAL_PRESETS,
|
|
807
|
-
} from "ts-time-utils/fiscal";
|
|
808
|
-
|
|
809
|
-
// Default calendar year (January start)
|
|
810
|
-
getFiscalYear(new Date("2024-06-15")); // 2024
|
|
811
|
-
getFiscalQuarter(new Date("2024-06-15")); // 2
|
|
812
|
-
|
|
813
|
-
// UK/India fiscal year (April start)
|
|
814
|
-
getFiscalYear(new Date("2024-03-15"), FISCAL_PRESETS.UK_INDIA); // 2023
|
|
815
|
-
getFiscalYear(new Date("2024-04-15"), FISCAL_PRESETS.UK_INDIA); // 2024
|
|
816
|
-
|
|
817
|
-
// Australian fiscal year (July start)
|
|
818
|
-
getFiscalYear(new Date("2024-06-30"), FISCAL_PRESETS.AUSTRALIA); // 2023
|
|
819
|
-
getFiscalYear(new Date("2024-07-01"), FISCAL_PRESETS.AUSTRALIA); // 2024
|
|
820
|
-
|
|
821
|
-
// US Federal fiscal year (October start)
|
|
822
|
-
getFiscalYear(new Date("2024-09-30"), FISCAL_PRESETS.US_FEDERAL); // 2023
|
|
823
|
-
getFiscalYear(new Date("2024-10-01"), FISCAL_PRESETS.US_FEDERAL); // 2024
|
|
824
|
-
|
|
825
|
-
// Get fiscal year boundaries
|
|
826
|
-
getFiscalYearStart(2024, FISCAL_PRESETS.UK_INDIA); // April 1, 2024
|
|
827
|
-
getFiscalYearEnd(2024, FISCAL_PRESETS.UK_INDIA); // March 31, 2025
|
|
828
|
-
|
|
829
|
-
// Format fiscal years
|
|
830
|
-
formatFiscalYear(2024); // "FY2024"
|
|
831
|
-
formatFiscalYear(2024, FISCAL_PRESETS.UK_INDIA, "long"); // "FY2024/25"
|
|
832
|
-
|
|
833
|
-
// Get comprehensive fiscal info
|
|
834
|
-
const info = getFiscalPeriodInfo(new Date("2024-06-15"));
|
|
835
|
-
// { fiscalYear: 2024, fiscalQuarter: 2, fiscalMonth: 6, progress: 45.2, ... }
|
|
334
|
+
import { calculateAge, getLifeStage, getNextBirthday } from 'ts-time-utils/age';
|
|
335
|
+
|
|
336
|
+
calculateAge(new Date('1990-05-15')); // { years: 34, months: 4, days: 2 }
|
|
337
|
+
getLifeStage(25); // "adult"
|
|
338
|
+
getNextBirthday(birthDate); // Next birthday date
|
|
836
339
|
```
|
|
837
340
|
|
|
838
|
-
###
|
|
341
|
+
### Countdown
|
|
342
|
+
|
|
343
|
+
Timer and countdown utilities.
|
|
839
344
|
|
|
840
345
|
```ts
|
|
841
|
-
import {
|
|
842
|
-
sortDates,
|
|
843
|
-
minDate,
|
|
844
|
-
maxDate,
|
|
845
|
-
closestDate,
|
|
846
|
-
uniqueDates,
|
|
847
|
-
groupDatesByMonth,
|
|
848
|
-
snapDate,
|
|
849
|
-
roundDate,
|
|
850
|
-
medianDate,
|
|
851
|
-
} from "ts-time-utils/compare";
|
|
852
|
-
|
|
853
|
-
const dates = [
|
|
854
|
-
new Date("2024-03-15"),
|
|
855
|
-
new Date("2024-01-10"),
|
|
856
|
-
new Date("2024-06-20"),
|
|
857
|
-
];
|
|
346
|
+
import { createCountdown, getRemainingTime, formatCountdown } from 'ts-time-utils/countdown';
|
|
858
347
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
348
|
+
const countdown = createCountdown(targetDate, {
|
|
349
|
+
onTick: (remaining) => console.log(remaining.days, 'd'),
|
|
350
|
+
onComplete: () => console.log('Done!'),
|
|
351
|
+
});
|
|
352
|
+
countdown.start();
|
|
862
353
|
|
|
863
|
-
//
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
medianDate(dates); // Mar 15, 2024
|
|
354
|
+
getRemainingTime(targetDate); // { days, hours, minutes, seconds }
|
|
355
|
+
formatCountdown(targetDate, { units: ['days', 'hours'] }); // "45d 12h"
|
|
356
|
+
```
|
|
867
357
|
|
|
868
|
-
|
|
869
|
-
const target = new Date("2024-04-01");
|
|
870
|
-
closestDate(target, dates); // Mar 15, 2024
|
|
358
|
+
### Interval
|
|
871
359
|
|
|
872
|
-
|
|
873
|
-
uniqueDates([date1, date1Copy, date2]); // [date1, date2]
|
|
874
|
-
uniqueDates(dates, "day"); // Unique by day precision
|
|
360
|
+
Time interval operations.
|
|
875
361
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
// Map { "2024-01" => [Jan 10], "2024-03" => [Mar 15], "2024-06" => [Jun 20] }
|
|
362
|
+
```ts
|
|
363
|
+
import { createInterval, intervalsOverlap, mergeIntervals } from 'ts-time-utils/interval';
|
|
879
364
|
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
365
|
+
const a = createInterval('2025-01-01', '2025-01-05');
|
|
366
|
+
const b = createInterval('2025-01-04', '2025-01-10');
|
|
367
|
+
intervalsOverlap(a, b); // true
|
|
368
|
+
mergeIntervals([a, b]); // Single merged interval
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Range Presets
|
|
372
|
+
|
|
373
|
+
Common date range presets.
|
|
883
374
|
|
|
884
|
-
|
|
885
|
-
|
|
375
|
+
```ts
|
|
376
|
+
import { today, lastNDays, thisWeek, thisMonth } from 'ts-time-utils/rangePresets';
|
|
377
|
+
|
|
378
|
+
today(); // { start, end } for today
|
|
379
|
+
lastNDays(7); // Last 7 days
|
|
380
|
+
thisWeek(); // Current week
|
|
381
|
+
thisMonth(); // Current month
|
|
886
382
|
```
|
|
887
383
|
|
|
888
|
-
###
|
|
384
|
+
### Parse
|
|
385
|
+
|
|
386
|
+
Date parsing from various formats.
|
|
889
387
|
|
|
890
388
|
```ts
|
|
891
|
-
import {
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
eachDayOfWeek,
|
|
898
|
-
iterateDays,
|
|
899
|
-
filterDays,
|
|
900
|
-
} from "ts-time-utils/iterate";
|
|
901
|
-
|
|
902
|
-
const start = new Date("2024-01-01");
|
|
903
|
-
const end = new Date("2024-01-31");
|
|
904
|
-
|
|
905
|
-
// Generate arrays of dates
|
|
906
|
-
eachDay(start, end); // [Jan 1, Jan 2, ..., Jan 31] (31 dates)
|
|
907
|
-
eachWeekday(start, end); // All Mon-Fri dates (23 dates)
|
|
908
|
-
eachWeek(start, end); // [Jan 7, Jan 14, Jan 21, Jan 28] (Sundays)
|
|
909
|
-
eachMonth(start, new Date("2024-06-30")); // [Feb 1, Mar 1, Apr 1, May 1, Jun 1]
|
|
910
|
-
|
|
911
|
-
// Count dates
|
|
912
|
-
countWeekdays(start, end); // 23
|
|
913
|
-
|
|
914
|
-
// Get specific weekdays
|
|
915
|
-
eachDayOfWeek(start, end, 1); // All Mondays in January
|
|
916
|
-
|
|
917
|
-
// Lazy iteration (memory efficient for large ranges)
|
|
918
|
-
for (const date of iterateDays(start, end)) {
|
|
919
|
-
console.log(date);
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
// Filter days by custom predicate
|
|
923
|
-
filterDays(start, end, (d) => d.getDate() === 15); // [Jan 15]
|
|
924
|
-
|
|
925
|
-
// Custom intervals
|
|
926
|
-
eachInterval(start, end, { days: 7 }); // Every 7 days
|
|
927
|
-
eachInterval(start, end, { hours: 6 }); // Every 6 hours
|
|
389
|
+
import { parseDate, parseTime, autoDetectFormat } from 'ts-time-utils/parse';
|
|
390
|
+
|
|
391
|
+
parseDate('Dec 25, 2025');
|
|
392
|
+
parseDate('25/12/2025', 'DD/MM/YYYY');
|
|
393
|
+
parseTime('2:30 PM'); // { hour: 14, minute: 30 }
|
|
394
|
+
autoDetectFormat('2025-09-14'); // 'YYYY-MM-DD'
|
|
928
395
|
```
|
|
929
396
|
|
|
930
|
-
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Plugin System
|
|
400
|
+
|
|
401
|
+
Extend ChainedDate with custom functionality.
|
|
931
402
|
|
|
932
403
|
```ts
|
|
933
|
-
import {
|
|
934
|
-
formatRelativeTime,
|
|
935
|
-
formatDateLocale,
|
|
936
|
-
formatTimeLocale,
|
|
937
|
-
formatDateTimeLocale,
|
|
938
|
-
registerLocale,
|
|
939
|
-
getLocaleConfig,
|
|
940
|
-
detectLocale,
|
|
941
|
-
getSupportedLocales,
|
|
942
|
-
} from "ts-time-utils/locale";
|
|
943
|
-
|
|
944
|
-
// Relative time formatting in multiple languages
|
|
945
|
-
const pastDate = new Date(Date.now() - 2 * 60 * 60 * 1000); // 2 hours ago
|
|
946
|
-
formatRelativeTime(pastDate, { locale: "en" }); // "2 hours ago"
|
|
947
|
-
formatRelativeTime(pastDate, { locale: "es" }); // "hace 2 horas"
|
|
948
|
-
formatRelativeTime(pastDate, { locale: "fr" }); // "il y a 2 heures"
|
|
949
|
-
formatRelativeTime(pastDate, { locale: "de" }); // "vor 2 Stunden"
|
|
950
|
-
formatRelativeTime(pastDate, { locale: "nl" }); // "2 uur geleden"
|
|
951
|
-
formatRelativeTime(pastDate, { locale: "it" }); // "2 ore fa"
|
|
952
|
-
formatRelativeTime(pastDate, { locale: "zh" }); // "2ĺ°ćśĺ"
|
|
953
|
-
formatRelativeTime(pastDate, { locale: "ja" }); // "2ćéĺ"
|
|
954
|
-
formatRelativeTime(pastDate, { locale: "fa" }); // "2 ساؚت ŮžŰŘ´"
|
|
955
|
-
|
|
956
|
-
// Future dates
|
|
957
|
-
const futureDate = new Date(Date.now() + 3 * 24 * 60 * 60 * 1000);
|
|
958
|
-
formatRelativeTime(futureDate, { locale: "en" }); // "in 3 days"
|
|
959
|
-
formatRelativeTime(futureDate, { locale: "es" }); // "en 3 dĂas"
|
|
960
|
-
formatRelativeTime(futureDate, { locale: "nl" }); // "over 3 dagen"
|
|
961
|
-
formatRelativeTime(futureDate, { locale: "it" }); // "tra 3 giorni"
|
|
962
|
-
formatRelativeTime(futureDate, { locale: "fa" }); // "3 ŘąŮز ŘŻŰÚŻŘą"
|
|
963
|
-
|
|
964
|
-
// Relative time options
|
|
965
|
-
formatRelativeTime(pastDate, {
|
|
966
|
-
locale: "en",
|
|
967
|
-
maxUnit: "days", // Don't use units larger than days
|
|
968
|
-
minUnit: "minutes", // Don't use units smaller than minutes
|
|
969
|
-
precision: 1, // Show 1 decimal place: "2.0 hours ago"
|
|
970
|
-
short: true, // Use abbreviated format: "2h ago"
|
|
971
|
-
numeric: "auto", // Use words when appropriate: "yesterday"
|
|
972
|
-
});
|
|
404
|
+
import { chain, registerPlugin, createPlugin } from 'ts-time-utils/chain';
|
|
973
405
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
formatDateLocale(date, "fr", "long"); // "15 janvier 2024"
|
|
979
|
-
formatDateLocale(date, "de", "short"); // "15.1.2024"
|
|
980
|
-
|
|
981
|
-
// Time formatting
|
|
982
|
-
formatTimeLocale(date, "en", "short"); // "2:30 PM"
|
|
983
|
-
formatTimeLocale(date, "de", "medium"); // "14:30:45"
|
|
984
|
-
formatTimeLocale(date, "fr", "long"); // "14:30:45 UTC"
|
|
985
|
-
|
|
986
|
-
// Combined date and time
|
|
987
|
-
formatDateTimeLocale(date, "en"); // "Jan 15, 2024 2:30:45 PM"
|
|
988
|
-
|
|
989
|
-
// Auto-detect locale from browser/system
|
|
990
|
-
const userLocale = detectLocale(); // e.g., 'en-US' or 'fr-FR'
|
|
991
|
-
formatRelativeTime(pastDate, { locale: userLocale });
|
|
992
|
-
|
|
993
|
-
// Get supported locales
|
|
994
|
-
const locales = getSupportedLocales();
|
|
995
|
-
// ['en', 'es', 'fr', 'de', 'zh', 'ja', ...]
|
|
996
|
-
|
|
997
|
-
// Register custom locale
|
|
998
|
-
registerLocale("custom", {
|
|
999
|
-
locale: "custom",
|
|
1000
|
-
dateFormats: {
|
|
1001
|
-
short: "M/d/yyyy",
|
|
1002
|
-
medium: "MMM d, yyyy",
|
|
1003
|
-
long: "MMMM d, yyyy",
|
|
1004
|
-
full: "EEEE, MMMM d, yyyy",
|
|
1005
|
-
},
|
|
1006
|
-
timeFormats: {
|
|
1007
|
-
short: "h:mm a",
|
|
1008
|
-
medium: "h:mm:ss a",
|
|
1009
|
-
long: "h:mm:ss a z",
|
|
1010
|
-
full: "h:mm:ss a zzzz",
|
|
1011
|
-
},
|
|
1012
|
-
relativeTime: {
|
|
1013
|
-
future: "in {0}",
|
|
1014
|
-
past: "{0} ago",
|
|
1015
|
-
units: {
|
|
1016
|
-
second: "sec",
|
|
1017
|
-
seconds: "secs",
|
|
1018
|
-
minute: "min",
|
|
1019
|
-
minutes: "mins",
|
|
1020
|
-
hour: "hr",
|
|
1021
|
-
hours: "hrs",
|
|
1022
|
-
day: "day",
|
|
1023
|
-
days: "days",
|
|
1024
|
-
week: "wk",
|
|
1025
|
-
weeks: "wks",
|
|
1026
|
-
month: "mo",
|
|
1027
|
-
months: "mos",
|
|
1028
|
-
year: "yr",
|
|
1029
|
-
years: "yrs",
|
|
1030
|
-
},
|
|
1031
|
-
},
|
|
1032
|
-
calendar: {
|
|
1033
|
-
weekStartsOn: 0, // Sunday
|
|
1034
|
-
monthNames: ["Jan", "Feb", "Mar" /* ... */],
|
|
1035
|
-
monthNamesShort: ["J", "F", "M" /* ... */],
|
|
1036
|
-
dayNames: ["Sun", "Mon", "Tue" /* ... */],
|
|
1037
|
-
dayNamesShort: ["S", "M", "T" /* ... */],
|
|
1038
|
-
},
|
|
1039
|
-
numbers: {
|
|
1040
|
-
decimal: ".",
|
|
1041
|
-
thousands: ",",
|
|
406
|
+
const businessPlugin = createPlugin('business', {
|
|
407
|
+
addBusinessDays(days: number) {
|
|
408
|
+
// Implementation
|
|
409
|
+
return this;
|
|
1042
410
|
},
|
|
411
|
+
isBusinessDay() {
|
|
412
|
+
const day = this.toDate().getDay();
|
|
413
|
+
return day !== 0 && day !== 6;
|
|
414
|
+
}
|
|
1043
415
|
});
|
|
1044
416
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
convertFormattedDate,
|
|
1051
|
-
convertRelativeTimeArray,
|
|
1052
|
-
compareLocaleFormats,
|
|
1053
|
-
} from "ts-time-utils/locale";
|
|
1054
|
-
|
|
1055
|
-
// Convert relative time between locales
|
|
1056
|
-
convertRelativeTime("2 hours ago", "en", "es"); // "hace 2 horas"
|
|
1057
|
-
convertRelativeTime("hace 3 dĂas", "es", "fr"); // "il y a 3 jours"
|
|
1058
|
-
convertRelativeTime("2h ago", "en", "de"); // "vor 2h"
|
|
1059
|
-
convertRelativeTime("2 hours ago", "en", "nl"); // "2 uur geleden"
|
|
1060
|
-
convertRelativeTime("2 hours ago", "en", "it"); // "2 ore fa"
|
|
1061
|
-
convertRelativeTime("2 hours ago", "en", "fa"); // "2 ساؚت ŮžŰŘ´"
|
|
1062
|
-
convertRelativeTime("2 ساؚت ŮžŰŘ´", "fa", "en"); // "2 hours ago"
|
|
1063
|
-
|
|
1064
|
-
// Detect locale from formatted text
|
|
1065
|
-
detectLocaleFromRelativeTime("2 hours ago"); // "en"
|
|
1066
|
-
detectLocaleFromRelativeTime("hace 2 horas"); // "es"
|
|
1067
|
-
detectLocaleFromRelativeTime("il y a 2 heures"); // "fr"
|
|
1068
|
-
detectLocaleFromRelativeTime("2 uur geleden"); // "nl"
|
|
1069
|
-
detectLocaleFromRelativeTime("2 ore fa"); // "it"
|
|
1070
|
-
detectLocaleFromRelativeTime("2 ساؚت ŮžŰŘ´"); // "fa"
|
|
1071
|
-
detectLocaleFromRelativeTime("vor 2 Stunden"); // "de"
|
|
1072
|
-
|
|
1073
|
-
// Convert date format patterns between locales
|
|
1074
|
-
convertFormatPattern("M/d/yyyy", "en", "de"); // "dd.MM.yyyy"
|
|
1075
|
-
convertFormatPattern("MMM d, yyyy", "en", "fr", "long"); // "d MMMM yyyy"
|
|
1076
|
-
|
|
1077
|
-
// Convert formatted dates between locales
|
|
1078
|
-
convertFormattedDate("Jan 15, 2024", "en", "es"); // "15 ene 2024"
|
|
1079
|
-
convertFormattedDate("15. Januar 2024", "de", "en"); // "Jan 15, 2024"
|
|
1080
|
-
|
|
1081
|
-
// Bulk conversion of relative time arrays
|
|
1082
|
-
const englishTimes = ["2 hours ago", "in 3 days", "1 week ago"];
|
|
1083
|
-
convertRelativeTimeArray(englishTimes, "en", "es");
|
|
1084
|
-
// ["hace 2 horas", "en 3 dĂas", "hace 1 semana"]
|
|
1085
|
-
|
|
1086
|
-
// Compare format differences between locales
|
|
1087
|
-
const comparison = compareLocaleFormats("en", "de");
|
|
1088
|
-
console.log(comparison.dateFormats.short);
|
|
1089
|
-
// { locale1: "M/d/yyyy", locale2: "dd.MM.yyyy" }
|
|
1090
|
-
console.log(comparison.weekStartsOn);
|
|
1091
|
-
// { locale1: 0, locale2: 1 } // Sunday vs Monday
|
|
417
|
+
registerPlugin(businessPlugin);
|
|
418
|
+
|
|
419
|
+
chain(new Date())
|
|
420
|
+
.addBusinessDays(5)
|
|
421
|
+
.isBusinessDay(); // true/false
|
|
1092
422
|
```
|
|
1093
423
|
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
- `parseDuration(duration)` - Parse duration string to milliseconds
|
|
1135
|
-
|
|
1136
|
-
### Parse Functions
|
|
1137
|
-
|
|
1138
|
-
- `parseISO8601Duration(duration)` - Parse ISO 8601 duration to object (P1Y2M3DT4H5M6S)
|
|
1139
|
-
- `parseISO8601DurationToMs(duration)` - Parse ISO 8601 duration to milliseconds
|
|
1140
|
-
- `parseTime(timeString)` - Parse time string ("14:30", "2:30 PM") to Date
|
|
1141
|
-
- `guessDateFormat(dateString)` - Guess the format of a date string
|
|
1142
|
-
- `parseAutoFormat(dateString)` - Auto-detect and parse date string
|
|
1143
|
-
- `parseRangeEndpoint(endpoint)` - Parse range endpoint (date string, Date, or number)
|
|
1144
|
-
|
|
1145
|
-
### Calendar Functions
|
|
1146
|
-
|
|
1147
|
-
- `getCalendarDays(year, month)` - Get array of days for a calendar month
|
|
1148
|
-
- `getWeekNumber(date)` - Get ISO week number (1-53)
|
|
1149
|
-
- `getQuarter(date)` - Get quarter (1-4)
|
|
1150
|
-
- `getFirstDayOfMonth(date)` / `getLastDayOfMonth(date)` - Month boundaries
|
|
1151
|
-
- `getFirstDayOfWeek(date)` / `getLastDayOfWeek(date)` - Week boundaries
|
|
1152
|
-
- `getNthDayOfMonth(year, month, dayOfWeek, n)` - Get nth occurrence of weekday in month
|
|
1153
|
-
- `getStartOfWeek(date, startDay?)` - Get start of week (configurable start day)
|
|
1154
|
-
- `getEndOfWeek(date, startDay?)` - Get end of week (configurable start day)
|
|
1155
|
-
- `getWeeksInMonth(year, month)` - Count weeks in a month
|
|
1156
|
-
|
|
1157
|
-
#### US Federal Holidays
|
|
1158
|
-
|
|
1159
|
-
- `getNewYearsDay(year)` - Get New Year's Day
|
|
1160
|
-
- `getMLKDay(year)` - Get Martin Luther King Jr. Day (3rd Monday of January)
|
|
1161
|
-
- `getPresidentsDay(year)` - Get Presidents Day (3rd Monday of February)
|
|
1162
|
-
- `getMemorialDay(year)` - Get Memorial Day (last Monday of May)
|
|
1163
|
-
- `getIndependenceDay(year)` - Get Independence Day (July 4th)
|
|
1164
|
-
- `getLaborDay(year)` - Get Labor Day (1st Monday of September)
|
|
1165
|
-
- `getColumbusDay(year)` - Get Columbus Day (2nd Monday of October)
|
|
1166
|
-
- `getVeteransDay(year)` - Get Veterans Day (November 11th)
|
|
1167
|
-
- `getThanksgivingDay(year)` - Get Thanksgiving Day (4th Thursday of November)
|
|
1168
|
-
- `getChristmasDay(year)` - Get Christmas Day
|
|
1169
|
-
- `getGoodFriday(year)` - Get Good Friday
|
|
1170
|
-
- `getUSHolidays(year)` - Get all US federal holidays for a year
|
|
1171
|
-
- `isUSHoliday(date)` - Check if date is a US federal holiday
|
|
1172
|
-
- `getUSHolidayName(date)` - Get name of US holiday (or null)
|
|
1173
|
-
|
|
1174
|
-
### Timezone Functions
|
|
1175
|
-
|
|
1176
|
-
- `getTimezoneOffset(timezone, date?)` - Get timezone offset in minutes
|
|
1177
|
-
- `convertTimezone(date, fromTz, toTz)` - Convert date between timezones
|
|
1178
|
-
- `getTimezoneNames()` - Get array of valid timezone names
|
|
1179
|
-
- `formatWithTimezone(date, timezone, format?)` - Format date in specific timezone
|
|
1180
|
-
- `isDST(date, timezone?)` - Check if DST is in effect
|
|
1181
|
-
- `getNextDSTTransition(date?, timezone?)` - Get next DST transition date
|
|
1182
|
-
- `findCommonWorkingHours(tz1, tz2, workStart?, workEnd?)` - Find overlapping work hours
|
|
1183
|
-
- `getTimezoneAbbreviation(date, timezone?)` - Get timezone abbreviation (EST, PST, etc.)
|
|
1184
|
-
- `convertBetweenZones(date, fromTz, toTz)` - Convert date between zones (returns new Date)
|
|
1185
|
-
- `getTimezoneDifferenceHours(tz1, tz2, date?)` - Get hour difference between timezones
|
|
1186
|
-
- `isSameTimezone(tz1, tz2, date?)` - Check if two timezones have same offset
|
|
1187
|
-
|
|
1188
|
-
### Working Hours Functions
|
|
1189
|
-
|
|
1190
|
-
- `isWithinWorkingHours(date, config?)` - Check if time is within working hours
|
|
1191
|
-
- `getNextWorkingHour(date, config?)` - Get next available working hour
|
|
1192
|
-
- `addWorkingMinutes(date, minutes, config?)` - Add minutes within working hours
|
|
1193
|
-
- `workingMinutesBetween(start, end, config?)` - Count working minutes between dates
|
|
1194
|
-
- `addWorkingDays(date, days, config?)` - Add working days to date
|
|
1195
|
-
- `subtractWorkingDays(date, days, config?)` - Subtract working days from date
|
|
1196
|
-
- `getNextWorkingDay(date, config?)` - Get next working day
|
|
1197
|
-
- `getPreviousWorkingDay(date, config?)` - Get previous working day
|
|
1198
|
-
- `getWorkingDaysInMonth(year, month, config?)` - Count working days in month
|
|
1199
|
-
- `getWorkingDaysInMonthArray(year, month, config?)` - Get array of working days
|
|
1200
|
-
- `workingDaysBetween(start, end, config?)` - Count working days between dates
|
|
1201
|
-
- `isBreakTime(date, breakStart?, breakEnd?)` - Check if time is during break
|
|
1202
|
-
- `getWorkDayStart(date, config?)` - Get start time of work day
|
|
1203
|
-
- `getWorkDayEnd(date, config?)` - Get end time of work day
|
|
1204
|
-
- `getWorkingHoursPerDay(config?)` - Get working hours per day
|
|
1205
|
-
|
|
1206
|
-
### Cron Functions
|
|
1207
|
-
|
|
1208
|
-
- `parseCronExpression(expression)` - Parse cron expression to object
|
|
1209
|
-
- `matchesCron(expression, date?)` - Check if date matches cron expression
|
|
1210
|
-
- `getNextCronDate(expression, after?)` - Get next date matching cron
|
|
1211
|
-
- `getNextCronDates(expression, count, after?)` - Get multiple future cron dates
|
|
1212
|
-
- `getPreviousCronDate(expression, before?)` - Get previous date matching cron
|
|
1213
|
-
- `isValidCron(expression)` - Validate cron expression syntax
|
|
1214
|
-
- `describeCron(expression)` - Get human-readable cron description
|
|
1215
|
-
- `CRON_PRESETS` - Common cron expressions (EVERY_MINUTE, HOURLY, DAILY, etc.)
|
|
1216
|
-
|
|
1217
|
-
### Fiscal Year Functions
|
|
1218
|
-
|
|
1219
|
-
- `getFiscalYear(date, config?)` - Get fiscal year for a date
|
|
1220
|
-
- `getFiscalQuarter(date, config?)` - Get fiscal quarter (1-4)
|
|
1221
|
-
- `getFiscalMonth(date, config?)` - Get fiscal month (1-12 within fiscal year)
|
|
1222
|
-
- `getFiscalWeek(date, config?)` - Get fiscal week number
|
|
1223
|
-
- `getFiscalYearStart(year, config?)` - Get start date of fiscal year
|
|
1224
|
-
- `getFiscalYearEnd(year, config?)` - Get end date of fiscal year
|
|
1225
|
-
- `getFiscalQuarterStart(year, quarter, config?)` - Get start of fiscal quarter
|
|
1226
|
-
- `getFiscalQuarterEnd(year, quarter, config?)` - Get end of fiscal quarter
|
|
1227
|
-
- `isSameFiscalYear(date1, date2, config?)` - Check if dates are in same fiscal year
|
|
1228
|
-
- `isSameFiscalQuarter(date1, date2, config?)` - Check if dates are in same fiscal quarter
|
|
1229
|
-
- `getDaysElapsedInFiscalYear(date, config?)` - Days elapsed in fiscal year
|
|
1230
|
-
- `getDaysRemainingInFiscalYear(date, config?)` - Days remaining in fiscal year
|
|
1231
|
-
- `getFiscalYearProgress(date, config?)` - Percentage of fiscal year completed
|
|
1232
|
-
- `formatFiscalYear(year, config?, format?)` - Format as "FY2024" or "FY2023/24"
|
|
1233
|
-
- `formatFiscalQuarter(year, quarter, config?)` - Format as "Q1 FY2024"
|
|
1234
|
-
- `getFiscalPeriodInfo(date, config?)` - Get comprehensive fiscal period info
|
|
1235
|
-
- `FISCAL_PRESETS` - CALENDAR, UK_INDIA, AUSTRALIA, US_FEDERAL
|
|
1236
|
-
|
|
1237
|
-
### Compare Functions
|
|
1238
|
-
|
|
1239
|
-
- `compareDates(a, b)` - Compare function for sorting dates
|
|
1240
|
-
- `compareDatesDesc(a, b)` - Compare function for reverse sorting
|
|
1241
|
-
- `sortDates(dates, direction?)` - Sort date array (asc/desc)
|
|
1242
|
-
- `minDate(dates)` - Find earliest date
|
|
1243
|
-
- `maxDate(dates)` - Find latest date
|
|
1244
|
-
- `dateExtent(dates)` - Get { min, max } from date array
|
|
1245
|
-
- `uniqueDates(dates, precision?)` - Remove duplicate dates
|
|
1246
|
-
- `closestDate(target, candidates)` - Find closest date to target
|
|
1247
|
-
- `closestFutureDate(target, candidates)` - Find closest future date
|
|
1248
|
-
- `closestPastDate(target, candidates)` - Find closest past date
|
|
1249
|
-
- `clampDate(date, min, max)` - Constrain date to range
|
|
1250
|
-
- `isDateInRange(date, min, max)` - Check if date is in range
|
|
1251
|
-
- `filterDatesInRange(dates, min, max)` - Filter dates in range
|
|
1252
|
-
- `groupDates(dates, keyFn)` - Group dates by custom key
|
|
1253
|
-
- `groupDatesByYear(dates)` - Group by year
|
|
1254
|
-
- `groupDatesByMonth(dates)` - Group by month (YYYY-MM)
|
|
1255
|
-
- `groupDatesByDay(dates)` - Group by day (YYYY-MM-DD)
|
|
1256
|
-
- `groupDatesByDayOfWeek(dates)` - Group by day of week (0-6)
|
|
1257
|
-
- `medianDate(dates)` - Calculate median date
|
|
1258
|
-
- `averageDate(dates)` - Calculate average/mean date
|
|
1259
|
-
- `roundDate(date, unit)` - Round to nearest minute/hour/day
|
|
1260
|
-
- `snapDate(date, intervalMinutes, mode?)` - Snap to interval grid
|
|
1261
|
-
- `isChronological(dates, strict?)` - Check if dates are in order
|
|
1262
|
-
- `dateSpan(dates)` - Get duration between min and max
|
|
1263
|
-
- `partitionDates(dates, predicate)` - Split into [matching, non-matching]
|
|
1264
|
-
- `nthDate(dates, n)` - Get nth date (supports negative indices)
|
|
1265
|
-
|
|
1266
|
-
### Iterate Functions
|
|
1267
|
-
|
|
1268
|
-
- `eachDay(start, end)` - Array of each day in range
|
|
1269
|
-
- `eachWeekday(start, end)` - Array of weekdays (Mon-Fri)
|
|
1270
|
-
- `eachWeekend(start, end)` - Array of weekend days (Sat-Sun)
|
|
1271
|
-
- `eachWeek(start, end, weekStartsOn?)` - Array of week starts
|
|
1272
|
-
- `eachMonth(start, end)` - Array of month starts
|
|
1273
|
-
- `eachMonthEnd(start, end)` - Array of month ends
|
|
1274
|
-
- `eachQuarter(start, end)` - Array of quarter starts
|
|
1275
|
-
- `eachYear(start, end)` - Array of year starts
|
|
1276
|
-
- `eachHour(start, end, step?)` - Array of hourly intervals
|
|
1277
|
-
- `eachMinute(start, end, step?)` - Array of minute intervals
|
|
1278
|
-
- `eachDayOfWeek(start, end, dayOfWeek)` - Array of specific weekday
|
|
1279
|
-
- `eachNthDayOfMonth(start, end, day)` - Array of nth day of each month
|
|
1280
|
-
- `eachInterval(start, end, interval)` - Array at custom intervals
|
|
1281
|
-
- `countDays(start, end)` - Count days in range
|
|
1282
|
-
- `countWeekdays(start, end)` - Count weekdays in range
|
|
1283
|
-
- `countWeekendDays(start, end)` - Count weekend days
|
|
1284
|
-
- `countWeeks(start, end)` - Count weeks in range
|
|
1285
|
-
- `countMonths(start, end)` - Count months in range
|
|
1286
|
-
- `iterateDates(start, end, step?)` - Lazy date generator
|
|
1287
|
-
- `iterateDays(start, end)` - Lazy day iterator
|
|
1288
|
-
- `iterateWeekdays(start, end)` - Lazy weekday iterator
|
|
1289
|
-
- `iterateMonths(start, end)` - Lazy month iterator
|
|
1290
|
-
- `filterDays(start, end, filter)` - Filter days by predicate
|
|
1291
|
-
|
|
1292
|
-
### Calculate Functions
|
|
1293
|
-
|
|
1294
|
-
- `differenceInUnits(date1, date2, unit?, precise?)` - Calculate difference between dates
|
|
1295
|
-
- `addTime(date, amount, unit)` - Add time to a date
|
|
1296
|
-
- `subtractTime(date, amount, unit)` - Subtract time from a date
|
|
1297
|
-
- `startOf(date, unit)` - Get start of time period
|
|
1298
|
-
- `endOf(date, unit)` - Get end of time period
|
|
1299
|
-
- `isBetween(date, start, end)` - Check if date is between two dates
|
|
1300
|
-
- `businessDaysBetween(start, end)` - Count business days between dates
|
|
1301
|
-
|
|
1302
|
-
### Validation Functions
|
|
1303
|
-
|
|
1304
|
-
- `isValidDate(date)` - Check if date is valid
|
|
1305
|
-
- `isLeapYear(year)` - Check if year is leap year
|
|
1306
|
-
- `isPast(date)` / `isFuture(date)` - Check if date is past/future
|
|
1307
|
-
- `isToday(date)` / `isYesterday(date)` / `isTomorrow(date)` - Date comparisons
|
|
1308
|
-
- `isSameDay(date1, date2)` - Check if dates are same day
|
|
1309
|
-
- `isSameWeek(date1, date2)` - Check if dates are in same week
|
|
1310
|
-
- `isSameMonth(date1, date2)` - Check if dates are in same month
|
|
1311
|
-
- `isSameYear(date1, date2)` - Check if dates are in same year
|
|
1312
|
-
- `isThisWeek(date)` - Check if date is in current week
|
|
1313
|
-
- `isThisMonth(date)` - Check if date is in current month
|
|
1314
|
-
- `isThisYear(date)` - Check if date is in current year
|
|
1315
|
-
- `isWeekend(date)` / `isWeekday(date)` - Check day type
|
|
1316
|
-
- `isBusinessDay(date)` - Check if date is a business day (weekday, not a US holiday)
|
|
1317
|
-
- `isInLastNDays(date, n)` - Check if date is within last N days
|
|
1318
|
-
- `isInNextNDays(date, n)` - Check if date is within next N days
|
|
1319
|
-
- `isValidTimeString(time)` - Validate HH:MM time format
|
|
1320
|
-
- `isValidISOString(dateString)` - Validate ISO 8601 date string
|
|
1321
|
-
|
|
1322
|
-
### Locale Functions
|
|
1323
|
-
|
|
1324
|
-
- `formatRelativeTime(date, options?)` - Format relative time with locale support
|
|
1325
|
-
- Options: `locale`, `maxUnit`, `minUnit`, `precision`, `short`, `numeric`, `style`
|
|
1326
|
-
- Supports 30+ locales: en, es, fr, de, it, pt, nl, sv, da, no, fi, pl, cs, sk, hu, ro, bg, hr, sl, et, lv, lt, ru, uk, tr, ar, he, hi, th, ko, zh, ja
|
|
1327
|
-
- `formatDateLocale(date, locale?, style?)` - Format date in locale-specific format
|
|
1328
|
-
- Styles: 'short', 'medium', 'long', 'full'
|
|
1329
|
-
- `formatTimeLocale(date, locale?, style?)` - Format time in locale-specific format
|
|
1330
|
-
- `formatDateTimeLocale(date, locale?, dateStyle?, timeStyle?)` - Format both date and time
|
|
1331
|
-
- `registerLocale(locale, config)` - Register a custom locale configuration
|
|
1332
|
-
- `getLocaleConfig(locale)` - Get configuration for a specific locale
|
|
1333
|
-
- `detectLocale(fallback?)` - Auto-detect system/browser locale
|
|
1334
|
-
- `getSupportedLocales()` - Get array of all supported locale codes
|
|
1335
|
-
- `getMonthNames(locale?, short?)` - Get localized month names
|
|
1336
|
-
- `getDayNames(locale?, short?)` - Get localized day names
|
|
1337
|
-
- `getBestMatchingLocale(preferences, fallback?)` - Find best matching locale from preferences
|
|
1338
|
-
|
|
1339
|
-
#### Locale Conversion Functions
|
|
1340
|
-
|
|
1341
|
-
- `convertRelativeTime(text, fromLocale, toLocale)` - Convert relative time between locales
|
|
1342
|
-
- Example: `convertRelativeTime("2 hours ago", "en", "es")` â `"hace 2 horas"`
|
|
1343
|
-
- Example: `convertRelativeTime("2 hours ago", "en", "nl")` â `"2 uur geleden"`
|
|
1344
|
-
- Example: `convertRelativeTime("2 hours ago", "en", "it")` â `"2 ore fa"`
|
|
1345
|
-
- Example: `convertRelativeTime("2 hours ago", "en", "fa")` â `"2 ساؚت ŮžŰŘ´"`
|
|
1346
|
-
- `detectLocaleFromRelativeTime(text)` - Detect locale from relative time string
|
|
1347
|
-
- Returns most likely locale or null if detection fails
|
|
1348
|
-
- `convertFormatPattern(pattern, fromLocale, toLocale, style?)` - Convert date format patterns
|
|
1349
|
-
- Maps common patterns between locales or uses target locale's style
|
|
1350
|
-
- `convertFormattedDate(formattedDate, fromLocale, toLocale, targetStyle?)` - Convert formatted dates
|
|
1351
|
-
- Parses date in source locale and reformats in target locale
|
|
1352
|
-
- `convertRelativeTimeArray(array, fromLocale, toLocale)` - Bulk convert relative time arrays
|
|
1353
|
-
- Returns array with same length, null for unparseable strings
|
|
1354
|
-
- `compareLocaleFormats(locale1, locale2)` - Compare format differences between locales
|
|
1355
|
-
- Returns object with dateFormats, timeFormats, and weekStartsOn comparisons
|
|
1356
|
-
|
|
1357
|
-
## đ ď¸ Development
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## API Reference
|
|
427
|
+
|
|
428
|
+
For complete API documentation, see the [Playground & Docs](https://ts-time-utils.h8frad.work).
|
|
429
|
+
|
|
430
|
+
### All Modules
|
|
431
|
+
|
|
432
|
+
| Module | Description |
|
|
433
|
+
|--------|-------------|
|
|
434
|
+
| `format` | Duration formatting, time ago, date patterns |
|
|
435
|
+
| `calculate` | Date arithmetic, differences, period boundaries |
|
|
436
|
+
| `validate` | Date validation, comparisons, type checks |
|
|
437
|
+
| `duration` | Immutable Duration class with arithmetic |
|
|
438
|
+
| `chain` | Fluent chainable API |
|
|
439
|
+
| `timezone` | Timezone conversions, DST handling |
|
|
440
|
+
| `calendar` | ISO weeks, quarters, holidays, grids |
|
|
441
|
+
| `dateRange` | Range operations: overlap, gaps, merge |
|
|
442
|
+
| `recurrence` | RRULE-inspired recurring patterns |
|
|
443
|
+
| `cron` | Cron expression parsing and matching |
|
|
444
|
+
| `fiscal` | Fiscal year utilities |
|
|
445
|
+
| `compare` | Date sorting, grouping, statistics |
|
|
446
|
+
| `iterate` | Date iteration and counting |
|
|
447
|
+
| `naturalLanguage` | Natural language date parsing |
|
|
448
|
+
| `holidays` | International holiday calculations |
|
|
449
|
+
| `locale` | Multi-language formatting (40+ locales) |
|
|
450
|
+
| `workingHours` | Business hours calculations |
|
|
451
|
+
| `serialize` | JSON date serialization |
|
|
452
|
+
| `performance` | Async utilities, benchmarking |
|
|
453
|
+
| `age` | Age calculations, birthdays |
|
|
454
|
+
| `countdown` | Timer and countdown utilities |
|
|
455
|
+
| `interval` | Time interval operations |
|
|
456
|
+
| `rangePresets` | Common date range presets |
|
|
457
|
+
| `parse` | Date parsing from various formats |
|
|
458
|
+
| `plugins` | Plugin system for extensions |
|
|
459
|
+
| `constants` | Time constants and types |
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
## Development
|
|
1358
464
|
|
|
1359
465
|
```bash
|
|
1360
|
-
# Install dependencies
|
|
1361
|
-
npm
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
npm run build
|
|
1365
|
-
|
|
1366
|
-
# Run tests
|
|
1367
|
-
npm test
|
|
1368
|
-
|
|
1369
|
-
# Run tests in watch mode
|
|
1370
|
-
npm run test:watch
|
|
1371
|
-
|
|
1372
|
-
# Lint code
|
|
1373
|
-
npm run lint
|
|
466
|
+
npm install # Install dependencies
|
|
467
|
+
npm run build # Build both CJS and ESM
|
|
468
|
+
npm test # Run tests
|
|
469
|
+
npm run lint # Lint code
|
|
1374
470
|
```
|
|
1375
471
|
|
|
1376
|
-
##
|
|
472
|
+
## License
|
|
1377
473
|
|
|
1378
474
|
MIT
|