ts-time-utils 4.1.0 → 4.4.1
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 +83 -32
- package/dist/{age.js → age.cjs} +14 -6
- package/dist/{calculate.js → calculate.cjs} +42 -18
- package/dist/calculate.d.ts +7 -0
- package/dist/calculate.d.ts.map +1 -1
- package/dist/{calendar.js → calendar.cjs} +80 -39
- package/dist/{calendars.js → calendars.cjs} +48 -23
- package/dist/{chain.js → chain.cjs} +41 -40
- package/dist/{compare.js → compare.cjs} +58 -28
- package/dist/constants.cjs +19 -0
- package/dist/{countdown.js → countdown.cjs} +16 -7
- package/dist/{cron.js → cron.cjs} +20 -9
- package/dist/{dateRange.js → dateRange.cjs} +42 -26
- package/dist/{duration.js → duration.cjs} +56 -44
- package/dist/esm/calculate.d.ts +7 -0
- package/dist/esm/calculate.d.ts.map +1 -1
- package/dist/esm/calculate.js +11 -0
- package/dist/esm/chain.js +0 -5
- package/dist/esm/format.d.ts.map +1 -1
- package/dist/esm/format.js +3 -3
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/naturalLanguage.d.ts +1 -3
- package/dist/esm/naturalLanguage.d.ts.map +1 -1
- package/dist/esm/naturalLanguage.js +9 -2
- package/dist/esm/plugins.d.ts +0 -6
- package/dist/esm/plugins.d.ts.map +1 -1
- package/dist/esm/plugins.js +36 -42
- package/dist/esm/recurrence.d.ts.map +1 -1
- package/dist/esm/recurrence.js +3 -5
- package/dist/esm/timezone.d.ts +6 -1
- package/dist/esm/timezone.d.ts.map +1 -1
- package/dist/esm/timezone.js +106 -66
- package/dist/esm/types.d.ts +0 -4
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/{finance.js → finance.cjs} +39 -22
- package/dist/{fiscal.js → fiscal.cjs} +36 -17
- package/dist/{format.js → format.cjs} +85 -72
- package/dist/format.d.ts.map +1 -1
- package/dist/{healthcare.js → healthcare.cjs} +37 -22
- package/dist/{holidays.js → holidays.cjs} +52 -25
- package/dist/index.cjs +596 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/{interval.js → interval.cjs} +24 -11
- package/dist/{iterate.js → iterate.cjs} +84 -41
- package/dist/{locale.js → locale.cjs} +54 -26
- package/dist/{naturalLanguage.js → naturalLanguage.cjs} +36 -23
- package/dist/naturalLanguage.d.ts +1 -3
- package/dist/naturalLanguage.d.ts.map +1 -1
- package/dist/{parse.js → parse.cjs} +24 -11
- package/dist/{performance.js → performance.cjs} +23 -10
- package/dist/{plugins.js → plugins.cjs} +48 -47
- package/dist/plugins.d.ts +0 -6
- package/dist/plugins.d.ts.map +1 -1
- package/dist/{precision.js → precision.cjs} +74 -37
- package/dist/{rangePresets.js → rangePresets.cjs} +40 -19
- package/dist/{recurrence.js → recurrence.cjs} +27 -21
- package/dist/recurrence.d.ts.map +1 -1
- package/dist/{scheduling.js → scheduling.cjs} +46 -31
- package/dist/{serialize.js → serialize.cjs} +36 -17
- package/dist/{temporal.js → temporal.cjs} +28 -13
- package/dist/{timezone.js → timezone.cjs} +140 -82
- package/dist/timezone.d.ts +6 -1
- package/dist/timezone.d.ts.map +1 -1
- package/dist/{types.js → types.cjs} +9 -3
- package/dist/types.d.ts +0 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/{validate.js → validate.cjs} +54 -26
- package/dist/{workingHours.js → workingHours.cjs} +36 -17
- package/package.json +41 -38
- package/dist/constants.js +0 -16
- package/dist/index.js +0 -72
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ts-time-utils
|
|
2
2
|
|
|
3
|
-
A comprehensive TypeScript utility library for time, dates, durations, and calendar operations. Zero dependencies, full tree-shaking support, 430+ functions across 32
|
|
3
|
+
A comprehensive TypeScript utility library for time, dates, durations, and calendar operations. Zero dependencies, full tree-shaking support, 430+ functions across 32 public modules.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/ts-time-utils)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -12,10 +12,16 @@ A comprehensive TypeScript utility library for time, dates, durations, and calen
|
|
|
12
12
|
- **Lightweight** — Import only what you need with tree-shaking support
|
|
13
13
|
- **Zero dependencies** — Pure TypeScript, no external packages
|
|
14
14
|
- **Type-safe** — Full TypeScript support with IntelliSense
|
|
15
|
-
- **Comprehensive** — 430+ functions across 32
|
|
15
|
+
- **Comprehensive** — 430+ functions across 32 public modules
|
|
16
16
|
- **Fluent API** — Chain operations with the `chain()` API
|
|
17
17
|
- **Extensible** — Plugin system for custom functionality
|
|
18
18
|
|
|
19
|
+
## When Not To Use This Library
|
|
20
|
+
|
|
21
|
+
- You only need a single built-in `Date` helper or one `Intl` formatter.
|
|
22
|
+
- You want the standardized Temporal API rather than a utility library.
|
|
23
|
+
- You need a mutable Moment-style wrapper with implicit global locale state.
|
|
24
|
+
|
|
19
25
|
## Installation
|
|
20
26
|
|
|
21
27
|
```bash
|
|
@@ -47,6 +53,16 @@ import { differenceInUnits } from 'ts-time-utils/calculate';
|
|
|
47
53
|
import { isValidDate } from 'ts-time-utils/validate';
|
|
48
54
|
```
|
|
49
55
|
|
|
56
|
+
Every public module is also available as a subpath import such as
|
|
57
|
+
`ts-time-utils/timezone`, `ts-time-utils/workingHours`, or
|
|
58
|
+
`ts-time-utils/naturalLanguage`.
|
|
59
|
+
|
|
60
|
+
### Module Selection
|
|
61
|
+
|
|
62
|
+
- Use `ts-time-utils` when you need a few core utilities from different areas.
|
|
63
|
+
- Use `ts-time-utils/format` or `ts-time-utils/calculate` when one module is enough.
|
|
64
|
+
- Use dedicated subpaths like `ts-time-utils/chain`, `ts-time-utils/plugins`, `ts-time-utils/locale`, or `ts-time-utils/workingHours` for those feature areas.
|
|
65
|
+
|
|
50
66
|
---
|
|
51
67
|
|
|
52
68
|
## Utility Categories
|
|
@@ -69,9 +85,10 @@ parseDuration('1h 30m'); // 5400000 (ms)
|
|
|
69
85
|
Date arithmetic, differences, and business day calculations.
|
|
70
86
|
|
|
71
87
|
```ts
|
|
72
|
-
import { differenceInUnits, addTime, startOf, endOf } from 'ts-time-utils/calculate';
|
|
88
|
+
import { differenceInUnits, differenceInCalendarDays, addTime, startOf, endOf } from 'ts-time-utils/calculate';
|
|
73
89
|
|
|
74
90
|
differenceInUnits(date1, date2, 'days'); // 10
|
|
91
|
+
differenceInCalendarDays(date1, date2); // Calendar date boundary count
|
|
75
92
|
addTime(new Date(), 5, 'hours'); // 5 hours from now
|
|
76
93
|
startOf(new Date(), 'day'); // 00:00:00 today
|
|
77
94
|
endOf(new Date(), 'month'); // Last moment of month
|
|
@@ -125,18 +142,22 @@ chain(new Date())
|
|
|
125
142
|
.format('YYYY-MM-DD'); // Next week Monday
|
|
126
143
|
```
|
|
127
144
|
|
|
145
|
+
Plugin extensions are imported from `ts-time-utils/plugins`, and that module now loads the chain class directly. You can import `plugins` before or after `chain` without any hidden global setup.
|
|
146
|
+
|
|
128
147
|
### Timezone
|
|
129
148
|
|
|
130
149
|
Timezone conversions, DST handling, and zone comparisons.
|
|
131
150
|
|
|
132
151
|
```ts
|
|
133
|
-
import { formatInTimeZone, isDST,
|
|
152
|
+
import { formatInTimeZone, isDST, convertBetweenZones } from 'ts-time-utils/timezone';
|
|
134
153
|
|
|
135
|
-
formatInTimeZone(
|
|
154
|
+
formatInTimeZone(new Date(), 'America/New_York');
|
|
136
155
|
isDST(new Date('2025-07-14'), 'America/New_York'); // true
|
|
137
|
-
|
|
156
|
+
convertBetweenZones(new Date(), 'UTC', 'Asia/Tokyo');
|
|
138
157
|
```
|
|
139
158
|
|
|
159
|
+
`isDST()` uses a yearly-offset heuristic rather than authoritative transition metadata.
|
|
160
|
+
|
|
140
161
|
### Calendar
|
|
141
162
|
|
|
142
163
|
ISO weeks, quarters, holidays, and calendar grids.
|
|
@@ -191,12 +212,14 @@ recurrenceToString(weekly.rule); // "Every week on Monday, Wednesday, Friday"
|
|
|
191
212
|
Parse and match cron expressions.
|
|
192
213
|
|
|
193
214
|
```ts
|
|
194
|
-
import { matchesCron, getNextCronDate, describeCron
|
|
215
|
+
import { parseCronExpression, matchesCron, getNextCronDate, describeCron } from 'ts-time-utils/cron';
|
|
216
|
+
|
|
217
|
+
const date = new Date();
|
|
195
218
|
|
|
196
|
-
|
|
219
|
+
parseCronExpression('0 9 * * 1-5'); // minute/hour/day/month/day-of-week parts
|
|
220
|
+
matchesCron(date, '0 9 * * 1-5'); // true if weekday 9am
|
|
197
221
|
getNextCronDate('0 9 * * *'); // Next 9am
|
|
198
222
|
describeCron('0 9 * * 1-5'); // "At 09:00 on Monday through Friday"
|
|
199
|
-
CRON_PRESETS.DAILY; // "0 0 * * *"
|
|
200
223
|
```
|
|
201
224
|
|
|
202
225
|
### Fiscal Year
|
|
@@ -204,11 +227,13 @@ CRON_PRESETS.DAILY; // "0 0 * * *"
|
|
|
204
227
|
Fiscal year utilities with configurable start month.
|
|
205
228
|
|
|
206
229
|
```ts
|
|
207
|
-
import { getFiscalYear, getFiscalQuarter
|
|
230
|
+
import { getFiscalYear, getFiscalQuarter } from 'ts-time-utils/fiscal';
|
|
208
231
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
getFiscalYear(date,
|
|
232
|
+
const date = new Date();
|
|
233
|
+
|
|
234
|
+
getFiscalYear(date, { startMonth: 4 }); // April start
|
|
235
|
+
getFiscalYear(date, { startMonth: 7 }); // July start
|
|
236
|
+
getFiscalYear(date, { startMonth: 10 }); // October start
|
|
212
237
|
getFiscalQuarter(date, { startMonth: 4 }); // Q2 for UK fiscal
|
|
213
238
|
```
|
|
214
239
|
|
|
@@ -254,6 +279,8 @@ extractDatesFromText('Meeting tomorrow at 3pm');
|
|
|
254
279
|
// [{ date: Date, text: 'tomorrow at 3pm', confidence: 0.9 }]
|
|
255
280
|
```
|
|
256
281
|
|
|
282
|
+
`parseNaturalDate` accepts `referenceDate`, `defaultTime`, and `strict`. When `strict` is `true`, the parser only returns the library's recognized patterns and skips the permissive `Date` fallback.
|
|
283
|
+
|
|
257
284
|
### International Holidays
|
|
258
285
|
|
|
259
286
|
Public holidays for 20 countries.
|
|
@@ -261,10 +288,12 @@ Public holidays for 20 countries.
|
|
|
261
288
|
```ts
|
|
262
289
|
import { getHolidays, isHoliday, getNextHoliday } from 'ts-time-utils/holidays';
|
|
263
290
|
|
|
291
|
+
const today = new Date();
|
|
292
|
+
|
|
264
293
|
getHolidays(2025, 'UK'); // UK bank holidays
|
|
265
294
|
getHolidays(2025, 'DE'); // German holidays
|
|
266
|
-
isHoliday(
|
|
267
|
-
getNextHoliday(
|
|
295
|
+
isHoliday(today, 'CA'); // Is Canadian holiday?
|
|
296
|
+
getNextHoliday(today, 'AU'); // Next Australian holiday
|
|
268
297
|
|
|
269
298
|
// Supported: UK, NL, DE, CA, AU, IT, ES, CN, IN, US,
|
|
270
299
|
// JP, FR, BR, MX, KR, SG, PL, SE, BE, CH
|
|
@@ -277,6 +306,9 @@ Multi-language formatting with 40+ locales.
|
|
|
277
306
|
```ts
|
|
278
307
|
import { formatRelativeTime, formatDateLocale, detectLocale } from 'ts-time-utils/locale';
|
|
279
308
|
|
|
309
|
+
const pastDate = new Date(Date.now() - 2 * 60 * 60 * 1000);
|
|
310
|
+
const date = new Date();
|
|
311
|
+
|
|
280
312
|
formatRelativeTime(pastDate, { locale: 'es' }); // "hace 2 horas"
|
|
281
313
|
formatRelativeTime(pastDate, { locale: 'de' }); // "vor 2 Stunden"
|
|
282
314
|
formatDateLocale(date, 'fr', 'long'); // "15 janvier 2024"
|
|
@@ -285,14 +317,24 @@ detectLocale(); // Auto-detect system locale
|
|
|
285
317
|
|
|
286
318
|
### Working Hours
|
|
287
319
|
|
|
288
|
-
Business hours calculations with break support.
|
|
320
|
+
Business hours calculations with break support. These helpers use the
|
|
321
|
+
`Date` values you pass in directly; if you need a different timezone's wall
|
|
322
|
+
clock, adapt the instant first with a timezone helper such as
|
|
323
|
+
`convertDateToZone()` or `reinterpretAsZone()`.
|
|
289
324
|
|
|
290
325
|
```ts
|
|
291
326
|
import { isWorkingTime, addWorkingDays, workingDaysBetween } from 'ts-time-utils/workingHours';
|
|
292
327
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
328
|
+
const config = {
|
|
329
|
+
workingDays: [1, 2, 3, 4, 5],
|
|
330
|
+
hours: { start: 9, end: 17 },
|
|
331
|
+
breaks: [{ start: 12, end: 13 }]
|
|
332
|
+
};
|
|
333
|
+
const now = new Date();
|
|
334
|
+
|
|
335
|
+
isWorkingTime(now, config);
|
|
336
|
+
addWorkingDays(now, 5, config);
|
|
337
|
+
workingDaysBetween(now, new Date('2025-12-31'), config);
|
|
296
338
|
```
|
|
297
339
|
|
|
298
340
|
### Serialization
|
|
@@ -450,12 +492,12 @@ leapSecondsBetween(date1, date2); // Number of leap seconds
|
|
|
450
492
|
Date parsing from various formats.
|
|
451
493
|
|
|
452
494
|
```ts
|
|
453
|
-
import { parseDate, parseTime,
|
|
495
|
+
import { parseDate, parseTime, guessDateFormat } from 'ts-time-utils/parse';
|
|
454
496
|
|
|
455
497
|
parseDate('Dec 25, 2025');
|
|
456
498
|
parseDate('25/12/2025', 'DD/MM/YYYY');
|
|
457
499
|
parseTime('2:30 PM'); // { hour: 14, minute: 30 }
|
|
458
|
-
|
|
500
|
+
guessDateFormat('2025-09-14'); // 'YYYY-MM-DD'
|
|
459
501
|
```
|
|
460
502
|
|
|
461
503
|
### Scheduling
|
|
@@ -471,7 +513,10 @@ import {
|
|
|
471
513
|
// Generate 30-min slots for a day
|
|
472
514
|
const slots = generateSlots(new Date(), {
|
|
473
515
|
slotDuration: 30,
|
|
474
|
-
workingHours: {
|
|
516
|
+
workingHours: {
|
|
517
|
+
workingDays: [1, 2, 3, 4, 5],
|
|
518
|
+
hours: { start: 9, end: 17 }
|
|
519
|
+
}
|
|
475
520
|
});
|
|
476
521
|
|
|
477
522
|
// Find available slots (excluding existing bookings)
|
|
@@ -557,21 +602,20 @@ timeUntilDeadline(eventDate, deadline); // Duration remaining
|
|
|
557
602
|
Extend ChainedDate with custom functionality.
|
|
558
603
|
|
|
559
604
|
```ts
|
|
560
|
-
import { chain,
|
|
605
|
+
import { chain, ChainedDate } from 'ts-time-utils/chain';
|
|
606
|
+
import { extend } from 'ts-time-utils/plugins';
|
|
561
607
|
|
|
562
|
-
|
|
563
|
-
addBusinessDays(days: number) {
|
|
608
|
+
extend('business', {
|
|
609
|
+
addBusinessDays(this: ChainedDate, days: number) {
|
|
564
610
|
// Implementation
|
|
565
611
|
return this;
|
|
566
612
|
},
|
|
567
|
-
isBusinessDay() {
|
|
613
|
+
isBusinessDay(this: ChainedDate) {
|
|
568
614
|
const day = this.toDate().getDay();
|
|
569
615
|
return day !== 0 && day !== 6;
|
|
570
616
|
}
|
|
571
617
|
});
|
|
572
618
|
|
|
573
|
-
registerPlugin(businessPlugin);
|
|
574
|
-
|
|
575
619
|
chain(new Date())
|
|
576
620
|
.addBusinessDays(5)
|
|
577
621
|
.isBusinessDay(); // true/false
|
|
@@ -628,6 +672,7 @@ For complete API documentation, see the [Playground & Docs](https://ts-time-util
|
|
|
628
672
|
npm install # Install dependencies
|
|
629
673
|
npm run build # Build both CJS and ESM
|
|
630
674
|
npm test # Run tests
|
|
675
|
+
npm run test:package # Verify built package exports after build
|
|
631
676
|
npm run lint # Lint code
|
|
632
677
|
```
|
|
633
678
|
|
|
@@ -638,16 +683,22 @@ Releases are automated via GitHub Actions with npm trusted publishing (OIDC).
|
|
|
638
683
|
**To release a new version:**
|
|
639
684
|
|
|
640
685
|
```bash
|
|
641
|
-
git tag
|
|
642
|
-
git push --tags # Push tag
|
|
686
|
+
git tag vX.Y.Z # Create a semantic version tag for the release
|
|
687
|
+
git push --tags # Push tag -> triggers publish workflow
|
|
643
688
|
```
|
|
644
689
|
|
|
645
690
|
The workflow automatically:
|
|
646
691
|
1. Sets `package.json` version from tag
|
|
647
|
-
2. Runs
|
|
692
|
+
2. Runs `npm run release:verify`
|
|
648
693
|
3. Publishes to npm with provenance
|
|
649
694
|
|
|
650
|
-
**Version format:** Tags must match `v*` pattern (e.g., `
|
|
695
|
+
**Version format:** Tags must match `v*` pattern (e.g., `v1.2.3`, `v1.2.3-beta.1`)
|
|
696
|
+
|
|
697
|
+
Before tagging, run:
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
npm run release:verify
|
|
701
|
+
```
|
|
651
702
|
|
|
652
703
|
## License
|
|
653
704
|
|
package/dist/{age.js → age.cjs}
RENAMED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateAge = calculateAge;
|
|
4
|
+
exports.getAgeInUnits = getAgeInUnits;
|
|
5
|
+
exports.getLifeStage = getLifeStage;
|
|
6
|
+
exports.getNextBirthday = getNextBirthday;
|
|
7
|
+
exports.getDaysUntilBirthday = getDaysUntilBirthday;
|
|
8
|
+
exports.isBirthday = isBirthday;
|
|
1
9
|
/**
|
|
2
10
|
* Calculate detailed age from birth date
|
|
3
11
|
* @param birthDate - date of birth
|
|
4
12
|
* @param referenceDate - date to calculate age from (defaults to now)
|
|
5
13
|
*/
|
|
6
|
-
|
|
14
|
+
function calculateAge(birthDate, referenceDate = new Date()) {
|
|
7
15
|
const birth = new Date(birthDate);
|
|
8
16
|
const reference = new Date(referenceDate);
|
|
9
17
|
let years = reference.getFullYear() - birth.getFullYear();
|
|
@@ -30,7 +38,7 @@ export function calculateAge(birthDate, referenceDate = new Date()) {
|
|
|
30
38
|
* @param unit - unit to return age in
|
|
31
39
|
* @param referenceDate - date to calculate from (defaults to now)
|
|
32
40
|
*/
|
|
33
|
-
|
|
41
|
+
function getAgeInUnits(birthDate, unit, referenceDate = new Date()) {
|
|
34
42
|
const diffMs = referenceDate.getTime() - birthDate.getTime();
|
|
35
43
|
switch (unit) {
|
|
36
44
|
case 'years':
|
|
@@ -57,7 +65,7 @@ export function getAgeInUnits(birthDate, unit, referenceDate = new Date()) {
|
|
|
57
65
|
* @param birthDate - date of birth
|
|
58
66
|
* @param referenceDate - date to calculate from (defaults to now)
|
|
59
67
|
*/
|
|
60
|
-
|
|
68
|
+
function getLifeStage(birthDate, referenceDate = new Date()) {
|
|
61
69
|
const ageInYears = getAgeInUnits(birthDate, 'years', referenceDate);
|
|
62
70
|
if (ageInYears < 2)
|
|
63
71
|
return 'infant';
|
|
@@ -74,7 +82,7 @@ export function getLifeStage(birthDate, referenceDate = new Date()) {
|
|
|
74
82
|
* @param birthDate - date of birth
|
|
75
83
|
* @param referenceDate - date to calculate from (defaults to now)
|
|
76
84
|
*/
|
|
77
|
-
|
|
85
|
+
function getNextBirthday(birthDate, referenceDate = new Date()) {
|
|
78
86
|
const birth = new Date(birthDate);
|
|
79
87
|
const reference = new Date(referenceDate);
|
|
80
88
|
const nextBirthday = new Date(reference.getFullYear(), birth.getMonth(), birth.getDate());
|
|
@@ -89,7 +97,7 @@ export function getNextBirthday(birthDate, referenceDate = new Date()) {
|
|
|
89
97
|
* @param birthDate - date of birth
|
|
90
98
|
* @param referenceDate - date to calculate from (defaults to now)
|
|
91
99
|
*/
|
|
92
|
-
|
|
100
|
+
function getDaysUntilBirthday(birthDate, referenceDate = new Date()) {
|
|
93
101
|
const nextBirthday = getNextBirthday(birthDate, referenceDate);
|
|
94
102
|
return Math.ceil((nextBirthday.getTime() - referenceDate.getTime()) / (1000 * 60 * 60 * 24));
|
|
95
103
|
}
|
|
@@ -98,7 +106,7 @@ export function getDaysUntilBirthday(birthDate, referenceDate = new Date()) {
|
|
|
98
106
|
* @param birthDate - date of birth
|
|
99
107
|
* @param referenceDate - date to check (defaults to now)
|
|
100
108
|
*/
|
|
101
|
-
|
|
109
|
+
function isBirthday(birthDate, referenceDate = new Date()) {
|
|
102
110
|
const birth = new Date(birthDate);
|
|
103
111
|
const reference = new Date(referenceDate);
|
|
104
112
|
return (birth.getMonth() === reference.getMonth() &&
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.differenceInUnits = differenceInUnits;
|
|
4
|
+
exports.differenceInCalendarDays = differenceInCalendarDays;
|
|
5
|
+
exports.addTime = addTime;
|
|
6
|
+
exports.subtractTime = subtractTime;
|
|
7
|
+
exports.startOf = startOf;
|
|
8
|
+
exports.endOf = endOf;
|
|
9
|
+
exports.isBetween = isBetween;
|
|
10
|
+
exports.businessDaysBetween = businessDaysBetween;
|
|
11
|
+
exports.roundToNearestUnit = roundToNearestUnit;
|
|
12
|
+
exports.ceilDate = ceilDate;
|
|
13
|
+
exports.floorDate = floorDate;
|
|
14
|
+
const constants_js_1 = require("./constants.cjs");
|
|
2
15
|
/**
|
|
3
16
|
* Calculate difference between two dates in specified unit
|
|
4
17
|
* @param date1 - first date
|
|
@@ -6,30 +19,30 @@ import { MILLISECONDS_PER_SECOND, MILLISECONDS_PER_MINUTE, MILLISECONDS_PER_HOUR
|
|
|
6
19
|
* @param unit - unit to return the difference in
|
|
7
20
|
* @param precise - if true, returns decimal values; if false, returns integers
|
|
8
21
|
*/
|
|
9
|
-
|
|
22
|
+
function differenceInUnits(date1, date2, unit = 'milliseconds', precise = true) {
|
|
10
23
|
const diffMs = Math.abs(date1.getTime() - date2.getTime());
|
|
11
24
|
let result;
|
|
12
25
|
switch (unit) {
|
|
13
26
|
case 'years':
|
|
14
|
-
result = diffMs / MILLISECONDS_PER_YEAR;
|
|
27
|
+
result = diffMs / constants_js_1.MILLISECONDS_PER_YEAR;
|
|
15
28
|
break;
|
|
16
29
|
case 'months':
|
|
17
|
-
result = diffMs / MILLISECONDS_PER_MONTH;
|
|
30
|
+
result = diffMs / constants_js_1.MILLISECONDS_PER_MONTH;
|
|
18
31
|
break;
|
|
19
32
|
case 'weeks':
|
|
20
|
-
result = diffMs / MILLISECONDS_PER_WEEK;
|
|
33
|
+
result = diffMs / constants_js_1.MILLISECONDS_PER_WEEK;
|
|
21
34
|
break;
|
|
22
35
|
case 'days':
|
|
23
|
-
result = diffMs / MILLISECONDS_PER_DAY;
|
|
36
|
+
result = diffMs / constants_js_1.MILLISECONDS_PER_DAY;
|
|
24
37
|
break;
|
|
25
38
|
case 'hours':
|
|
26
|
-
result = diffMs / MILLISECONDS_PER_HOUR;
|
|
39
|
+
result = diffMs / constants_js_1.MILLISECONDS_PER_HOUR;
|
|
27
40
|
break;
|
|
28
41
|
case 'minutes':
|
|
29
|
-
result = diffMs / MILLISECONDS_PER_MINUTE;
|
|
42
|
+
result = diffMs / constants_js_1.MILLISECONDS_PER_MINUTE;
|
|
30
43
|
break;
|
|
31
44
|
case 'seconds':
|
|
32
|
-
result = diffMs / MILLISECONDS_PER_SECOND;
|
|
45
|
+
result = diffMs / constants_js_1.MILLISECONDS_PER_SECOND;
|
|
33
46
|
break;
|
|
34
47
|
case 'milliseconds':
|
|
35
48
|
default:
|
|
@@ -38,13 +51,24 @@ export function differenceInUnits(date1, date2, unit = 'milliseconds', precise =
|
|
|
38
51
|
}
|
|
39
52
|
return precise ? result : Math.floor(result);
|
|
40
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Calculate the difference in local calendar days between two dates.
|
|
56
|
+
*
|
|
57
|
+
* Unlike differenceInUnits(date1, date2, 'days'), this ignores the time of day
|
|
58
|
+
* and counts date boundaries, so late today to midnight two dates from now is 2.
|
|
59
|
+
*/
|
|
60
|
+
function differenceInCalendarDays(date1, date2) {
|
|
61
|
+
const start1 = Date.UTC(date1.getFullYear(), date1.getMonth(), date1.getDate());
|
|
62
|
+
const start2 = Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate());
|
|
63
|
+
return Math.round(Math.abs(start1 - start2) / constants_js_1.MILLISECONDS_PER_DAY);
|
|
64
|
+
}
|
|
41
65
|
/**
|
|
42
66
|
* Add time to a date
|
|
43
67
|
* @param date - base date
|
|
44
68
|
* @param amount - amount to add
|
|
45
69
|
* @param unit - unit of the amount
|
|
46
70
|
*/
|
|
47
|
-
|
|
71
|
+
function addTime(date, amount, unit) {
|
|
48
72
|
const result = new Date(date);
|
|
49
73
|
switch (unit) {
|
|
50
74
|
case 'year':
|
|
@@ -97,7 +121,7 @@ export function addTime(date, amount, unit) {
|
|
|
97
121
|
* @param amount - amount to subtract
|
|
98
122
|
* @param unit - unit of the amount
|
|
99
123
|
*/
|
|
100
|
-
|
|
124
|
+
function subtractTime(date, amount, unit) {
|
|
101
125
|
return addTime(date, -amount, unit);
|
|
102
126
|
}
|
|
103
127
|
/**
|
|
@@ -105,7 +129,7 @@ export function subtractTime(date, amount, unit) {
|
|
|
105
129
|
* @param date - input date
|
|
106
130
|
* @param unit - time unit to get the start of
|
|
107
131
|
*/
|
|
108
|
-
|
|
132
|
+
function startOf(date, unit) {
|
|
109
133
|
const result = new Date(date);
|
|
110
134
|
switch (unit) {
|
|
111
135
|
case 'minute':
|
|
@@ -137,7 +161,7 @@ export function startOf(date, unit) {
|
|
|
137
161
|
* @param date - input date
|
|
138
162
|
* @param unit - time unit to get the end of
|
|
139
163
|
*/
|
|
140
|
-
|
|
164
|
+
function endOf(date, unit) {
|
|
141
165
|
const result = new Date(date);
|
|
142
166
|
switch (unit) {
|
|
143
167
|
case 'minute':
|
|
@@ -175,7 +199,7 @@ export function endOf(date, unit) {
|
|
|
175
199
|
* @param end - end date
|
|
176
200
|
* @param inclusive - whether boundaries are inclusive (default: true)
|
|
177
201
|
*/
|
|
178
|
-
|
|
202
|
+
function isBetween(date, start, end, inclusive = true) {
|
|
179
203
|
const time = date.getTime();
|
|
180
204
|
const startTime = start.getTime();
|
|
181
205
|
const endTime = end.getTime();
|
|
@@ -189,7 +213,7 @@ export function isBetween(date, start, end, inclusive = true) {
|
|
|
189
213
|
* @param startDate - start date
|
|
190
214
|
* @param endDate - end date
|
|
191
215
|
*/
|
|
192
|
-
|
|
216
|
+
function businessDaysBetween(startDate, endDate) {
|
|
193
217
|
let count = 0;
|
|
194
218
|
const current = new Date(startDate);
|
|
195
219
|
while (current <= endDate) {
|
|
@@ -209,7 +233,7 @@ export function businessDaysBetween(startDate, endDate) {
|
|
|
209
233
|
* roundToNearestUnit(new Date('2024-03-15T14:37:00'), 'hour') // 15:00
|
|
210
234
|
* roundToNearestUnit(new Date('2024-03-15T14:22:00'), 'hour') // 14:00
|
|
211
235
|
*/
|
|
212
|
-
|
|
236
|
+
function roundToNearestUnit(date, unit) {
|
|
213
237
|
const d = new Date(date);
|
|
214
238
|
switch (unit) {
|
|
215
239
|
case 'second':
|
|
@@ -263,7 +287,7 @@ export function roundToNearestUnit(date, unit) {
|
|
|
263
287
|
* @example
|
|
264
288
|
* ceilDate(new Date('2024-03-15T14:01:00'), 'hour') // 15:00
|
|
265
289
|
*/
|
|
266
|
-
|
|
290
|
+
function ceilDate(date, unit) {
|
|
267
291
|
const floored = floorDate(date, unit);
|
|
268
292
|
if (floored.getTime() === date.getTime())
|
|
269
293
|
return new Date(date);
|
|
@@ -297,7 +321,7 @@ export function ceilDate(date, unit) {
|
|
|
297
321
|
* @example
|
|
298
322
|
* floorDate(new Date('2024-03-15T14:59:00'), 'hour') // 14:00
|
|
299
323
|
*/
|
|
300
|
-
|
|
324
|
+
function floorDate(date, unit) {
|
|
301
325
|
const d = new Date(date);
|
|
302
326
|
switch (unit) {
|
|
303
327
|
case 'second':
|
package/dist/calculate.d.ts
CHANGED
|
@@ -7,6 +7,13 @@ import { TimeUnit } from './constants.js';
|
|
|
7
7
|
* @param precise - if true, returns decimal values; if false, returns integers
|
|
8
8
|
*/
|
|
9
9
|
export declare function differenceInUnits(date1: Date, date2: Date, unit?: TimeUnit, precise?: boolean): number;
|
|
10
|
+
/**
|
|
11
|
+
* Calculate the difference in local calendar days between two dates.
|
|
12
|
+
*
|
|
13
|
+
* Unlike differenceInUnits(date1, date2, 'days'), this ignores the time of day
|
|
14
|
+
* and counts date boundaries, so late today to midnight two dates from now is 2.
|
|
15
|
+
*/
|
|
16
|
+
export declare function differenceInCalendarDays(date1: Date, date2: Date): number;
|
|
10
17
|
/**
|
|
11
18
|
* Add time to a date
|
|
12
19
|
* @param date - base date
|
package/dist/calculate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calculate.d.ts","sourceRoot":"","sources":["../src/calculate.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,QAAQ,EACT,MAAM,gBAAgB,CAAC;AAExB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACX,IAAI,GAAE,QAAyB,EAC/B,OAAO,GAAE,OAAc,GACtB,MAAM,CAkCR;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAgDxE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BrG;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BnG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,GAAE,OAAc,GAAG,OAAO,CAShG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,MAAM,CAa1E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAC5D,IAAI,CA2CN;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAC5D,IAAI,CA0BN;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAC5D,IAAI,CA8BN"}
|
|
1
|
+
{"version":3,"file":"calculate.d.ts","sourceRoot":"","sources":["../src/calculate.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,QAAQ,EACT,MAAM,gBAAgB,CAAC;AAExB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,EACX,IAAI,GAAE,QAAyB,EAC/B,OAAO,GAAE,OAAc,GACtB,MAAM,CAkCR;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,MAAM,CAKzE;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAgDxE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAE7E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BrG;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CA4BnG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,GAAE,OAAc,GAAG,OAAO,CAShG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,GAAG,MAAM,CAa1E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAC5D,IAAI,CA2CN;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAC5D,IAAI,CA0BN;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAC5D,IAAI,CA8BN"}
|