svelte-date-utils 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018–2026 Wojciech Maj
4
+ Copyright (c) 2026 Adhi Ravishankar
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+
24
+
25
+ The adapters in src/AdapterDateFns.ts and src/AdapterLuxon.ts are adapted from the
26
+ adapters in @mui/x-date-pickers (MIT, Copyright (c) 2020 MUI Team), which are based on
27
+ @date-io (MIT, Copyright (c) 2017 Dmitriy Kovalenko). The function names and behavior in
28
+ src/createDateUtils.ts follow @wojtekmaj/date-utils (MIT, Copyright (c) Wojciech Maj).
@@ -0,0 +1,61 @@
1
+ import type { DateAdapter } from './types.js';
2
+ export interface AdapterDateOptions {
3
+ /** First day of the week, 0 (Sunday) to 6 (Saturday). Defaults to 0. */
4
+ weekStartsOn?: number;
5
+ }
6
+ /** Adapter for the native `Date`, with no dependency. The default adapter of the package. */
7
+ export declare class AdapterDate implements DateAdapter<Date> {
8
+ readonly lib = "native";
9
+ private readonly weekStartsOn;
10
+ constructor({ weekStartsOn }?: AdapterDateOptions);
11
+ date: (value?: string) => Date;
12
+ getInvalidDate: () => Date;
13
+ isValid: (value: Date | null | undefined) => value is Date;
14
+ toJsDate: (value: Date) => Date;
15
+ formatByString: (value: Date, format: string) => string;
16
+ /** Parses the numeric tokens `yyyy MM dd HH mm ss`. Use another adapter for locale formats. */
17
+ parse: (value: string, format: string) => Date | null;
18
+ isEqual: (value: Date | null, comparing: Date | null) => boolean;
19
+ isSameYear: (value: Date, comparing: Date) => boolean;
20
+ isSameMonth: (value: Date, comparing: Date) => boolean;
21
+ isSameDay: (value: Date, comparing: Date) => boolean;
22
+ isAfter: (value: Date, comparing: Date) => boolean;
23
+ isBefore: (value: Date, comparing: Date) => boolean;
24
+ isWithinRange: (value: Date, [start, end]: [Date, Date]) => boolean;
25
+ startOfYear: (value: Date) => Date;
26
+ startOfMonth: (value: Date) => Date;
27
+ startOfWeek: (value: Date) => Date;
28
+ startOfDay: (value: Date) => Date;
29
+ endOfYear: (value: Date) => Date;
30
+ endOfMonth: (value: Date) => Date;
31
+ endOfWeek: (value: Date) => Date;
32
+ endOfDay: (value: Date) => Date;
33
+ addYears: (value: Date, amount: number) => Date;
34
+ /** Clamps to the last day of the target month, like date-fns and Luxon: Jan 31 + 1 month is Feb 28. */
35
+ addMonths: (value: Date, amount: number) => Date;
36
+ addWeeks: (value: Date, amount: number) => Date;
37
+ addDays: (value: Date, amount: number) => Date;
38
+ addHours: (value: Date, amount: number) => Date;
39
+ addMinutes: (value: Date, amount: number) => Date;
40
+ addSeconds: (value: Date, amount: number) => Date;
41
+ getYear: (value: Date) => number;
42
+ getMonth: (value: Date) => number;
43
+ getDate: (value: Date) => number;
44
+ getHours: (value: Date) => number;
45
+ getMinutes: (value: Date) => number;
46
+ getSeconds: (value: Date) => number;
47
+ getMilliseconds: (value: Date) => number;
48
+ /** Clamps the day when the target month is shorter (Feb 29 to a common year is Feb 28). */
49
+ setYear: (value: Date, year: number) => Date;
50
+ setMonth: (value: Date, month: number) => Date;
51
+ setDate: (value: Date, date: number) => Date;
52
+ setHours: (value: Date, hours: number) => Date;
53
+ setMinutes: (value: Date, minutes: number) => Date;
54
+ setSeconds: (value: Date, seconds: number) => Date;
55
+ setMilliseconds: (value: Date, milliseconds: number) => Date;
56
+ getDaysInMonth: (value: Date) => number;
57
+ getWeekArray: (value: Date) => Date[][];
58
+ /** Week of the year, where week 1 holds January 1 (the date-fns default for `getWeek`). */
59
+ getWeekNumber: (value: Date) => number;
60
+ getDayOfWeek: (value: Date) => number;
61
+ }
@@ -0,0 +1,176 @@
1
+ const copy = (value) => new Date(value.getTime());
2
+ /** Adapter for the native `Date`, with no dependency. The default adapter of the package. */
3
+ export class AdapterDate {
4
+ lib = 'native';
5
+ weekStartsOn;
6
+ constructor({ weekStartsOn = 0 } = {}) {
7
+ this.weekStartsOn = weekStartsOn;
8
+ }
9
+ date = (value) => (value === undefined ? new Date() : new Date(value));
10
+ getInvalidDate = () => new Date('Invalid Date');
11
+ isValid = (value) => value instanceof Date && !Number.isNaN(value.getTime());
12
+ toJsDate = (value) => value;
13
+ formatByString = (value, format) => {
14
+ const pad = (n, length = 2) => String(n).padStart(length, '0');
15
+ const tokens = {
16
+ yyyy: pad(value.getFullYear(), 4),
17
+ MM: pad(value.getMonth() + 1),
18
+ dd: pad(value.getDate()),
19
+ HH: pad(value.getHours()),
20
+ mm: pad(value.getMinutes()),
21
+ ss: pad(value.getSeconds()),
22
+ SSS: pad(value.getMilliseconds(), 3),
23
+ };
24
+ return format.replace(/yyyy|MM|dd|HH|mm|ss|SSS/g, (token) => tokens[token] ?? token);
25
+ };
26
+ /** Parses the numeric tokens `yyyy MM dd HH mm ss`. Use another adapter for locale formats. */
27
+ parse = (value, format) => {
28
+ if (value === '')
29
+ return null;
30
+ const order = [];
31
+ const source = format
32
+ .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
33
+ .replace(/yyyy|MM|dd|HH|mm|ss/g, (token) => {
34
+ order.push(token);
35
+ return `(\\d{${token.length}})`;
36
+ });
37
+ const match = new RegExp(`^${source}$`).exec(value);
38
+ if (!match)
39
+ return this.getInvalidDate();
40
+ const part = (token, fallback) => {
41
+ const index = order.indexOf(token);
42
+ return index === -1 ? fallback : Number(match[index + 1]);
43
+ };
44
+ const result = new Date(part('yyyy', 1970), part('MM', 1) - 1, part('dd', 1), part('HH', 0), part('mm', 0), part('ss', 0));
45
+ // new Date(99, ...) means 1999: keep the year as written
46
+ result.setFullYear(part('yyyy', 1970));
47
+ return result;
48
+ };
49
+ isEqual = (value, comparing) => value === null || comparing === null ? value === comparing : +value === +comparing;
50
+ isSameYear = (value, comparing) => value.getFullYear() === comparing.getFullYear();
51
+ isSameMonth = (value, comparing) => this.isSameYear(value, comparing) && value.getMonth() === comparing.getMonth();
52
+ isSameDay = (value, comparing) => this.isSameMonth(value, comparing) && value.getDate() === comparing.getDate();
53
+ isAfter = (value, comparing) => value > comparing;
54
+ isBefore = (value, comparing) => value < comparing;
55
+ isWithinRange = (value, [start, end]) => value >= start && value <= end;
56
+ startOfYear = (value) => {
57
+ const result = new Date(0);
58
+ result.setFullYear(value.getFullYear(), 0, 1);
59
+ result.setHours(0, 0, 0, 0);
60
+ return result;
61
+ };
62
+ startOfMonth = (value) => this.startOfDay(this.setDate(value, 1));
63
+ startOfWeek = (value) => {
64
+ const diff = (value.getDay() - this.weekStartsOn + 7) % 7;
65
+ return this.startOfDay(this.addDays(value, -diff));
66
+ };
67
+ startOfDay = (value) => {
68
+ const result = copy(value);
69
+ result.setHours(0, 0, 0, 0);
70
+ return result;
71
+ };
72
+ endOfYear = (value) => {
73
+ const result = copy(value);
74
+ result.setMonth(11, 31);
75
+ result.setHours(23, 59, 59, 999);
76
+ return result;
77
+ };
78
+ endOfMonth = (value) => {
79
+ const result = this.setDate(value, this.getDaysInMonth(value));
80
+ result.setHours(23, 59, 59, 999);
81
+ return result;
82
+ };
83
+ endOfWeek = (value) => this.endOfDay(this.addDays(this.startOfWeek(value), 6));
84
+ endOfDay = (value) => {
85
+ const result = copy(value);
86
+ result.setHours(23, 59, 59, 999);
87
+ return result;
88
+ };
89
+ addYears = (value, amount) => this.addMonths(value, amount * 12);
90
+ /** Clamps to the last day of the target month, like date-fns and Luxon: Jan 31 + 1 month is Feb 28. */
91
+ addMonths = (value, amount) => {
92
+ const result = copy(value);
93
+ result.setDate(1);
94
+ result.setMonth(result.getMonth() + amount);
95
+ result.setDate(Math.min(value.getDate(), this.getDaysInMonth(result)));
96
+ return result;
97
+ };
98
+ addWeeks = (value, amount) => this.addDays(value, amount * 7);
99
+ addDays = (value, amount) => {
100
+ const result = copy(value);
101
+ result.setDate(result.getDate() + amount);
102
+ return result;
103
+ };
104
+ addHours = (value, amount) => new Date(value.getTime() + amount * 3_600_000);
105
+ addMinutes = (value, amount) => new Date(value.getTime() + amount * 60_000);
106
+ addSeconds = (value, amount) => new Date(value.getTime() + amount * 1000);
107
+ getYear = (value) => value.getFullYear();
108
+ getMonth = (value) => value.getMonth();
109
+ getDate = (value) => value.getDate();
110
+ getHours = (value) => value.getHours();
111
+ getMinutes = (value) => value.getMinutes();
112
+ getSeconds = (value) => value.getSeconds();
113
+ getMilliseconds = (value) => value.getMilliseconds();
114
+ /** Clamps the day when the target month is shorter (Feb 29 to a common year is Feb 28). */
115
+ setYear = (value, year) => {
116
+ const result = copy(value);
117
+ result.setFullYear(year, value.getMonth(), 1);
118
+ result.setDate(Math.min(value.getDate(), this.getDaysInMonth(result)));
119
+ return result;
120
+ };
121
+ setMonth = (value, month) => {
122
+ const result = copy(value);
123
+ result.setMonth(month, 1);
124
+ result.setDate(Math.min(value.getDate(), this.getDaysInMonth(result)));
125
+ return result;
126
+ };
127
+ setDate = (value, date) => {
128
+ const result = copy(value);
129
+ result.setDate(date);
130
+ return result;
131
+ };
132
+ setHours = (value, hours) => {
133
+ const result = copy(value);
134
+ result.setHours(hours);
135
+ return result;
136
+ };
137
+ setMinutes = (value, minutes) => {
138
+ const result = copy(value);
139
+ result.setMinutes(minutes);
140
+ return result;
141
+ };
142
+ setSeconds = (value, seconds) => {
143
+ const result = copy(value);
144
+ result.setSeconds(seconds);
145
+ return result;
146
+ };
147
+ setMilliseconds = (value, milliseconds) => {
148
+ const result = copy(value);
149
+ result.setMilliseconds(milliseconds);
150
+ return result;
151
+ };
152
+ getDaysInMonth = (value) => new Date(value.getFullYear(), value.getMonth() + 1, 0).getDate();
153
+ getWeekArray = (value) => {
154
+ const start = this.startOfWeek(this.startOfMonth(value));
155
+ const end = this.endOfWeek(this.endOfMonth(value));
156
+ const weeks = [];
157
+ let current = start;
158
+ for (let count = 0; current < end; count += 1) {
159
+ const week = (weeks[Math.floor(count / 7)] ??= []);
160
+ week.push(current);
161
+ current = this.addDays(current, 1);
162
+ }
163
+ return weeks;
164
+ };
165
+ /** Week of the year, where week 1 holds January 1 (the date-fns default for `getWeek`). */
166
+ getWeekNumber = (value) => {
167
+ const yearStart = this.startOfWeek(this.startOfYear(value));
168
+ const weekStart = this.startOfWeek(value);
169
+ const nextYearStart = this.startOfWeek(this.startOfYear(this.addYears(value, 1)));
170
+ // the last days of December can belong to week 1 of the next year
171
+ if (weekStart >= nextYearStart)
172
+ return 1;
173
+ return Math.round((weekStart.getTime() - yearStart.getTime()) / (7 * 86_400_000)) + 1;
174
+ };
175
+ getDayOfWeek = (value) => ((value.getDay() - this.weekStartsOn + 7) % 7) + 1;
176
+ }
@@ -0,0 +1,58 @@
1
+ import type { Locale } from 'date-fns/locale';
2
+ import type { DateAdapter } from './types.js';
3
+ export interface AdapterDateFnsOptions {
4
+ /** A date-fns locale, for example `import { de } from 'date-fns/locale/de'`. Defaults to en-US. */
5
+ locale?: Locale;
6
+ }
7
+ /** Adapter for date-fns v3 and v4. Values are native `Date` objects. */
8
+ export declare class AdapterDateFns implements DateAdapter<Date> {
9
+ readonly lib = "date-fns";
10
+ readonly locale: Locale;
11
+ constructor({ locale }?: AdapterDateFnsOptions);
12
+ date: (value?: string) => Date;
13
+ getInvalidDate: () => Date;
14
+ isValid: (value: Date | null | undefined) => value is Date;
15
+ toJsDate: (value: Date) => Date;
16
+ formatByString: (value: Date, formatString: string) => string;
17
+ parse: (value: string, formatString: string) => Date | null;
18
+ isEqual: (value: Date | null, comparing: Date | null) => boolean;
19
+ isSameYear: (value: Date, comparing: Date) => boolean;
20
+ isSameMonth: (value: Date, comparing: Date) => boolean;
21
+ isSameDay: (value: Date, comparing: Date) => boolean;
22
+ isAfter: (value: Date, comparing: Date) => boolean;
23
+ isBefore: (value: Date, comparing: Date) => boolean;
24
+ isWithinRange: (value: Date, [start, end]: [Date, Date]) => boolean;
25
+ startOfYear: (value: Date) => Date;
26
+ startOfMonth: (value: Date) => Date;
27
+ startOfWeek: (value: Date) => Date;
28
+ startOfDay: (value: Date) => Date;
29
+ endOfYear: (value: Date) => Date;
30
+ endOfMonth: (value: Date) => Date;
31
+ endOfWeek: (value: Date) => Date;
32
+ endOfDay: (value: Date) => Date;
33
+ addYears: (value: Date, amount: number) => Date;
34
+ addMonths: (value: Date, amount: number) => Date;
35
+ addWeeks: (value: Date, amount: number) => Date;
36
+ addDays: (value: Date, amount: number) => Date;
37
+ addHours: (value: Date, amount: number) => Date;
38
+ addMinutes: (value: Date, amount: number) => Date;
39
+ addSeconds: (value: Date, amount: number) => Date;
40
+ getYear: (value: Date) => number;
41
+ getMonth: (value: Date) => number;
42
+ getDate: (value: Date) => number;
43
+ getHours: (value: Date) => number;
44
+ getMinutes: (value: Date) => number;
45
+ getSeconds: (value: Date) => number;
46
+ getMilliseconds: (value: Date) => number;
47
+ setYear: (value: Date, year: number) => Date;
48
+ setMonth: (value: Date, month: number) => Date;
49
+ setDate: (value: Date, date: number) => Date;
50
+ setHours: (value: Date, hours: number) => Date;
51
+ setMinutes: (value: Date, minutes: number) => Date;
52
+ setSeconds: (value: Date, seconds: number) => Date;
53
+ setMilliseconds: (value: Date, milliseconds: number) => Date;
54
+ getDaysInMonth: (value: Date) => number;
55
+ getWeekArray: (value: Date) => Date[][];
56
+ getWeekNumber: (value: Date) => number;
57
+ getDayOfWeek: (value: Date) => number;
58
+ }
@@ -0,0 +1,110 @@
1
+ // Adapted from AdapterDateFns in @mui/x-date-pickers, which is based on @date-io/date-fns.
2
+ // MIT License, Copyright (c) 2017 Dmitriy Kovalenko. See LICENSE.
3
+ import { addDays } from 'date-fns/addDays';
4
+ import { addHours } from 'date-fns/addHours';
5
+ import { addMinutes } from 'date-fns/addMinutes';
6
+ import { addMonths } from 'date-fns/addMonths';
7
+ import { addSeconds } from 'date-fns/addSeconds';
8
+ import { addWeeks } from 'date-fns/addWeeks';
9
+ import { addYears } from 'date-fns/addYears';
10
+ import { endOfDay } from 'date-fns/endOfDay';
11
+ import { endOfMonth } from 'date-fns/endOfMonth';
12
+ import { endOfWeek } from 'date-fns/endOfWeek';
13
+ import { endOfYear } from 'date-fns/endOfYear';
14
+ import { format } from 'date-fns/format';
15
+ import { getDate } from 'date-fns/getDate';
16
+ import { getDay } from 'date-fns/getDay';
17
+ import { getDaysInMonth } from 'date-fns/getDaysInMonth';
18
+ import { getHours } from 'date-fns/getHours';
19
+ import { getMilliseconds } from 'date-fns/getMilliseconds';
20
+ import { getMinutes } from 'date-fns/getMinutes';
21
+ import { getMonth } from 'date-fns/getMonth';
22
+ import { getSeconds } from 'date-fns/getSeconds';
23
+ import { getWeek } from 'date-fns/getWeek';
24
+ import { getYear } from 'date-fns/getYear';
25
+ import { isAfter } from 'date-fns/isAfter';
26
+ import { isBefore } from 'date-fns/isBefore';
27
+ import { isEqual } from 'date-fns/isEqual';
28
+ import { isSameDay } from 'date-fns/isSameDay';
29
+ import { isSameMonth } from 'date-fns/isSameMonth';
30
+ import { isSameYear } from 'date-fns/isSameYear';
31
+ import { isValid } from 'date-fns/isValid';
32
+ import { isWithinInterval } from 'date-fns/isWithinInterval';
33
+ import { enUS } from 'date-fns/locale/en-US';
34
+ import { parse } from 'date-fns/parse';
35
+ import { setDate } from 'date-fns/setDate';
36
+ import { setHours } from 'date-fns/setHours';
37
+ import { setMilliseconds } from 'date-fns/setMilliseconds';
38
+ import { setMinutes } from 'date-fns/setMinutes';
39
+ import { setMonth } from 'date-fns/setMonth';
40
+ import { setSeconds } from 'date-fns/setSeconds';
41
+ import { setYear } from 'date-fns/setYear';
42
+ import { startOfDay } from 'date-fns/startOfDay';
43
+ import { startOfMonth } from 'date-fns/startOfMonth';
44
+ import { startOfWeek } from 'date-fns/startOfWeek';
45
+ import { startOfYear } from 'date-fns/startOfYear';
46
+ /** Adapter for date-fns v3 and v4. Values are native `Date` objects. */
47
+ export class AdapterDateFns {
48
+ lib = 'date-fns';
49
+ locale;
50
+ constructor({ locale } = {}) {
51
+ this.locale = locale ?? enUS;
52
+ }
53
+ date = (value) => (value === undefined ? new Date() : new Date(value));
54
+ getInvalidDate = () => new Date('Invalid Date');
55
+ isValid = (value) => value != null && isValid(value);
56
+ toJsDate = (value) => value;
57
+ formatByString = (value, formatString) => format(value, formatString, { locale: this.locale });
58
+ parse = (value, formatString) => value === '' ? null : parse(value, formatString, new Date(), { locale: this.locale });
59
+ isEqual = (value, comparing) => value === null || comparing === null ? value === comparing : isEqual(value, comparing);
60
+ isSameYear = (value, comparing) => isSameYear(value, comparing);
61
+ isSameMonth = (value, comparing) => isSameMonth(value, comparing);
62
+ isSameDay = (value, comparing) => isSameDay(value, comparing);
63
+ isAfter = (value, comparing) => isAfter(value, comparing);
64
+ isBefore = (value, comparing) => isBefore(value, comparing);
65
+ isWithinRange = (value, [start, end]) => isWithinInterval(value, { start, end });
66
+ startOfYear = (value) => startOfYear(value);
67
+ startOfMonth = (value) => startOfMonth(value);
68
+ startOfWeek = (value) => startOfWeek(value, { locale: this.locale });
69
+ startOfDay = (value) => startOfDay(value);
70
+ endOfYear = (value) => endOfYear(value);
71
+ endOfMonth = (value) => endOfMonth(value);
72
+ endOfWeek = (value) => endOfWeek(value, { locale: this.locale });
73
+ endOfDay = (value) => endOfDay(value);
74
+ addYears = (value, amount) => addYears(value, amount);
75
+ addMonths = (value, amount) => addMonths(value, amount);
76
+ addWeeks = (value, amount) => addWeeks(value, amount);
77
+ addDays = (value, amount) => addDays(value, amount);
78
+ addHours = (value, amount) => addHours(value, amount);
79
+ addMinutes = (value, amount) => addMinutes(value, amount);
80
+ addSeconds = (value, amount) => addSeconds(value, amount);
81
+ getYear = (value) => getYear(value);
82
+ getMonth = (value) => getMonth(value);
83
+ getDate = (value) => getDate(value);
84
+ getHours = (value) => getHours(value);
85
+ getMinutes = (value) => getMinutes(value);
86
+ getSeconds = (value) => getSeconds(value);
87
+ getMilliseconds = (value) => getMilliseconds(value);
88
+ setYear = (value, year) => setYear(value, year);
89
+ setMonth = (value, month) => setMonth(value, month);
90
+ setDate = (value, date) => setDate(value, date);
91
+ setHours = (value, hours) => setHours(value, hours);
92
+ setMinutes = (value, minutes) => setMinutes(value, minutes);
93
+ setSeconds = (value, seconds) => setSeconds(value, seconds);
94
+ setMilliseconds = (value, milliseconds) => setMilliseconds(value, milliseconds);
95
+ getDaysInMonth = (value) => getDaysInMonth(value);
96
+ getWeekArray = (value) => {
97
+ const start = this.startOfWeek(this.startOfMonth(value));
98
+ const end = this.endOfWeek(this.endOfMonth(value));
99
+ const weeks = [];
100
+ let current = start;
101
+ for (let count = 0; this.isBefore(current, end); count += 1) {
102
+ const week = (weeks[Math.floor(count / 7)] ??= []);
103
+ week.push(current);
104
+ current = this.addDays(current, 1);
105
+ }
106
+ return weeks;
107
+ };
108
+ getWeekNumber = (value) => getWeek(value, { locale: this.locale });
109
+ getDayOfWeek = (value) => ((getDay(value) - (this.locale.options?.weekStartsOn ?? 0) + 7) % 7) + 1;
110
+ }
@@ -0,0 +1,59 @@
1
+ import { DateTime } from 'luxon';
2
+ import type { DateAdapter } from './types.js';
3
+ export interface AdapterLuxonOptions {
4
+ /** A locale such as `de` or `en-GB`. Defaults to `en-US`. */
5
+ locale?: string;
6
+ }
7
+ /** Adapter for Luxon v3. Values are `DateTime` objects, in the zone they were created in. */
8
+ export declare class AdapterLuxon implements DateAdapter<DateTime> {
9
+ readonly lib = "luxon";
10
+ readonly locale: string;
11
+ constructor({ locale }?: AdapterLuxonOptions);
12
+ private withLocale;
13
+ date: (value?: string) => DateTime<true> | DateTime<false>;
14
+ getInvalidDate: () => DateTime<true> | DateTime<false>;
15
+ isValid: (value: DateTime | null | undefined) => value is DateTime;
16
+ toJsDate: (value: DateTime) => Date;
17
+ formatByString: (value: DateTime, format: string) => string;
18
+ parse: (value: string, format: string) => DateTime<true> | DateTime<false> | null;
19
+ isEqual: (value: DateTime | null, comparing: DateTime | null) => boolean;
20
+ isSameYear: (value: DateTime, comparing: DateTime) => boolean;
21
+ isSameMonth: (value: DateTime, comparing: DateTime) => boolean;
22
+ isSameDay: (value: DateTime, comparing: DateTime) => boolean;
23
+ isAfter: (value: DateTime, comparing: DateTime) => boolean;
24
+ isBefore: (value: DateTime, comparing: DateTime) => boolean;
25
+ isWithinRange: (value: DateTime, [start, end]: [DateTime, DateTime]) => boolean;
26
+ startOfYear: (value: DateTime) => DateTime<boolean>;
27
+ startOfMonth: (value: DateTime) => DateTime<boolean>;
28
+ startOfWeek: (value: DateTime) => DateTime<boolean>;
29
+ startOfDay: (value: DateTime) => DateTime<boolean>;
30
+ endOfYear: (value: DateTime) => DateTime<boolean>;
31
+ endOfMonth: (value: DateTime) => DateTime<boolean>;
32
+ endOfWeek: (value: DateTime) => DateTime<boolean>;
33
+ endOfDay: (value: DateTime) => DateTime<boolean>;
34
+ addYears: (value: DateTime, amount: number) => DateTime<boolean>;
35
+ addMonths: (value: DateTime, amount: number) => DateTime<boolean>;
36
+ addWeeks: (value: DateTime, amount: number) => DateTime<boolean>;
37
+ addDays: (value: DateTime, amount: number) => DateTime<boolean>;
38
+ addHours: (value: DateTime, amount: number) => DateTime<boolean>;
39
+ addMinutes: (value: DateTime, amount: number) => DateTime<boolean>;
40
+ addSeconds: (value: DateTime, amount: number) => DateTime<boolean>;
41
+ getYear: (value: DateTime) => number;
42
+ getMonth: (value: DateTime) => number;
43
+ getDate: (value: DateTime) => number;
44
+ getHours: (value: DateTime) => number;
45
+ getMinutes: (value: DateTime) => number;
46
+ getSeconds: (value: DateTime) => number;
47
+ getMilliseconds: (value: DateTime) => number;
48
+ setYear: (value: DateTime, year: number) => DateTime<boolean>;
49
+ setMonth: (value: DateTime, month: number) => DateTime<boolean>;
50
+ setDate: (value: DateTime, date: number) => DateTime<boolean>;
51
+ setHours: (value: DateTime, hour: number) => DateTime<boolean>;
52
+ setMinutes: (value: DateTime, minute: number) => DateTime<boolean>;
53
+ setSeconds: (value: DateTime, second: number) => DateTime<boolean>;
54
+ setMilliseconds: (value: DateTime, millisecond: number) => DateTime<boolean>;
55
+ getDaysInMonth: (value: DateTime) => import("luxon").PossibleDaysInMonth;
56
+ getWeekArray: (value: DateTime) => DateTime<boolean>[][];
57
+ getWeekNumber: (value: DateTime) => number;
58
+ getDayOfWeek: (value: DateTime) => number;
59
+ }
@@ -0,0 +1,72 @@
1
+ // Adapted from AdapterLuxon in @mui/x-date-pickers, which is based on @date-io/luxon.
2
+ // MIT License, Copyright (c) 2017 Dmitriy Kovalenko. See LICENSE.
3
+ import { DateTime } from 'luxon';
4
+ /** Adapter for Luxon v3. Values are `DateTime` objects, in the zone they were created in. */
5
+ export class AdapterLuxon {
6
+ lib = 'luxon';
7
+ locale;
8
+ constructor({ locale } = {}) {
9
+ this.locale = locale || 'en-US';
10
+ }
11
+ withLocale = (value) => value.locale === this.locale ? value : value.setLocale(this.locale);
12
+ date = (value) => value === undefined
13
+ ? DateTime.now().setLocale(this.locale)
14
+ : DateTime.fromISO(value, { locale: this.locale });
15
+ getInvalidDate = () => DateTime.fromJSDate(new Date('Invalid Date'));
16
+ isValid = (value) => value != null && value.isValid;
17
+ toJsDate = (value) => value.toJSDate();
18
+ formatByString = (value, format) => value.setLocale(this.locale).toFormat(format);
19
+ parse = (value, format) => value === '' ? null : DateTime.fromFormat(value, format, { locale: this.locale });
20
+ isEqual = (value, comparing) => value === null || comparing === null ? value === comparing : +value === +comparing;
21
+ // the comparison happens in the zone of `value`
22
+ isSameYear = (value, comparing) => value.hasSame(comparing.setZone(value.zone), 'year');
23
+ isSameMonth = (value, comparing) => value.hasSame(comparing.setZone(value.zone), 'month');
24
+ isSameDay = (value, comparing) => value.hasSame(comparing.setZone(value.zone), 'day');
25
+ isAfter = (value, comparing) => value > comparing;
26
+ isBefore = (value, comparing) => value < comparing;
27
+ isWithinRange = (value, [start, end]) => value >= start && value <= end;
28
+ startOfYear = (value) => value.startOf('year');
29
+ startOfMonth = (value) => value.startOf('month');
30
+ startOfWeek = (value) => this.withLocale(value).startOf('week', { useLocaleWeeks: true });
31
+ startOfDay = (value) => value.startOf('day');
32
+ endOfYear = (value) => value.endOf('year');
33
+ endOfMonth = (value) => value.endOf('month');
34
+ endOfWeek = (value) => this.withLocale(value).endOf('week', { useLocaleWeeks: true });
35
+ endOfDay = (value) => value.endOf('day');
36
+ addYears = (value, amount) => value.plus({ years: amount });
37
+ addMonths = (value, amount) => value.plus({ months: amount });
38
+ addWeeks = (value, amount) => value.plus({ weeks: amount });
39
+ addDays = (value, amount) => value.plus({ days: amount });
40
+ addHours = (value, amount) => value.plus({ hours: amount });
41
+ addMinutes = (value, amount) => value.plus({ minutes: amount });
42
+ addSeconds = (value, amount) => value.plus({ seconds: amount });
43
+ getYear = (value) => value.year;
44
+ // Luxon months are 1-based
45
+ getMonth = (value) => value.month - 1;
46
+ getDate = (value) => value.day;
47
+ getHours = (value) => value.hour;
48
+ getMinutes = (value) => value.minute;
49
+ getSeconds = (value) => value.second;
50
+ getMilliseconds = (value) => value.millisecond;
51
+ setYear = (value, year) => value.set({ year });
52
+ setMonth = (value, month) => value.set({ month: month + 1 });
53
+ setDate = (value, date) => value.set({ day: date });
54
+ setHours = (value, hour) => value.set({ hour });
55
+ setMinutes = (value, minute) => value.set({ minute });
56
+ setSeconds = (value, second) => value.set({ second });
57
+ setMilliseconds = (value, millisecond) => value.set({ millisecond });
58
+ getDaysInMonth = (value) => value.daysInMonth;
59
+ getWeekArray = (value) => {
60
+ const first = this.startOfWeek(this.startOfMonth(value));
61
+ const last = this.endOfWeek(this.endOfMonth(value));
62
+ const days = Math.round(last.diff(first, 'days').days);
63
+ const weeks = [];
64
+ for (let day = 0; day < days; day += 1) {
65
+ const week = (weeks[Math.floor(day / 7)] ??= []);
66
+ week.push(first.plus({ days: day }));
67
+ }
68
+ return weeks;
69
+ };
70
+ getWeekNumber = (value) => this.withLocale(value).localWeekNumber ?? value.weekNumber;
71
+ getDayOfWeek = (value) => this.withLocale(value).localWeekday ?? value.weekday;
72
+ }
@@ -0,0 +1,62 @@
1
+ import type { DateAdapter } from './types.js';
2
+ /** A date, or a year given as a number or numeric string. */
3
+ export type YearLike<T> = T | number | string;
4
+ /** A date, or a time string such as `10:30`, `10:30:15` or `10:30:15.5`. */
5
+ export type TimeLike<T> = T | string;
6
+ /**
7
+ * Builds the helpers of `@wojtekmaj/date-utils` (start, end, previous, next and range of a century,
8
+ * decade, year, month and day, plus ISO-like local formatting) on top of any `DateAdapter`.
9
+ */
10
+ export declare function createDateUtils<T>(adapter: DateAdapter<T>): {
11
+ adapter: DateAdapter<T>;
12
+ getYear: (value: YearLike<T>) => number;
13
+ getMonth: (date: T) => number;
14
+ getMonthHuman: (date: T) => number;
15
+ getDate: (date: T) => number;
16
+ getHours: (date: TimeLike<T>) => number;
17
+ getMinutes: (date: TimeLike<T>) => number;
18
+ getSeconds: (date: TimeLike<T>) => number;
19
+ getMilliseconds: (date: TimeLike<T>) => number;
20
+ getCenturyStart: (date: YearLike<T>) => T;
21
+ getPreviousCenturyStart: (date: YearLike<T>, offset?: number) => T;
22
+ getNextCenturyStart: (date: YearLike<T>, offset?: number) => T;
23
+ getCenturyEnd: (date: YearLike<T>) => T;
24
+ getPreviousCenturyEnd: (date: YearLike<T>, offset?: number) => T;
25
+ getNextCenturyEnd: (date: YearLike<T>, offset?: number) => T;
26
+ getCenturyRange: (date: YearLike<T>) => [T, T];
27
+ getDecadeStart: (date: YearLike<T>) => T;
28
+ getPreviousDecadeStart: (date: YearLike<T>, offset?: number) => T;
29
+ getNextDecadeStart: (date: YearLike<T>, offset?: number) => T;
30
+ getDecadeEnd: (date: YearLike<T>) => T;
31
+ getPreviousDecadeEnd: (date: YearLike<T>, offset?: number) => T;
32
+ getNextDecadeEnd: (date: YearLike<T>, offset?: number) => T;
33
+ getDecadeRange: (date: YearLike<T>) => [T, T];
34
+ getYearStart: (date: YearLike<T>) => T;
35
+ getPreviousYearStart: (date: YearLike<T>, offset?: number) => T;
36
+ getNextYearStart: (date: YearLike<T>, offset?: number) => T;
37
+ getYearEnd: (date: YearLike<T>) => T;
38
+ getPreviousYearEnd: (date: YearLike<T>, offset?: number) => T;
39
+ getNextYearEnd: (date: YearLike<T>, offset?: number) => T;
40
+ getYearRange: (date: YearLike<T>) => [T, T];
41
+ getMonthStart: (date: YearLike<T>) => T;
42
+ getPreviousMonthStart: (date: YearLike<T>, offset?: number) => T;
43
+ getNextMonthStart: (date: YearLike<T>, offset?: number) => T;
44
+ getMonthEnd: (date: YearLike<T>) => T;
45
+ getPreviousMonthEnd: (date: YearLike<T>, offset?: number) => T;
46
+ getNextMonthEnd: (date: YearLike<T>, offset?: number) => T;
47
+ getMonthRange: (date: YearLike<T>) => [T, T];
48
+ getDayStart: (date: YearLike<T>) => T;
49
+ getPreviousDayStart: (date: YearLike<T>, offset?: number) => T;
50
+ getNextDayStart: (date: YearLike<T>, offset?: number) => T;
51
+ getDayEnd: (date: YearLike<T>) => T;
52
+ getPreviousDayEnd: (date: YearLike<T>, offset?: number) => T;
53
+ getNextDayEnd: (date: YearLike<T>, offset?: number) => T;
54
+ getDayRange: (date: YearLike<T>) => [T, T];
55
+ getDaysInMonth: (date: T) => number;
56
+ getHoursMinutes: (date: TimeLike<T>) => string;
57
+ getHoursMinutesSeconds: (date: TimeLike<T>) => string;
58
+ getISOLocalMonth: (date: T) => string;
59
+ getISOLocalDate: (date: T) => string;
60
+ getISOLocalDateTime: (date: T) => string;
61
+ };
62
+ export type DateUtils<T> = ReturnType<typeof createDateUtils<T>>;