@himanshu-sorathiya/datetime 1.0.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 ADDED
@@ -0,0 +1,270 @@
1
+ # Date & Time Utilities
2
+
3
+ A strictly client-side, fully type-safe, zero-dependency toolkit for parsing, querying, manipulating, and formatting dates in TypeScript. Every function is a pure, immutable transformation — no wrapper classes, no prototype patching, no hidden global state.
4
+
5
+ ## Motivation (Why this module?)
6
+
7
+ Native `Date` math is a minefield: months are 0-based, mutation happens in place, arithmetic silently overflows across month boundaries, and adding raw milliseconds breaks the moment a DST transition is crossed. Giant wrapper libraries like Moment.js solve some of this, but drag in mutable object instances, a heavyweight locale bundle, and an API surface that actively encourages chained mutation bugs.
8
+
9
+ This module takes a different approach — a flat set of small, composable functions built on four non-negotiable pillars:
10
+
11
+ - **Strict immutability.** Every public function funnels its input through a single `toDate()` gateway. If the input is already a `Date`, it is cloned via `new Date(input.getTime())` before anything touches it. No function in this engine can ever mutate the caller's original reference — which means you can chain ten operations on the same variable without ever worrying about spooky-action-at-a-distance bugs.
12
+ - **DST-safe calendar math.** Calendar-level operations (`addDays`, `addWeeks`, `startOfWeek`, etc.) use `setDate()` / `setMonth()` / `setFullYear()` rather than raw millisecond arithmetic. This forces the runtime to preserve local wall-clock time across Daylight Saving Time boundaries, instead of silently shifting `14:00` to `15:00` when a day is added.
13
+ - **Human-readable, 1-based months.** `getMonth()`, `setMonth()`, and `createDate()` all use `1 = January … 12 = December`, eliminating the classic native-`Date` off-by-one bug at the source.
14
+ - **End-of-month & leap-year clamping.** Adding a month to January 31st gives you February 28th — not an accidental rollover into March. Adding a year to February 29th gives you February 28th of the following year. The engine clamps instead of overflowing.
15
+ - **Zero-dependency localization.** All textual formatting (month names, weekday names, AM/PM, relative time, pluralization) is delegated entirely to the native `Intl` API. There are no hardcoded translation dictionaries to download, version, or fall out of date.
16
+
17
+ ## Import Syntax
18
+
19
+ ```tsx
20
+ // Preferred
21
+ import { toDate, addDays, format, isPast } from "@himanshu-sorathiya/react-kit/datetime";
22
+ // Or
23
+ import { toDate, addDays, format, isPast } from "@himanshu-sorathiya/react-kit";
24
+ ```
25
+
26
+ ## Basic Usage
27
+
28
+ ```ts
29
+ import { toDate, addDays, format } from "@himanshu-sorathiya/react-kit/datetime";
30
+
31
+ const input = toDate("2026-07-16"); // parsed once, safely
32
+ const dueDate = addDays(input, 14); // 14 days later, DST-safe
33
+
34
+ console.log(format(dueDate, "MMMM dd, yyyy"));
35
+ // → "July 30, 2026"
36
+ ```
37
+
38
+ ## API Reference
39
+
40
+ ### Core & Getters
41
+
42
+ The immutability gateway and primitive getters. Every other function in the library is built on top of these.
43
+
44
+ | Function | Returns | Notes |
45
+ | --- | --- | --- |
46
+ | `toDate(input)` | `Date` | Clones if already a `Date`; parses if `string` / `number`. The immutability gateway used internally by every other function. |
47
+ | `isDate(value)` | `boolean` | Type guard — `value instanceof Date`. |
48
+ | `isValid(date)` | `boolean` | `isDate(date) && !isNaN(date.getTime())`. |
49
+ | `createDate(year, month, day?)` | `Date` | **1-based month.** Overflow-clamped: `createDate(2026, 2, 31)` → Feb 28, not a rollover into March. `day` defaults to `1`. |
50
+ | `getYear(date)` | `number` | |
51
+ | `getMonth(date)` | `number` | **1-based** (1–12), unlike native `getMonth()`. |
52
+ | `getDate(date)` | `number` | Day of month (1–31). |
53
+ | `getHours(date)` | `number` | Local time (0–23). |
54
+ | `getMinutes(date)` | `number` | 0–59. |
55
+ | `getSeconds(date)` | `number` | 0–59. |
56
+ | `getMilliseconds(date)` | `number` | 0–999. |
57
+ | `getTimestamp(date)` | `number` | Epoch milliseconds — prefer this over repeated `isBefore()` calls in hot loops. |
58
+ | `getDayOfWeek(date)` | `number` | 0 = Sunday … 6 = Saturday (local time). |
59
+ | `getDaysInMonth(date)` | `number` | Leap-year aware. |
60
+ | `getQuarter(date)` | `number` | 1–4. |
61
+ | `getDayOfYear(date)` | `number` | 1–366, DST-safe (computed from start-of-day timestamps). |
62
+
63
+ ### Queries (Predicates)
64
+
65
+ Pure boolean functions. No date values are ever returned here — only `true` or `false`, and **invalid inputs always resolve to `false`**, never `NaN` or a thrown error.
66
+
67
+ | Function | Notes |
68
+ | --- | --- |
69
+ | `isSameDay(a, b)` | Ignores time component. |
70
+ | `isSameMonth(a, b)` | Checks year too — October 2025 ≠ October 2026. |
71
+ | `isSameYear(a, b)` | |
72
+ | `isSameQuarter(a, b)` | Checks year too. |
73
+ | `isSameWeek(a, b, weekStartsOn?)` | Defaults to Sunday start (`0`); pass `1` for Monday / ISO. |
74
+ | `isSameHour(a, b)` | Checks full date + hour. |
75
+ | `isSameMinute(a, b)` | Checks full date + hour + minute. |
76
+ | `isSameSecond(a, b)` | Checks full date + H:M:S. |
77
+ | `isSameTime(a, b)` | Checks H:M:S only — ignores the calendar date entirely. |
78
+ | `isBefore(date, compareDate)` | Strict millisecond comparison. |
79
+ | `isAfter(date, compareDate)` | Strict millisecond comparison. |
80
+ | `isEqual(a, b)` | Fixes native `Date` object-reference inequality by comparing timestamps. |
81
+ | `compareAsc(left, right)` | Array sort comparator: returns `-1`, `0`, or `1`. |
82
+ | `compareDesc(left, right)` | Reverse array sort comparator: returns `1`, `0`, or `-1`. |
83
+ | `isWithinRange(date, start, end)` | Inclusive. **Auto-swaps an inverted `start`/`end`** instead of returning `false`. |
84
+ | `isOverlapping(rangeA, rangeB)` | Strict — exact boundary touches (`rangeA.end === rangeB.start`) return `false`. |
85
+ | `isToday(date)` | Local timezone. |
86
+ | `isYesterday(date)` | Local timezone. |
87
+ | `isTomorrow(date)` | Local timezone. |
88
+ | `isPast(date)` | Strict millisecond comparison against `Date.now()`. |
89
+ | `isFuture(date)` | Strict millisecond comparison against `Date.now()`. |
90
+ | `isThisWeek(date, weekStartsOn?)` | |
91
+ | `isThisMonth(date)` | |
92
+ | `isThisYear(date)` | |
93
+ | `isFirstDayOfMonth(date)` | `getDate() === 1`. |
94
+ | `isLastDayOfMonth(date)` | Detects the month change after advancing one day. |
95
+ | `isWeekend(date)` | Saturday or Sunday, local time. |
96
+ | `isWeekday(date)` | Monday–Friday, local time. |
97
+ | `isAM(date)` | Hour is before noon (0–11). |
98
+ | `isPM(date)` | Hour is noon or later (12–23). |
99
+ | `isLeapYear(yearOrDate)` | Accepts a raw `number` **or** a `Date`. Standard Gregorian rule. |
100
+ | `isInLeapYear(date)` | Convenience wrapper — extracts the year and delegates to `isLeapYear`. |
101
+
102
+ ### Manipulation
103
+
104
+ Date arithmetic, field setters, period snapping, difference calculations, and range utilities. **Every function returns a new `Date`; originals are never mutated.**
105
+
106
+ **Add / Sub**
107
+
108
+ | Function | Notes |
109
+ | --- | --- |
110
+ | `addMilliseconds` / `subMilliseconds` | Raw millisecond math (safe — no calendar quirks at this granularity). |
111
+ | `addSeconds` / `subSeconds` | Raw millisecond math. |
112
+ | `addMinutes` / `subMinutes` | Raw millisecond math. |
113
+ | `addHours` / `subHours` | Raw millisecond math. |
114
+ | `addDays` / `subDays` | Uses `setDate()` — DST transitions never shift the time-of-day component. |
115
+ | `addWeeks` / `subWeeks` | Delegates to `addDays(date, amount * 7)`. |
116
+ | `addMonths` / `subMonths` | End-of-month clamped: `addMonths(Jan 31, 1)` → Feb 28, not Mar 3. |
117
+ | `addYears` / `subYears` | Leap-year clamped: `addYears(Feb 29 2024, 1)` → Feb 28 2025. |
118
+
119
+ **Set** (same overflow-clamping guarantees as their `add` counterparts)
120
+
121
+ | Function | Notes |
122
+ | --- | --- |
123
+ | `setYear(date, year)` | Leap-year clamped, same as `addYears`. |
124
+ | `setMonth(date, month)` | **1-based.** End-of-month clamped, same as `addMonths`. |
125
+ | `setDate(date, day)` | Clamps to `[1, daysInMonth]` — never overflows into the next month. Use `addDays` to intentionally roll over. |
126
+ | `setHours(date, hours)` | Out-of-bounds values follow native rollover behavior. |
127
+ | `setMinutes(date, minutes)` | |
128
+ | `setSeconds(date, seconds)` | |
129
+ | `setMilliseconds(date, ms)` | |
130
+
131
+ **Start / End of Period**
132
+
133
+ | Function | Notes |
134
+ | --- | --- |
135
+ | `startOfDay` / `endOfDay` | `00:00:00.000` / `23:59:59.999`. |
136
+ | `startOfHour` / `endOfHour` | |
137
+ | `startOfMinute` / `endOfMinute` | |
138
+ | `startOfWeek(date, weekStartsOn?)` | Defaults to Sunday (`0`). |
139
+ | `endOfWeek(date, weekStartsOn?)` | Defaults to Sunday (`0`). |
140
+ | `startOfMonth` / `endOfMonth` | `endOfMonth` uses the "day 0 of next month" trick — automatically leap-year correct. |
141
+ | `startOfQuarter` / `endOfQuarter` | |
142
+ | `startOfYear` / `endOfYear` | |
143
+
144
+ **Differences** (signed integer — positive means the left argument is later)
145
+
146
+ | Function | Notes |
147
+ | --- | --- |
148
+ | `differenceInMilliseconds(left, right)` | Base primitive for all sub-day differences. |
149
+ | `differenceInSeconds` / `differenceInMinutes` / `differenceInHours` | Truncated (`Math.trunc`). |
150
+ | `differenceInDays` | Both inputs snapped to `startOfDay()` first, then `Math.round()` — DST-safe. |
151
+ | `differenceInWeeks` | `Math.trunc(differenceInDays / 7)`. |
152
+ | `differenceInMonths` | Returns only **completed** months (Jan 31 → Feb 1 is `0`, not `1`). |
153
+ | `differenceInYears` | Returns only **completed** years; correctly handles Feb 29 birthdays. |
154
+ | `getOverlappingDaysInInterval(left, right)` | Calculates the number of overlapping 24-hour periods between two `DateInterval`s. |
155
+
156
+ **Business Days** (weekends excluded — no holiday calendar)
157
+
158
+ | Function | Notes |
159
+ | --- | --- |
160
+ | `addBusinessDays(date, amount)` | Traverses one day at a time skipping Sat/Sun. Negative amounts traverse backward. |
161
+ | `differenceInBusinessDays(left, right)` | O(n % 7) — counts full weeks as 5 days each, then iterates the remainder. |
162
+
163
+ **Range & Array**
164
+
165
+ | Function | Notes |
166
+ | --- | --- |
167
+ | `clampDate(date, min, max)` | Enforces `minDate` / `maxDate` picker constraints without mutation. |
168
+ | `min(dates[])` | Earliest date in the array. Returns `null` for an empty array. |
169
+ | `max(dates[])` | Latest date in the array. Returns `null` for an empty array. |
170
+ | `closestTo(date, datesArray[])` | Nearest date by absolute difference. Returns `null` for an empty array. |
171
+ | `eachMinuteOfInterval(interval, step?)` | Generates a date for every `step` minute (defaults to 1). |
172
+ | `eachHourOfInterval(interval, step?)` | Generates a date for every `step` hour (defaults to 1). |
173
+ | `eachDayOfInterval(interval)` | Every calendar day, inclusive of both boundaries. |
174
+ | `eachWeekOfInterval(interval, weekStartsOn?)` | First day of every week in the interval. |
175
+ | `eachMonthOfInterval(interval)` | First day of every month in the interval. |
176
+ | `eachYearOfInterval(interval)` | January 1st of every year in the interval. |
177
+
178
+ **Unix Timestamps**
179
+
180
+ | Function | Notes |
181
+ | --- | --- |
182
+ | `fromUnixTime(seconds)` | Converts Unix epoch **seconds** (not ms) to a `Date`. |
183
+ | `toUnixTime(date)` | Converts to Unix epoch **seconds**, truncated. |
184
+
185
+ **Rounding & ISO Weeks**
186
+
187
+ | Function | Notes |
188
+ | --- | --- |
189
+ | `roundToNearestMinutes(date, step)` | Snaps to the nearest multiple of `step` minutes. |
190
+ | `getISOWeek(date)` | ISO-8601 week number (1–53); Week 1 contains the year's first Thursday. |
191
+ | `setISOWeek(date, week)` | Shifts the date to the same weekday within the target ISO week. |
192
+
193
+ **Duration**
194
+
195
+ | Function | Notes |
196
+ | --- | --- |
197
+ | `intervalToDuration(interval)` | Cascades an interval into `{ years, months, days, hours, minutes, seconds }` largest-to-smallest, so units never double-count. |
198
+ | `durationToMilliseconds(duration)` | Approximate total — see [Gotchas](#gotchas--edge-cases). |
199
+
200
+ ### Formatting & Parsing
201
+
202
+ Locale-aware formatting and parsing powered entirely by the native `Intl` API.
203
+
204
+ | Function | Notes |
205
+ | --- | --- |
206
+ | `format(date, formatString, options?)` | Token-based pattern formatting (`"yyyy-MM-dd"`, etc.). Supports `'literal text'` escaping. |
207
+ | `formatDate(date, locale?, options?)` | Thin wrapper over `Intl.DateTimeFormat` — use for strict, options-driven localization. |
208
+ | `formatRelativeTime(date, baseDate?, locale?)` | Wraps `Intl.RelativeTimeFormat`; auto-selects the most meaningful unit (seconds → years). |
209
+ | `formatDistance(date, baseDate, options?)` | "less than a minute", "about 2 hours", etc. Supports `addSuffix`. |
210
+ | `formatDistanceStrict(date, baseDate, options?)` | Strict unit distance without fuzzy words. Enforces specific units and rounding. |
211
+ | `formatDistanceToNow(date, options?)` | Convenience wrapper over `formatDistance` against current time. |
212
+ | `formatDistanceIntl(date, baseDate, options?)` | `Intl`-powered exact relative time (e.g. "in 2 days", "3 hours ago"). |
213
+ | `formatRelative(date, baseDate, options?)` | "Today at 2:00 PM", "Tomorrow at...", "Last Friday at...". |
214
+ | `formatISO(date, options?)` | ISO 8601 using the **local** timezone offset, unlike native `toISOString()`. |
215
+ | `formatRFC3339(date, options?)` | RFC 3339 — the internet-protocol profile of ISO 8601. Outputs `"Z"` for UTC offset. |
216
+ | `formatISO9075(date, options?)` | The SQL datetime standard (space separator, no offset) used by Postgres/MySQL/SQLite. |
217
+ | `formatRFC2822(date)` | Email/HTTP header format. Day and month names are always English per the RFC spec. |
218
+ | `formatDuration(duration, options?)` | Human-readable duration string with `Intl.PluralRules`-correct pluralization. |
219
+ | `toISOString(date)` | Thin wrapper over native `toISOString()` — always UTC, always ends in `"Z"`. |
220
+ | `parseISO(isoString)` | **Strict** ISO 8601 parser — rejects locale-specific/ambiguous formats (unlike the permissive `toDate()`). |
221
+
222
+ ## Advanced Usage & Examples
223
+
224
+ ### Safe Date Chaining
225
+
226
+ Because every function clones its input before touching it, you can chain operations inline without ever worrying about a downstream call mutating an upstream reference:
227
+
228
+ ```ts
229
+ import {
230
+ startOfWeek,
231
+ addBusinessDays,
232
+ format,
233
+ } from "@himanshu-sorathiya/react-kit/datetime";
234
+
235
+ const today = new Date();
236
+
237
+ const dueDate = format(
238
+ addBusinessDays(startOfWeek(today, 1), 3), // Monday-start week + 3 business days
239
+ "EEEE, MMMM dd yyyy",
240
+ );
241
+
242
+ console.log(dueDate); // → "Thursday, July 16 2026"
243
+ console.log(today); // → untouched — the original reference was never mutated
244
+ ```
245
+
246
+ `startOfWeek` clones `today` before snapping it to Monday, `addBusinessDays` clones that result again before walking forward — so `today` is guaranteed to still point at the exact instant it was created, no matter how many functions are chained on top of it.
247
+
248
+ ## Real-World Use Cases
249
+
250
+ - Building custom date-picker calendar grids, including blank-cell padding before the 1st and "Today" highlighting.
251
+ - Calculating user trial or subscription expiration dates, and the number of days remaining.
252
+ - Rendering localized activity/timeline feeds ("3 hours ago", "in 2 days") without a translation bundle.
253
+ - Validating age restrictions (e.g. 18+) on signup or KYC forms.
254
+ - Drawing Gantt chart bars and interval overlays from raw start/end dates.
255
+ - Detecting scheduling conflicts or double-bookings in calendar and meeting-room apps.
256
+ - Snapping free-form time selections to fixed appointment slots (e.g. rounding to the nearest 15 minutes).
257
+ - Computing business-day SLAs and shipping/delivery estimates while skipping weekends.
258
+ - Generating recurring event occurrences across a bounded date range.
259
+ - Formatting timestamps for API payloads, database inserts, and email headers (RFC 3339, ISO 9075, RFC 2822).
260
+
261
+ ## Gotchas & Edge Cases
262
+
263
+ - **Local timezone mandate.** The entire library operates in the runtime's local timezone. Parsing a UTC string (e.g. via `toDate()`) converts it to local time under the hood — there is no "UTC mode."
264
+ - **Graceful failures, not exceptions.** All numeric getters return `NaN` and all query/predicate functions return `false` when given an invalid date input. Nothing in this library throws on bad input.
265
+ - **Day-level past/future checks.** `isPast(startOfDay(today))` evaluates to `true`, because midnight of the current day is already in the past. If you need to know whether a *calendar day* (not a timestamp) is yesterday or older, use `isBefore(date, startOfDay(new Date()))` instead of `isPast()` directly.
266
+ - **Zero-duration overlaps.** `isOverlapping` treats an exact boundary touch (Event A ends exactly when Event B starts) as **not** overlapping — it returns `false`. This holds true even for zero-duration events (`start === end`) that land precisely on a boundary.
267
+ - **`durationToMilliseconds` is an approximation — never use it for arithmetic.** It computes years and months using mean averages (365.25 days/year, 30.4375 days/month) because their true length varies. It is intended strictly for **sorting and comparing** the relative size of durations. Using its output to actually advance a clock or a calendar date will introduce drift.
268
+ - **`intervalToDuration` always returns an absolute duration.** It strips away chronological direction: even if `interval.start` is chronologically *after* `interval.end`, the returned `Duration` is always positive.
269
+ - **`format` vs. `formatDate`.** Prefer `formatDate` when you need strict, correct localization — it delegates fully to `Intl.DateTimeFormat`, which natively supports non-Gregorian calendars and Eastern Arabic numerals. The `format` token parser, by contrast, builds its output from padded native getters, so it **always** produces Western Arabic numerals (0–9) on the **Gregorian calendar**, regardless of the `locale` option passed.
270
+ - **`formatDuration`'s locale support is partial.** It uses `Intl.PluralRules` to select the grammatically correct plural form (correctly handling languages like Arabic, which has six plural categories) — but the unit label strings themselves ("years", "months", "days", …) are currently hardcoded to English only.
@@ -0,0 +1,285 @@
1
+ export declare function addBusinessDays(date: DateInput, amount: number): Date;
2
+
3
+ export declare function addDays(date: DateInput, amount: number): Date;
4
+
5
+ export declare function addHours(date: DateInput, amount: number): Date;
6
+
7
+ export declare function addMilliseconds(date: DateInput, amount: number): Date;
8
+
9
+ export declare function addMinutes(date: DateInput, amount: number): Date;
10
+
11
+ export declare function addMonths(date: DateInput, amount: number): Date;
12
+
13
+ export declare function addSeconds(date: DateInput, amount: number): Date;
14
+
15
+ export declare function addWeeks(date: DateInput, amount: number): Date;
16
+
17
+ export declare function addYears(date: DateInput, amount: number): Date;
18
+
19
+ export declare function clampDate(date: DateInput, min: DateInput, max: DateInput): Date;
20
+
21
+ export declare function closestTo(date: DateInput, datesArray: Date[]): Date | null;
22
+
23
+ export declare function compareAsc(dateLeft: DateInput, dateRight: DateInput): number;
24
+
25
+ export declare function compareDesc(dateLeft: DateInput, dateRight: DateInput): number;
26
+
27
+ export declare function createDate(year: number, month: number, day?: number): Date;
28
+
29
+ declare type DateInput = Date | number | string;
30
+
31
+ declare type DateInterval = {
32
+ start: Date;
33
+ end: Date;
34
+ };
35
+
36
+ declare type DateRange = {
37
+ start: Date;
38
+ end: Date;
39
+ };
40
+
41
+ export declare function differenceInBusinessDays(dateLeft: DateInput, dateRight: DateInput): number;
42
+
43
+ export declare function differenceInDays(dateLeft: DateInput, dateRight: DateInput): number;
44
+
45
+ export declare function differenceInHours(dateLeft: DateInput, dateRight: DateInput): number;
46
+
47
+ export declare function differenceInMilliseconds(dateLeft: DateInput, dateRight: DateInput): number;
48
+
49
+ export declare function differenceInMinutes(dateLeft: DateInput, dateRight: DateInput): number;
50
+
51
+ export declare function differenceInMonths(dateLeft: DateInput, dateRight: DateInput): number;
52
+
53
+ export declare function differenceInSeconds(dateLeft: DateInput, dateRight: DateInput): number;
54
+
55
+ export declare function differenceInWeeks(dateLeft: DateInput, dateRight: DateInput): number;
56
+
57
+ export declare function differenceInYears(dateLeft: DateInput, dateRight: DateInput): number;
58
+
59
+ declare type Duration = {
60
+ years?: number;
61
+ months?: number;
62
+ weeks?: number;
63
+ days?: number;
64
+ hours?: number;
65
+ minutes?: number;
66
+ seconds?: number;
67
+ };
68
+
69
+ export declare function durationToMilliseconds(duration: Duration): number;
70
+
71
+ export declare function eachDayOfInterval(interval: DateInterval): Date[];
72
+
73
+ export declare function eachHourOfInterval(interval: DateInterval, step?: number): Date[];
74
+
75
+ export declare function eachMinuteOfInterval(interval: DateInterval, step?: number): Date[];
76
+
77
+ export declare function eachMonthOfInterval(interval: DateInterval): Date[];
78
+
79
+ export declare function eachWeekOfInterval(interval: DateInterval, weekStartsOn?: WeekStartsOn): Date[];
80
+
81
+ export declare function eachYearOfInterval(interval: DateInterval): Date[];
82
+
83
+ export declare function endOfDay(date: DateInput): Date;
84
+
85
+ export declare function endOfHour(date: DateInput): Date;
86
+
87
+ export declare function endOfMinute(date: DateInput): Date;
88
+
89
+ export declare function endOfMonth(date: DateInput): Date;
90
+
91
+ export declare function endOfQuarter(date: DateInput): Date;
92
+
93
+ export declare function endOfWeek(date: DateInput, weekStartsOn?: WeekStartsOn): Date;
94
+
95
+ export declare function endOfYear(date: DateInput): Date;
96
+
97
+ export declare function format(date: DateInput, formatString: string, options?: {
98
+ locale?: string;
99
+ }): string;
100
+
101
+ export declare function formatDate(date: DateInput, locale?: string | string[], options?: Intl.DateTimeFormatOptions): string;
102
+
103
+ export declare function formatDuration(duration: Duration, options?: {
104
+ format?: ReadonlyArray<keyof Duration>;
105
+ zero?: boolean;
106
+ delimiter?: string;
107
+ locale?: string;
108
+ }): string;
109
+
110
+ export declare function formatISO(date: DateInput, options?: {
111
+ format?: 'extended' | 'basic';
112
+ representation?: 'complete' | 'date' | 'time';
113
+ }): string;
114
+
115
+ export declare function formatISO9075(date: DateInput, options?: {
116
+ representation?: 'complete' | 'date' | 'time';
117
+ }): string;
118
+
119
+ export declare function formatRelativeTime(date: DateInput, baseDate?: DateInput, locale?: string | string[]): string;
120
+
121
+ export declare function formatRFC2822(date: DateInput): string;
122
+
123
+ export declare function formatRFC3339(date: DateInput, options?: {
124
+ fractionDigits?: 0 | 1 | 2 | 3;
125
+ }): string;
126
+
127
+ export declare function fromUnixTime(seconds: number): Date;
128
+
129
+ export declare function getDate(date: DateInput): number;
130
+
131
+ export declare function getDayOfWeek(date: DateInput): number;
132
+
133
+ export declare function getDayOfYear(date: DateInput): number;
134
+
135
+ export declare function getDaysInMonth(date: DateInput): number;
136
+
137
+ export declare function getHours(date: DateInput): number;
138
+
139
+ export declare function getISOWeek(date: DateInput): number;
140
+
141
+ export declare function getMilliseconds(date: DateInput): number;
142
+
143
+ export declare function getMinutes(date: DateInput): number;
144
+
145
+ export declare function getMonth(date: DateInput): number;
146
+
147
+ export declare function getOverlappingDaysInInterval(intervalLeft: DateInterval, intervalRight: DateInterval): number;
148
+
149
+ export declare function getQuarter(date: DateInput): number;
150
+
151
+ export declare function getSeconds(date: DateInput): number;
152
+
153
+ export declare function getTimestamp(date: DateInput): number;
154
+
155
+ export declare function getYear(date: DateInput): number;
156
+
157
+ export declare function intervalToDuration(interval: DateInterval): Duration;
158
+
159
+ export declare function isAfter(date: DateInput, compareDate: DateInput): boolean;
160
+
161
+ export declare function isAM(date: DateInput): boolean;
162
+
163
+ export declare function isBefore(date: DateInput, compareDate: DateInput): boolean;
164
+
165
+ export declare function isDate(value: unknown): value is Date;
166
+
167
+ export declare function isEqual(dateA: DateInput, dateB: DateInput): boolean;
168
+
169
+ export declare function isFirstDayOfMonth(date: DateInput): boolean;
170
+
171
+ export declare function isFuture(date: DateInput): boolean;
172
+
173
+ export declare function isInLeapYear(date: DateInput): boolean;
174
+
175
+ export declare function isLastDayOfMonth(date: DateInput): boolean;
176
+
177
+ export declare function isLeapYear(yearOrDate: number | Date): boolean;
178
+
179
+ export declare function isOverlapping(rangeA: DateRange, rangeB: DateRange): boolean;
180
+
181
+ export declare function isPast(date: DateInput): boolean;
182
+
183
+ export declare function isPM(date: DateInput): boolean;
184
+
185
+ export declare function isSameDay(dateA: DateInput, dateB: DateInput): boolean;
186
+
187
+ export declare function isSameHour(dateA: DateInput, dateB: DateInput): boolean;
188
+
189
+ export declare function isSameMinute(dateA: DateInput, dateB: DateInput): boolean;
190
+
191
+ export declare function isSameMonth(dateA: DateInput, dateB: DateInput): boolean;
192
+
193
+ export declare function isSameQuarter(dateA: DateInput, dateB: DateInput): boolean;
194
+
195
+ export declare function isSameSecond(dateA: DateInput, dateB: DateInput): boolean;
196
+
197
+ export declare function isSameTime(dateA: DateInput, dateB: DateInput): boolean;
198
+
199
+ export declare function isSameWeek(dateA: DateInput, dateB: DateInput, weekStartsOn?: WeekStartsOn): boolean;
200
+
201
+ export declare function isSameYear(dateA: DateInput, dateB: DateInput): boolean;
202
+
203
+ export declare function isThisMonth(date: DateInput): boolean;
204
+
205
+ export declare function isThisWeek(date: DateInput, weekStartsOn?: WeekStartsOn): boolean;
206
+
207
+ export declare function isThisYear(date: DateInput): boolean;
208
+
209
+ export declare function isToday(date: DateInput): boolean;
210
+
211
+ export declare function isTomorrow(date: DateInput): boolean;
212
+
213
+ export declare function isValid(date: Date): boolean;
214
+
215
+ export declare function isWeekday(date: DateInput): boolean;
216
+
217
+ export declare function isWeekend(date: DateInput): boolean;
218
+
219
+ export declare function isWithinRange(date: DateInput, start: DateInput, end: DateInput): boolean;
220
+
221
+ export declare function isYesterday(date: DateInput): boolean;
222
+
223
+ export declare function max(dates: Date[]): Date | null;
224
+
225
+ export declare function min(dates: Date[]): Date | null;
226
+
227
+ export declare function parseISO(isoString: string): Date;
228
+
229
+ export declare function roundToNearestMinutes(date: DateInput, step: number): Date;
230
+
231
+ export declare function setDate(date: DateInput, day: number): Date;
232
+
233
+ export declare function setHours(date: DateInput, hours: number): Date;
234
+
235
+ export declare function setISOWeek(date: DateInput, week: number): Date;
236
+
237
+ export declare function setMilliseconds(date: DateInput, ms: number): Date;
238
+
239
+ export declare function setMinutes(date: DateInput, minutes: number): Date;
240
+
241
+ export declare function setMonth(date: DateInput, month: number): Date;
242
+
243
+ export declare function setSeconds(date: DateInput, seconds: number): Date;
244
+
245
+ export declare function setYear(date: DateInput, year: number): Date;
246
+
247
+ export declare function startOfDay(date: DateInput): Date;
248
+
249
+ export declare function startOfHour(date: DateInput): Date;
250
+
251
+ export declare function startOfMinute(date: DateInput): Date;
252
+
253
+ export declare function startOfMonth(date: DateInput): Date;
254
+
255
+ export declare function startOfQuarter(date: DateInput): Date;
256
+
257
+ export declare function startOfWeek(date: DateInput, weekStartsOn?: WeekStartsOn): Date;
258
+
259
+ export declare function startOfYear(date: DateInput): Date;
260
+
261
+ export declare function subDays(date: DateInput, amount: number): Date;
262
+
263
+ export declare function subHours(date: DateInput, amount: number): Date;
264
+
265
+ export declare function subMilliseconds(date: DateInput, amount: number): Date;
266
+
267
+ export declare function subMinutes(date: DateInput, amount: number): Date;
268
+
269
+ export declare function subMonths(date: DateInput, amount: number): Date;
270
+
271
+ export declare function subSeconds(date: DateInput, amount: number): Date;
272
+
273
+ export declare function subWeeks(date: DateInput, amount: number): Date;
274
+
275
+ export declare function subYears(date: DateInput, amount: number): Date;
276
+
277
+ export declare function toDate(input: DateInput): Date;
278
+
279
+ export declare function toISOString(date: DateInput): string;
280
+
281
+ export declare function toUnixTime(date: DateInput): number;
282
+
283
+ declare type WeekStartsOn = 0 | 1 | 2 | 3 | 4 | 5 | 6;
284
+
285
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,630 @@
1
+ //#region src/core.ts
2
+ function e(e) {
3
+ return e instanceof Date ? new Date(e.getTime()) : typeof e != "number" && typeof e != "string" ? /* @__PURE__ */ new Date(NaN) : new Date(e);
4
+ }
5
+ function t(e) {
6
+ return e instanceof Date;
7
+ }
8
+ function n(e) {
9
+ return t(e) && !isNaN(e.getTime());
10
+ }
11
+ function r(e, t, n = 1) {
12
+ let r = new Date(e, t - 1, n);
13
+ return r.getMonth() === t - 1 ? r : new Date(e, t, 0);
14
+ }
15
+ function i(t) {
16
+ return e(t).getFullYear();
17
+ }
18
+ function a(t) {
19
+ return e(t).getMonth() + 1;
20
+ }
21
+ function o(t) {
22
+ return e(t).getDate();
23
+ }
24
+ function s(t) {
25
+ return e(t).getHours();
26
+ }
27
+ function c(t) {
28
+ return e(t).getMinutes();
29
+ }
30
+ function l(t) {
31
+ return e(t).getSeconds();
32
+ }
33
+ function u(t) {
34
+ return e(t).getMilliseconds();
35
+ }
36
+ function d(t) {
37
+ return e(t).getTime();
38
+ }
39
+ function f(t) {
40
+ return e(t).getDay();
41
+ }
42
+ function p(t) {
43
+ let n = e(t);
44
+ return new Date(n.getFullYear(), n.getMonth() + 1, 0).getDate();
45
+ }
46
+ function m(t) {
47
+ return Math.ceil((e(t).getMonth() + 1) / 3);
48
+ }
49
+ function h(t) {
50
+ let n = e(t), r = new Date(n.getFullYear(), 0, 1, 0, 0, 0, 0), i = new Date(n.getFullYear(), n.getMonth(), n.getDate(), 0, 0, 0, 0);
51
+ return Math.round((i.getTime() - r.getTime()) / 864e5) + 1;
52
+ }
53
+ //#endregion
54
+ //#region src/manipulation.ts
55
+ function g(t, n) {
56
+ return new Date(e(t).getTime() + n);
57
+ }
58
+ function _(t, n) {
59
+ return new Date(e(t).getTime() + n * V);
60
+ }
61
+ function v(t, n) {
62
+ return new Date(e(t).getTime() + n * H);
63
+ }
64
+ function y(t, n) {
65
+ return new Date(e(t).getTime() + n * U);
66
+ }
67
+ function b(t, n) {
68
+ let r = e(t);
69
+ return r.setDate(r.getDate() + n), r;
70
+ }
71
+ function x(e, t) {
72
+ return b(e, t * 7);
73
+ }
74
+ function S(t, n) {
75
+ let r = e(t), i = r.getDate();
76
+ return r.setDate(1), r.setMonth(r.getMonth() + n), r.setDate(Math.min(i, p(r))), r;
77
+ }
78
+ function C(t, n) {
79
+ let r = e(t), i = r.getMonth();
80
+ return r.setFullYear(r.getFullYear() + n), r.getMonth() !== i && r.setDate(0), r;
81
+ }
82
+ function w(e, t) {
83
+ return g(e, -t);
84
+ }
85
+ function ee(e, t) {
86
+ return _(e, -t);
87
+ }
88
+ function te(e, t) {
89
+ return v(e, -t);
90
+ }
91
+ function ne(e, t) {
92
+ return y(e, -t);
93
+ }
94
+ function re(e, t) {
95
+ return b(e, -t);
96
+ }
97
+ function ie(e, t) {
98
+ return x(e, -t);
99
+ }
100
+ function ae(e, t) {
101
+ return S(e, -t);
102
+ }
103
+ function oe(e, t) {
104
+ return C(e, -t);
105
+ }
106
+ function se(t, n) {
107
+ let r = e(t), i = r.getMonth();
108
+ return r.setFullYear(n), r.getMonth() !== i && r.setDate(0), r;
109
+ }
110
+ function T(t, n) {
111
+ let r = e(t), i = r.getDate();
112
+ return r.setDate(1), r.setMonth(n - 1), r.setDate(Math.min(i, p(r))), r;
113
+ }
114
+ function ce(t, n) {
115
+ let r = e(t), i = p(r);
116
+ return r.setDate(Math.min(Math.max(1, n), i)), r;
117
+ }
118
+ function le(t, n) {
119
+ let r = e(t);
120
+ return r.setHours(n), r;
121
+ }
122
+ function ue(t, n) {
123
+ let r = e(t);
124
+ return r.setMinutes(n), r;
125
+ }
126
+ function de(t, n) {
127
+ let r = e(t);
128
+ return r.setSeconds(n), r;
129
+ }
130
+ function fe(t, n) {
131
+ let r = e(t);
132
+ return r.setMilliseconds(n), r;
133
+ }
134
+ function E(t) {
135
+ let n = e(t);
136
+ return n.setHours(0, 0, 0, 0), n;
137
+ }
138
+ function pe(t) {
139
+ let n = e(t);
140
+ return n.setHours(23, 59, 59, 999), n;
141
+ }
142
+ function D(t) {
143
+ let n = e(t);
144
+ return n.setMinutes(0, 0, 0), n;
145
+ }
146
+ function me(t) {
147
+ let n = e(t);
148
+ return n.setMinutes(59, 59, 999), n;
149
+ }
150
+ function O(t) {
151
+ let n = e(t);
152
+ return n.setSeconds(0, 0), n;
153
+ }
154
+ function he(t) {
155
+ let n = e(t);
156
+ return n.setSeconds(59, 999), n;
157
+ }
158
+ function k(t, n = 0) {
159
+ let r = e(t), i = (r.getDay() - n + 7) % 7;
160
+ return r.setDate(r.getDate() - i), r.setHours(0, 0, 0, 0), r;
161
+ }
162
+ function ge(e, t = 0) {
163
+ let n = k(e, t);
164
+ return n.setDate(n.getDate() + 6), n.setHours(23, 59, 59, 999), n;
165
+ }
166
+ function A(t) {
167
+ let n = e(t);
168
+ return n.setDate(1), n.setHours(0, 0, 0, 0), n;
169
+ }
170
+ function _e(t) {
171
+ let n = e(t);
172
+ return new Date(n.getFullYear(), n.getMonth() + 1, 0, 23, 59, 59, 999);
173
+ }
174
+ function ve(t) {
175
+ let n = e(t), r = n.getMonth() - n.getMonth() % 3;
176
+ return new Date(n.getFullYear(), r, 1, 0, 0, 0, 0);
177
+ }
178
+ function ye(t) {
179
+ let n = e(t), r = n.getMonth() - n.getMonth() % 3 + 2;
180
+ return new Date(n.getFullYear(), r + 1, 0, 23, 59, 59, 999);
181
+ }
182
+ function j(t) {
183
+ let n = e(t);
184
+ return new Date(n.getFullYear(), 0, 1, 0, 0, 0, 0);
185
+ }
186
+ function M(t) {
187
+ let n = e(t);
188
+ return new Date(n.getFullYear(), 11, 31, 23, 59, 59, 999);
189
+ }
190
+ function N(t, n) {
191
+ return e(t).getTime() - e(n).getTime();
192
+ }
193
+ function P(e, t) {
194
+ return Math.trunc(N(e, t) / V);
195
+ }
196
+ function F(e, t) {
197
+ return Math.trunc(N(e, t) / H);
198
+ }
199
+ function I(e, t) {
200
+ return Math.trunc(N(e, t) / U);
201
+ }
202
+ function L(t, n) {
203
+ let r = E(e(t)), i = E(e(n));
204
+ return Math.round((r.getTime() - i.getTime()) / W);
205
+ }
206
+ function be(e, t) {
207
+ return Math.trunc(L(e, t) / 7);
208
+ }
209
+ function R(t, n) {
210
+ let r = e(t), i = e(n), a = r.getFullYear() - i.getFullYear(), o = r.getMonth() - i.getMonth(), s = a * 12 + o, c = S(i, s);
211
+ return s > 0 && c.getTime() > r.getTime() ? s - 1 : s < 0 && c.getTime() < r.getTime() ? s + 1 : s;
212
+ }
213
+ function z(t, n) {
214
+ let r = e(t), i = e(n), a = r.getFullYear() - i.getFullYear(), o = C(i, a);
215
+ return a > 0 && o.getTime() > r.getTime() ? a - 1 : a < 0 && o.getTime() < r.getTime() ? a + 1 : a;
216
+ }
217
+ function xe(t, n) {
218
+ let r = e(t), i = n < 0 ? -1 : 1, a = Math.abs(n);
219
+ for (; a > 0;) {
220
+ r.setDate(r.getDate() + i);
221
+ let e = r.getDay();
222
+ e !== 0 && e !== 6 && a--;
223
+ }
224
+ return r;
225
+ }
226
+ function Se(t, n) {
227
+ let r = E(e(t)), i = E(e(n)), a = L(r, i);
228
+ if (a === 0) return 0;
229
+ let o = a > 0 ? 1 : -1, s = Math.abs(a), c = Math.floor(s / 7) * 5, l = new Date(i);
230
+ for (let e = 0; e < s % 7; e++) {
231
+ l.setDate(l.getDate() + o);
232
+ let e = l.getDay();
233
+ e !== 0 && e !== 6 && c++;
234
+ }
235
+ return c * o;
236
+ }
237
+ function Ce(t, r, i) {
238
+ let a = e(t), o = e(r), s = e(i);
239
+ return !n(a) || !n(o) || !n(s) ? /* @__PURE__ */ new Date(NaN) : a.getTime() < o.getTime() ? o : a.getTime() > s.getTime() ? s : a;
240
+ }
241
+ function we(e) {
242
+ return e.length === 0 ? null : new Date(Math.min(...e.map((e) => e.getTime())));
243
+ }
244
+ function Te(e) {
245
+ return e.length === 0 ? null : new Date(Math.max(...e.map((e) => e.getTime())));
246
+ }
247
+ function Ee(t, r) {
248
+ if (r.length === 0) return null;
249
+ let i = e(t);
250
+ if (!n(i)) return /* @__PURE__ */ new Date(NaN);
251
+ let a = i.getTime();
252
+ return r.reduce((e, t) => n(t) && Math.abs(t.getTime() - a) < Math.abs(e.getTime() - a) ? t : e);
253
+ }
254
+ function De(t, n = 1) {
255
+ let r = [], i = O(e(t.start)), a = O(e(t.end)), o = new Date(i), s = Math.trunc(n);
256
+ if (s < 1 || Number.isNaN(s)) return r;
257
+ for (; o.getTime() <= a.getTime();) r.push(new Date(o)), o.setMinutes(o.getMinutes() + s);
258
+ return r;
259
+ }
260
+ function Oe(t, n = 1) {
261
+ let r = [], i = D(e(t.start)), a = D(e(t.end)), o = new Date(i), s = Math.trunc(n);
262
+ if (s < 1 || Number.isNaN(s)) return r;
263
+ for (; o.getTime() <= a.getTime();) r.push(new Date(o)), o.setHours(o.getHours() + s);
264
+ return r;
265
+ }
266
+ function ke(t) {
267
+ let n = [], r = E(e(t.start)), i = E(e(t.end)), a = new Date(r);
268
+ for (; a.getTime() <= i.getTime();) n.push(new Date(a)), a.setDate(a.getDate() + 1);
269
+ return n;
270
+ }
271
+ function Ae(t, n = 0) {
272
+ let r = [], i = k(e(t.start), n), a = k(e(t.end), n), o = new Date(i);
273
+ for (; o.getTime() <= a.getTime();) r.push(new Date(o)), o.setDate(o.getDate() + 7);
274
+ return r;
275
+ }
276
+ function je(t) {
277
+ let n = [], r = A(e(t.start)), i = A(e(t.end)), a = new Date(r);
278
+ for (; a.getTime() <= i.getTime();) n.push(new Date(a)), a.setMonth(a.getMonth() + 1);
279
+ return n;
280
+ }
281
+ function Me(t) {
282
+ let n = [], r = j(e(t.start)), i = j(e(t.end)), a = new Date(r);
283
+ for (; a.getTime() <= i.getTime();) n.push(new Date(a)), a.setFullYear(a.getFullYear() + 1);
284
+ return n;
285
+ }
286
+ function Ne(e) {
287
+ return /* @__PURE__ */ new Date(e * 1e3);
288
+ }
289
+ function Pe(t) {
290
+ return Math.floor(e(t).getTime() / 1e3);
291
+ }
292
+ function Fe(t, n) {
293
+ let r = n * H;
294
+ return new Date(Math.round(e(t).getTime() / r) * r);
295
+ }
296
+ function B(t) {
297
+ let n = e(t), r = n.getDay() || 7;
298
+ n.setDate(n.getDate() + 4 - r);
299
+ let i = new Date(n.getFullYear(), 0, 1);
300
+ return Math.ceil(((n.getTime() - i.getTime()) / W + 1) / 7);
301
+ }
302
+ function Ie(t, n) {
303
+ let r = e(t), i = B(r);
304
+ return r.setDate(r.getDate() + (n - i) * 7), r;
305
+ }
306
+ function Le(t) {
307
+ let n = e(t.start), r = e(t.end), [i, a] = n.getTime() <= r.getTime() ? [n, r] : [r, n], o = z(a, i), s = C(i, o), c = R(a, s), l = S(s, c), u = L(a, l), d = b(l, u), f = I(a, d), p = y(d, f), m = F(a, p);
308
+ return {
309
+ years: o,
310
+ months: c,
311
+ days: u,
312
+ hours: f,
313
+ minutes: m,
314
+ seconds: P(a, v(p, m))
315
+ };
316
+ }
317
+ function Re(e) {
318
+ let t = 365.25 * W, n = 30.4375 * W;
319
+ return (e.years ?? 0) * t + (e.months ?? 0) * n + (e.weeks ?? 0) * 7 * W + (e.days ?? 0) * W + (e.hours ?? 0) * U + (e.minutes ?? 0) * H + (e.seconds ?? 0) * V;
320
+ }
321
+ function ze(t, r) {
322
+ let i = e(t.start), a = e(t.end), o = e(r.start), s = e(r.end);
323
+ if (!n(i) || !n(a) || !n(o) || !n(s)) return NaN;
324
+ let c = i.getTime(), l = a.getTime(), u = o.getTime(), d = s.getTime(), [f, p] = c <= l ? [c, l] : [l, c], [m, h] = u <= d ? [u, d] : [d, u];
325
+ return f < h && p > m ? Math.ceil(((p > h ? h : p) - (f < m ? m : f)) / W) : 0;
326
+ }
327
+ //#endregion
328
+ //#region src/constants.ts
329
+ var V = 1e3, H = 6e4, U = 36e5, W = 864e5, G = {
330
+ yyyy: (e) => String(e.getFullYear()).padStart(4, "0"),
331
+ yy: (e) => String(e.getFullYear()).slice(-2),
332
+ MMMM: (e, t) => new Intl.DateTimeFormat(t, { month: "long" }).format(e),
333
+ MMM: (e, t) => new Intl.DateTimeFormat(t, { month: "short" }).format(e),
334
+ MM: (e) => String(e.getMonth() + 1).padStart(2, "0"),
335
+ M: (e) => String(e.getMonth() + 1),
336
+ dd: (e) => String(e.getDate()).padStart(2, "0"),
337
+ d: (e) => String(e.getDate()),
338
+ EEEE: (e, t) => new Intl.DateTimeFormat(t, { weekday: "long" }).format(e),
339
+ EEE: (e, t) => new Intl.DateTimeFormat(t, { weekday: "short" }).format(e),
340
+ E: (e, t) => new Intl.DateTimeFormat(t, { weekday: "short" }).format(e),
341
+ HH: (e) => String(e.getHours()).padStart(2, "0"),
342
+ H: (e) => String(e.getHours()),
343
+ hh: (e) => String(e.getHours() % 12 || 12).padStart(2, "0"),
344
+ h: (e) => String(e.getHours() % 12 || 12),
345
+ mm: (e) => String(e.getMinutes()).padStart(2, "0"),
346
+ ss: (e) => String(e.getSeconds()).padStart(2, "0"),
347
+ SSS: (e) => String(e.getMilliseconds()).padStart(3, "0"),
348
+ a: (e, t) => new Intl.DateTimeFormat(t, {
349
+ hour: "numeric",
350
+ hour12: !0
351
+ }).formatToParts(e).find((e) => e.type === "dayPeriod")?.value ?? "",
352
+ Q: (e) => String(Math.ceil((e.getMonth() + 1) / 3)),
353
+ w: (e) => String(B(e)),
354
+ D: (e) => String(h(e)),
355
+ xxx: (e) => {
356
+ let t = q(e);
357
+ return `${t.sign}${t.hours}:${t.minutes}`;
358
+ },
359
+ xx: (e) => {
360
+ let t = q(e);
361
+ return `${t.sign}${t.hours}${t.minutes}`;
362
+ },
363
+ x: (e) => {
364
+ let t = q(e);
365
+ return `${t.sign}${t.hours}`;
366
+ }
367
+ }, Be = RegExp("'[^']*'|" + Object.keys(G).sort((e, t) => t.length - e.length).join("|"), "g"), Ve = [
368
+ "Sun",
369
+ "Mon",
370
+ "Tue",
371
+ "Wed",
372
+ "Thu",
373
+ "Fri",
374
+ "Sat"
375
+ ], He = [
376
+ "Jan",
377
+ "Feb",
378
+ "Mar",
379
+ "Apr",
380
+ "May",
381
+ "Jun",
382
+ "Jul",
383
+ "Aug",
384
+ "Sep",
385
+ "Oct",
386
+ "Nov",
387
+ "Dec"
388
+ ], Ue = [
389
+ "years",
390
+ "months",
391
+ "weeks",
392
+ "days",
393
+ "hours",
394
+ "minutes",
395
+ "seconds"
396
+ ], K = {
397
+ years: ["year", "years"],
398
+ months: ["month", "months"],
399
+ weeks: ["week", "weeks"],
400
+ days: ["day", "days"],
401
+ hours: ["hour", "hours"],
402
+ minutes: ["minute", "minutes"],
403
+ seconds: ["second", "seconds"]
404
+ }, We = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?$/;
405
+ //#endregion
406
+ //#region src/internals.ts
407
+ function q(e) {
408
+ let t = e.getTimezoneOffset(), n = t <= 0 ? "+" : "-", r = Math.abs(t);
409
+ return {
410
+ sign: n,
411
+ hours: String(Math.floor(r / 60)).padStart(2, "0"),
412
+ minutes: String(r % 60).padStart(2, "0")
413
+ };
414
+ }
415
+ function J(e, t) {
416
+ let n = new Date(e), r = (n.getDay() - t + 7) % 7;
417
+ return n.setDate(n.getDate() - r), n.setHours(0, 0, 0, 0), n;
418
+ }
419
+ //#endregion
420
+ //#region src/queries.ts
421
+ function Y(t, r) {
422
+ let i = e(t), a = e(r);
423
+ return !n(i) || !n(a) ? !1 : i.getFullYear() === a.getFullYear() && i.getMonth() === a.getMonth() && i.getDate() === a.getDate();
424
+ }
425
+ function X(t, r) {
426
+ let i = e(t), a = e(r);
427
+ return !n(i) || !n(a) ? !1 : i.getFullYear() === a.getFullYear() && i.getMonth() === a.getMonth();
428
+ }
429
+ function Z(t, r) {
430
+ let i = e(t), a = e(r);
431
+ return !n(i) || !n(a) ? !1 : i.getFullYear() === a.getFullYear();
432
+ }
433
+ function Ge(t, r) {
434
+ let i = e(t), a = e(r);
435
+ if (!n(i) || !n(a)) return !1;
436
+ let o = Math.ceil((i.getMonth() + 1) / 3), s = Math.ceil((a.getMonth() + 1) / 3);
437
+ return i.getFullYear() === a.getFullYear() && o === s;
438
+ }
439
+ function Q(t, r, i = 0) {
440
+ let a = e(t), o = e(r);
441
+ return !n(a) || !n(o) ? !1 : J(a, i).getTime() === J(o, i).getTime();
442
+ }
443
+ function Ke(t, r) {
444
+ let i = e(t), a = e(r);
445
+ return !n(i) || !n(a) ? !1 : i.getFullYear() === a.getFullYear() && i.getMonth() === a.getMonth() && i.getDate() === a.getDate() && i.getHours() === a.getHours();
446
+ }
447
+ function qe(t, r) {
448
+ let i = e(t), a = e(r);
449
+ return !n(i) || !n(a) ? !1 : i.getFullYear() === a.getFullYear() && i.getMonth() === a.getMonth() && i.getDate() === a.getDate() && i.getHours() === a.getHours() && i.getMinutes() === a.getMinutes();
450
+ }
451
+ function Je(t, r) {
452
+ let i = e(t), a = e(r);
453
+ return !n(i) || !n(a) ? !1 : i.getFullYear() === a.getFullYear() && i.getMonth() === a.getMonth() && i.getDate() === a.getDate() && i.getHours() === a.getHours() && i.getMinutes() === a.getMinutes() && i.getSeconds() === a.getSeconds();
454
+ }
455
+ function Ye(t, r) {
456
+ let i = e(t), a = e(r);
457
+ return !n(i) || !n(a) ? !1 : i.getHours() === a.getHours() && i.getMinutes() === a.getMinutes() && i.getSeconds() === a.getSeconds();
458
+ }
459
+ function Xe(t, r) {
460
+ let i = e(t), a = e(r);
461
+ if (!n(i) || !n(a)) return NaN;
462
+ let o = i.getTime() - a.getTime();
463
+ return o < 0 ? -1 : +(o > 0);
464
+ }
465
+ function Ze(t, r) {
466
+ let i = e(t), a = e(r);
467
+ if (!n(i) || !n(a)) return NaN;
468
+ let o = i.getTime() - a.getTime();
469
+ return o > 0 ? -1 : +(o < 0);
470
+ }
471
+ function Qe(t, r) {
472
+ let i = e(t), a = e(r);
473
+ return !n(i) || !n(a) ? !1 : i.getTime() < a.getTime();
474
+ }
475
+ function $e(t, r) {
476
+ let i = e(t), a = e(r);
477
+ return !n(i) || !n(a) ? !1 : i.getTime() > a.getTime();
478
+ }
479
+ function et(t, r) {
480
+ let i = e(t), a = e(r);
481
+ return !n(i) || !n(a) ? !1 : i.getTime() === a.getTime();
482
+ }
483
+ function tt(t, r, i) {
484
+ let a = e(t), o = e(r), s = e(i);
485
+ return !n(a) || !n(o) || !n(s) ? !1 : (o.getTime() > s.getTime() && ([o, s] = [s, o]), a.getTime() >= o.getTime() && a.getTime() <= s.getTime());
486
+ }
487
+ function nt(e, t) {
488
+ return !n(e.start) || !n(e.end) || !n(t.start) || !n(t.end) ? !1 : e.start.getTime() < t.end.getTime() && e.end.getTime() > t.start.getTime();
489
+ }
490
+ function rt(e) {
491
+ return Y(e, /* @__PURE__ */ new Date());
492
+ }
493
+ function it(e) {
494
+ let t = /* @__PURE__ */ new Date();
495
+ return t.setDate(t.getDate() - 1), Y(e, t);
496
+ }
497
+ function at(e) {
498
+ let t = /* @__PURE__ */ new Date();
499
+ return t.setDate(t.getDate() + 1), Y(e, t);
500
+ }
501
+ function ot(t) {
502
+ let r = e(t);
503
+ return n(r) ? r.getTime() < Date.now() : !1;
504
+ }
505
+ function st(t) {
506
+ let r = e(t);
507
+ return n(r) ? r.getTime() > Date.now() : !1;
508
+ }
509
+ function ct(e, t = 0) {
510
+ return Q(e, /* @__PURE__ */ new Date(), t);
511
+ }
512
+ function lt(e) {
513
+ return X(e, /* @__PURE__ */ new Date());
514
+ }
515
+ function ut(e) {
516
+ return Z(e, /* @__PURE__ */ new Date());
517
+ }
518
+ function dt(t) {
519
+ let r = e(t);
520
+ return n(r) ? r.getDate() === 1 : !1;
521
+ }
522
+ function ft(t) {
523
+ let r = e(t);
524
+ if (!n(r)) return !1;
525
+ let i = new Date(r);
526
+ return i.setDate(i.getDate() + 1), i.getMonth() !== r.getMonth();
527
+ }
528
+ function pt(t) {
529
+ let r = e(t);
530
+ if (!n(r)) return !1;
531
+ let i = r.getDay();
532
+ return i === 0 || i === 6;
533
+ }
534
+ function mt(t) {
535
+ let r = e(t);
536
+ if (!n(r)) return !1;
537
+ let i = r.getDay();
538
+ return i >= 1 && i <= 5;
539
+ }
540
+ function ht(t) {
541
+ let r = e(t);
542
+ return n(r) ? r.getHours() < 12 : !1;
543
+ }
544
+ function gt(t) {
545
+ let r = e(t);
546
+ return n(r) ? r.getHours() >= 12 : !1;
547
+ }
548
+ function $(e) {
549
+ let t;
550
+ if (e instanceof Date) {
551
+ if (!n(e)) return !1;
552
+ t = e.getFullYear();
553
+ } else t = e;
554
+ return t % 4 == 0 && t % 100 != 0 || t % 400 == 0;
555
+ }
556
+ function _t(t) {
557
+ let r = e(t);
558
+ return n(r) ? $(r.getFullYear()) : !1;
559
+ }
560
+ //#endregion
561
+ //#region src/format.ts
562
+ function vt(t, r, i) {
563
+ let a = e(t);
564
+ if (!n(a)) return "Invalid Date";
565
+ let o = i?.locale ?? "default";
566
+ return r.replace(Be, (e) => {
567
+ if (e.startsWith("'")) {
568
+ let t = e.slice(1, -1);
569
+ return t === "" ? "'" : t;
570
+ }
571
+ let t = G[e];
572
+ return t(a, o);
573
+ });
574
+ }
575
+ function yt(t, r = "default", i = {}) {
576
+ let a = e(t);
577
+ return n(a) ? new Intl.DateTimeFormat(r, i).format(a) : "Invalid Date";
578
+ }
579
+ function bt(t, r = /* @__PURE__ */ new Date(), i = "default") {
580
+ let a = e(t), o = e(r);
581
+ if (!n(a) || !n(o)) return "Invalid Date";
582
+ let s = new Intl.RelativeTimeFormat(i, { numeric: "auto" }), c = Math.abs.bind(Math), l = P(a, o), u = F(a, o), d = I(a, o), f = L(a, o), p = Math.trunc(f / 7), m = Math.round(f / 30.4375), h = Math.round(f / 365.25);
583
+ return c(l) < 60 ? s.format(l, "second") : c(u) < 60 ? s.format(u, "minute") : c(d) < 24 ? s.format(d, "hour") : c(f) < 7 ? s.format(f, "day") : c(p) < 4 ? s.format(p, "week") : c(m) < 12 ? s.format(m, "month") : s.format(h, "year");
584
+ }
585
+ function xt(t, r) {
586
+ let i = e(t);
587
+ if (!n(i)) return "Invalid Date";
588
+ let a = r?.format ?? "extended", o = r?.representation ?? "complete", s = a === "extended" ? "-" : "", c = a === "extended" ? ":" : "", l = String(i.getFullYear()).padStart(4, "0"), u = String(i.getMonth() + 1).padStart(2, "0"), d = String(i.getDate()).padStart(2, "0"), f = String(i.getHours()).padStart(2, "0"), p = String(i.getMinutes()).padStart(2, "0"), m = String(i.getSeconds()).padStart(2, "0"), h = q(i), g = `${h.sign}${h.hours}${c}${h.minutes}`, _ = `${l}${s}${u}${s}${d}`, v = `${f}${c}${p}${c}${m}`;
589
+ return o === "date" ? _ : o === "time" ? `${v}${g}` : `${_}T${v}${g}`;
590
+ }
591
+ function St(t, r) {
592
+ let i = e(t);
593
+ if (!n(i)) return "Invalid Date";
594
+ let a = r?.fractionDigits ?? 0;
595
+ return `${String(i.getFullYear()).padStart(4, "0")}-${String(i.getMonth() + 1).padStart(2, "0")}-${String(i.getDate()).padStart(2, "0")}T${String(i.getHours()).padStart(2, "0")}:${String(i.getMinutes()).padStart(2, "0")}:${String(i.getSeconds()).padStart(2, "0")}${a > 0 ? "." + String(i.getMilliseconds()).padStart(3, "0").slice(0, a) : ""}${i.getTimezoneOffset() === 0 ? "Z" : (() => {
596
+ let e = q(i);
597
+ return `${e.sign}${e.hours}:${e.minutes}`;
598
+ })()}`;
599
+ }
600
+ function Ct(t, r) {
601
+ let i = e(t);
602
+ if (!n(i)) return "Invalid Date";
603
+ let a = r?.representation ?? "complete", o = String(i.getFullYear()).padStart(4, "0"), s = String(i.getMonth() + 1).padStart(2, "0"), c = String(i.getDate()).padStart(2, "0"), l = String(i.getHours()).padStart(2, "0"), u = String(i.getMinutes()).padStart(2, "0"), d = String(i.getSeconds()).padStart(2, "0");
604
+ return a === "date" ? `${o}-${s}-${c}` : a === "time" ? `${l}:${u}:${d}` : `${o}-${s}-${c} ${l}:${u}:${d}`;
605
+ }
606
+ function wt(t) {
607
+ let r = e(t);
608
+ if (!n(r)) return "Invalid Date";
609
+ let i = Ve[r.getDay()], a = String(r.getDate()).padStart(2, "0"), o = He[r.getMonth()], s = r.getFullYear(), c = String(r.getHours()).padStart(2, "0"), l = String(r.getMinutes()).padStart(2, "0"), u = String(r.getSeconds()).padStart(2, "0"), d = q(r);
610
+ return `${i}, ${a} ${o} ${s} ${c}:${l}:${u} ${d.sign}${d.hours}${d.minutes}`;
611
+ }
612
+ function Tt(e, t) {
613
+ let n = t?.zero ?? !1, r = t?.delimiter ?? ", ", i = t?.locale ?? "default", a = t?.format ?? Ue, o = new Intl.PluralRules(i), s = new Intl.NumberFormat(i), c = [];
614
+ for (let t of a) {
615
+ let r = e[t] ?? 0;
616
+ if (r === 0 && !n) continue;
617
+ let [i, a] = K[t], l = o.select(r) === "one" ? i : a;
618
+ c.push(`${s.format(r)} ${l}`);
619
+ }
620
+ return c.join(r);
621
+ }
622
+ function Et(t) {
623
+ let r = e(t);
624
+ return n(r) ? r.toISOString() : "Invalid Date";
625
+ }
626
+ function Dt(e) {
627
+ return We.test(e.trim()) ? new Date(e) : /* @__PURE__ */ new Date(NaN);
628
+ }
629
+ //#endregion
630
+ export { xe as addBusinessDays, b as addDays, y as addHours, g as addMilliseconds, v as addMinutes, S as addMonths, _ as addSeconds, x as addWeeks, C as addYears, Ce as clampDate, Ee as closestTo, Xe as compareAsc, Ze as compareDesc, r as createDate, Se as differenceInBusinessDays, L as differenceInDays, I as differenceInHours, N as differenceInMilliseconds, F as differenceInMinutes, R as differenceInMonths, P as differenceInSeconds, be as differenceInWeeks, z as differenceInYears, Re as durationToMilliseconds, ke as eachDayOfInterval, Oe as eachHourOfInterval, De as eachMinuteOfInterval, je as eachMonthOfInterval, Ae as eachWeekOfInterval, Me as eachYearOfInterval, pe as endOfDay, me as endOfHour, he as endOfMinute, _e as endOfMonth, ye as endOfQuarter, ge as endOfWeek, M as endOfYear, vt as format, yt as formatDate, Tt as formatDuration, xt as formatISO, Ct as formatISO9075, wt as formatRFC2822, St as formatRFC3339, bt as formatRelativeTime, Ne as fromUnixTime, o as getDate, f as getDayOfWeek, h as getDayOfYear, p as getDaysInMonth, s as getHours, B as getISOWeek, u as getMilliseconds, c as getMinutes, a as getMonth, ze as getOverlappingDaysInInterval, m as getQuarter, l as getSeconds, d as getTimestamp, i as getYear, Le as intervalToDuration, ht as isAM, $e as isAfter, Qe as isBefore, t as isDate, et as isEqual, dt as isFirstDayOfMonth, st as isFuture, _t as isInLeapYear, ft as isLastDayOfMonth, $ as isLeapYear, nt as isOverlapping, gt as isPM, ot as isPast, Y as isSameDay, Ke as isSameHour, qe as isSameMinute, X as isSameMonth, Ge as isSameQuarter, Je as isSameSecond, Ye as isSameTime, Q as isSameWeek, Z as isSameYear, lt as isThisMonth, ct as isThisWeek, ut as isThisYear, rt as isToday, at as isTomorrow, n as isValid, mt as isWeekday, pt as isWeekend, tt as isWithinRange, it as isYesterday, Te as max, we as min, Dt as parseISO, Fe as roundToNearestMinutes, ce as setDate, le as setHours, Ie as setISOWeek, fe as setMilliseconds, ue as setMinutes, T as setMonth, de as setSeconds, se as setYear, E as startOfDay, D as startOfHour, O as startOfMinute, A as startOfMonth, ve as startOfQuarter, k as startOfWeek, j as startOfYear, re as subDays, ne as subHours, w as subMilliseconds, te as subMinutes, ae as subMonths, ee as subSeconds, ie as subWeeks, oe as subYears, e as toDate, Et as toISOString, Pe as toUnixTime };
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@himanshu-sorathiya/datetime",
3
+ "version": "1.0.1",
4
+ "description": "A strictly client-side, fully type-safe, zero-dependency toolkit for parsing, querying, manipulating, and formatting dates in TypeScript. Every function is a pure, immutable transformation — no wrapper classes, no prototype patching, no hidden global state.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "scripts": {
20
+ "dev": "vite",
21
+ "build": "tsc -b && vite build",
22
+ "lint": "eslint .",
23
+ "preview": "vite preview",
24
+ "format": "prettier . --write"
25
+ },
26
+ "devDependencies": {
27
+ "@microsoft/api-extractor": "^7.58.12",
28
+ "@types/node": "^26.1.1",
29
+ "prettier": "^3.9.6",
30
+ "typescript": "~6.0.2",
31
+ "vite": "^8.1.1",
32
+ "vite-plugin-dts": "^5.0.3"
33
+ }
34
+ }