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.
@@ -0,0 +1,141 @@
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
+
47
+ import type { Locale } from 'date-fns/locale';
48
+
49
+ import type { DateAdapter } from './types.js';
50
+
51
+ export interface AdapterDateFnsOptions {
52
+ /** A date-fns locale, for example `import { de } from 'date-fns/locale/de'`. Defaults to en-US. */
53
+ locale?: Locale;
54
+ }
55
+
56
+ /** Adapter for date-fns v3 and v4. Values are native `Date` objects. */
57
+ export class AdapterDateFns implements DateAdapter<Date> {
58
+ public readonly lib = 'date-fns';
59
+
60
+ public readonly locale: Locale;
61
+
62
+ constructor({ locale }: AdapterDateFnsOptions = {}) {
63
+ this.locale = locale ?? enUS;
64
+ }
65
+
66
+ public date = (value?: string) => (value === undefined ? new Date() : new Date(value));
67
+ public getInvalidDate = () => new Date('Invalid Date');
68
+ public isValid = (value: Date | null | undefined): value is Date =>
69
+ value != null && isValid(value);
70
+ public toJsDate = (value: Date) => value;
71
+
72
+ public formatByString = (value: Date, formatString: string) =>
73
+ format(value, formatString, { locale: this.locale });
74
+ public parse = (value: string, formatString: string) =>
75
+ value === '' ? null : parse(value, formatString, new Date(), { locale: this.locale });
76
+
77
+ public isEqual = (value: Date | null, comparing: Date | null) =>
78
+ value === null || comparing === null ? value === comparing : isEqual(value, comparing);
79
+ public isSameYear = (value: Date, comparing: Date) => isSameYear(value, comparing);
80
+ public isSameMonth = (value: Date, comparing: Date) => isSameMonth(value, comparing);
81
+ public isSameDay = (value: Date, comparing: Date) => isSameDay(value, comparing);
82
+ public isAfter = (value: Date, comparing: Date) => isAfter(value, comparing);
83
+ public isBefore = (value: Date, comparing: Date) => isBefore(value, comparing);
84
+ public isWithinRange = (value: Date, [start, end]: [Date, Date]) =>
85
+ isWithinInterval(value, { start, end });
86
+
87
+ public startOfYear = (value: Date) => startOfYear(value);
88
+ public startOfMonth = (value: Date) => startOfMonth(value);
89
+ public startOfWeek = (value: Date) => startOfWeek(value, { locale: this.locale });
90
+ public startOfDay = (value: Date) => startOfDay(value);
91
+ public endOfYear = (value: Date) => endOfYear(value);
92
+ public endOfMonth = (value: Date) => endOfMonth(value);
93
+ public endOfWeek = (value: Date) => endOfWeek(value, { locale: this.locale });
94
+ public endOfDay = (value: Date) => endOfDay(value);
95
+
96
+ public addYears = (value: Date, amount: number) => addYears(value, amount);
97
+ public addMonths = (value: Date, amount: number) => addMonths(value, amount);
98
+ public addWeeks = (value: Date, amount: number) => addWeeks(value, amount);
99
+ public addDays = (value: Date, amount: number) => addDays(value, amount);
100
+ public addHours = (value: Date, amount: number) => addHours(value, amount);
101
+ public addMinutes = (value: Date, amount: number) => addMinutes(value, amount);
102
+ public addSeconds = (value: Date, amount: number) => addSeconds(value, amount);
103
+
104
+ public getYear = (value: Date) => getYear(value);
105
+ public getMonth = (value: Date) => getMonth(value);
106
+ public getDate = (value: Date) => getDate(value);
107
+ public getHours = (value: Date) => getHours(value);
108
+ public getMinutes = (value: Date) => getMinutes(value);
109
+ public getSeconds = (value: Date) => getSeconds(value);
110
+ public getMilliseconds = (value: Date) => getMilliseconds(value);
111
+
112
+ public setYear = (value: Date, year: number) => setYear(value, year);
113
+ public setMonth = (value: Date, month: number) => setMonth(value, month);
114
+ public setDate = (value: Date, date: number) => setDate(value, date);
115
+ public setHours = (value: Date, hours: number) => setHours(value, hours);
116
+ public setMinutes = (value: Date, minutes: number) => setMinutes(value, minutes);
117
+ public setSeconds = (value: Date, seconds: number) => setSeconds(value, seconds);
118
+ public setMilliseconds = (value: Date, milliseconds: number) =>
119
+ setMilliseconds(value, milliseconds);
120
+
121
+ public getDaysInMonth = (value: Date) => getDaysInMonth(value);
122
+
123
+ public getWeekArray = (value: Date) => {
124
+ const start = this.startOfWeek(this.startOfMonth(value));
125
+ const end = this.endOfWeek(this.endOfMonth(value));
126
+
127
+ const weeks: Date[][] = [];
128
+ let current = start;
129
+ for (let count = 0; this.isBefore(current, end); count += 1) {
130
+ const week = (weeks[Math.floor(count / 7)] ??= []);
131
+ week.push(current);
132
+ current = this.addDays(current, 1);
133
+ }
134
+ return weeks;
135
+ };
136
+
137
+ public getWeekNumber = (value: Date) => getWeek(value, { locale: this.locale });
138
+
139
+ public getDayOfWeek = (value: Date) =>
140
+ ((getDay(value) - (this.locale.options?.weekStartsOn ?? 0) + 7) % 7) + 1;
141
+ }
@@ -0,0 +1,108 @@
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
+
5
+ import type { DateAdapter } from './types.js';
6
+
7
+ export interface AdapterLuxonOptions {
8
+ /** A locale such as `de` or `en-GB`. Defaults to `en-US`. */
9
+ locale?: string;
10
+ }
11
+
12
+ /** Adapter for Luxon v3. Values are `DateTime` objects, in the zone they were created in. */
13
+ export class AdapterLuxon implements DateAdapter<DateTime> {
14
+ public readonly lib = 'luxon';
15
+
16
+ public readonly locale: string;
17
+
18
+ constructor({ locale }: AdapterLuxonOptions = {}) {
19
+ this.locale = locale || 'en-US';
20
+ }
21
+
22
+ private withLocale = (value: DateTime) =>
23
+ value.locale === this.locale ? value : value.setLocale(this.locale);
24
+
25
+ public date = (value?: string) =>
26
+ value === undefined
27
+ ? DateTime.now().setLocale(this.locale)
28
+ : DateTime.fromISO(value, { locale: this.locale });
29
+ public getInvalidDate = () => DateTime.fromJSDate(new Date('Invalid Date'));
30
+ public isValid = (value: DateTime | null | undefined): value is DateTime =>
31
+ value != null && value.isValid;
32
+ public toJsDate = (value: DateTime) => value.toJSDate();
33
+
34
+ public formatByString = (value: DateTime, format: string) =>
35
+ value.setLocale(this.locale).toFormat(format);
36
+ public parse = (value: string, format: string) =>
37
+ value === '' ? null : DateTime.fromFormat(value, format, { locale: this.locale });
38
+
39
+ public isEqual = (value: DateTime | null, comparing: DateTime | null) =>
40
+ value === null || comparing === null ? value === comparing : +value === +comparing;
41
+ // the comparison happens in the zone of `value`
42
+ public isSameYear = (value: DateTime, comparing: DateTime) =>
43
+ value.hasSame(comparing.setZone(value.zone), 'year');
44
+ public isSameMonth = (value: DateTime, comparing: DateTime) =>
45
+ value.hasSame(comparing.setZone(value.zone), 'month');
46
+ public isSameDay = (value: DateTime, comparing: DateTime) =>
47
+ value.hasSame(comparing.setZone(value.zone), 'day');
48
+ public isAfter = (value: DateTime, comparing: DateTime) => value > comparing;
49
+ public isBefore = (value: DateTime, comparing: DateTime) => value < comparing;
50
+ public isWithinRange = (value: DateTime, [start, end]: [DateTime, DateTime]) =>
51
+ value >= start && value <= end;
52
+
53
+ public startOfYear = (value: DateTime) => value.startOf('year');
54
+ public startOfMonth = (value: DateTime) => value.startOf('month');
55
+ public startOfWeek = (value: DateTime) =>
56
+ this.withLocale(value).startOf('week', { useLocaleWeeks: true });
57
+ public startOfDay = (value: DateTime) => value.startOf('day');
58
+ public endOfYear = (value: DateTime) => value.endOf('year');
59
+ public endOfMonth = (value: DateTime) => value.endOf('month');
60
+ public endOfWeek = (value: DateTime) =>
61
+ this.withLocale(value).endOf('week', { useLocaleWeeks: true });
62
+ public endOfDay = (value: DateTime) => value.endOf('day');
63
+
64
+ public addYears = (value: DateTime, amount: number) => value.plus({ years: amount });
65
+ public addMonths = (value: DateTime, amount: number) => value.plus({ months: amount });
66
+ public addWeeks = (value: DateTime, amount: number) => value.plus({ weeks: amount });
67
+ public addDays = (value: DateTime, amount: number) => value.plus({ days: amount });
68
+ public addHours = (value: DateTime, amount: number) => value.plus({ hours: amount });
69
+ public addMinutes = (value: DateTime, amount: number) => value.plus({ minutes: amount });
70
+ public addSeconds = (value: DateTime, amount: number) => value.plus({ seconds: amount });
71
+
72
+ public getYear = (value: DateTime) => value.year;
73
+ // Luxon months are 1-based
74
+ public getMonth = (value: DateTime) => value.month - 1;
75
+ public getDate = (value: DateTime) => value.day;
76
+ public getHours = (value: DateTime) => value.hour;
77
+ public getMinutes = (value: DateTime) => value.minute;
78
+ public getSeconds = (value: DateTime) => value.second;
79
+ public getMilliseconds = (value: DateTime) => value.millisecond;
80
+
81
+ public setYear = (value: DateTime, year: number) => value.set({ year });
82
+ public setMonth = (value: DateTime, month: number) => value.set({ month: month + 1 });
83
+ public setDate = (value: DateTime, date: number) => value.set({ day: date });
84
+ public setHours = (value: DateTime, hour: number) => value.set({ hour });
85
+ public setMinutes = (value: DateTime, minute: number) => value.set({ minute });
86
+ public setSeconds = (value: DateTime, second: number) => value.set({ second });
87
+ public setMilliseconds = (value: DateTime, millisecond: number) => value.set({ millisecond });
88
+
89
+ public getDaysInMonth = (value: DateTime) => value.daysInMonth!;
90
+
91
+ public getWeekArray = (value: DateTime) => {
92
+ const first = this.startOfWeek(this.startOfMonth(value));
93
+ const last = this.endOfWeek(this.endOfMonth(value));
94
+ const days = Math.round(last.diff(first, 'days').days);
95
+
96
+ const weeks: DateTime[][] = [];
97
+ for (let day = 0; day < days; day += 1) {
98
+ const week = (weeks[Math.floor(day / 7)] ??= []);
99
+ week.push(first.plus({ days: day }));
100
+ }
101
+ return weeks;
102
+ };
103
+
104
+ public getWeekNumber = (value: DateTime) =>
105
+ this.withLocale(value).localWeekNumber ?? value.weekNumber;
106
+
107
+ public getDayOfWeek = (value: DateTime) => this.withLocale(value).localWeekday ?? value.weekday;
108
+ }
@@ -0,0 +1,188 @@
1
+ import type { DateAdapter } from './types.js';
2
+
3
+ /** A date, or a year given as a number or numeric string. */
4
+ export type YearLike<T> = T | number | string;
5
+ /** A date, or a time string such as `10:30`, `10:30:15` or `10:30:15.5`. */
6
+ export type TimeLike<T> = T | string;
7
+
8
+ const padStart = (value: number | string, length = 2) => String(value).padStart(length, '0');
9
+
10
+ const isDateString = (value: unknown): value is string => typeof value === 'string';
11
+
12
+ /** Piece `index` (0 hours, 1 minutes, 2 seconds) of a time string that has at least `hh:mm`. */
13
+ const timePiece = (value: string, index: number) => {
14
+ const pieces = value.split(':');
15
+ return pieces.length >= 2 ? pieces[index] || (index === 0 ? undefined : '0') : undefined;
16
+ };
17
+
18
+ const parseTimePiece = (piece: string | undefined, name: string, value: string) => {
19
+ const parsed = Number.parseInt(piece ?? '', 10);
20
+ if (Number.isNaN(parsed)) throw new Error(`Failed to get ${name} from date: ${value}.`);
21
+ return parsed;
22
+ };
23
+
24
+ /**
25
+ * Builds the helpers of `@wojtekmaj/date-utils` (start, end, previous, next and range of a century,
26
+ * decade, year, month and day, plus ISO-like local formatting) on top of any `DateAdapter`.
27
+ */
28
+ export function createDateUtils<T>(adapter: DateAdapter<T>) {
29
+ const ops = adapter;
30
+
31
+ const yearOf = (value: YearLike<T>): number => {
32
+ if (typeof value === 'number') return value;
33
+ if (isDateString(value)) {
34
+ const year = Number.parseInt(value, 10);
35
+ if (!Number.isNaN(year)) return year;
36
+ throw new Error(`Failed to get year from date: ${value}.`);
37
+ }
38
+ return ops.getYear(value);
39
+ };
40
+
41
+ /** A date to start from: the given one, or today moved to the given year. */
42
+ const dateOf = (value: YearLike<T>): T =>
43
+ typeof value === 'number' || isDateString(value)
44
+ ? ops.setYear(ops.date(), yearOf(value))
45
+ : value;
46
+
47
+ // ---- getters
48
+
49
+ const getYear = yearOf;
50
+ const getMonth = (date: T) => ops.getMonth(date);
51
+ const getMonthHuman = (date: T) => ops.getMonth(date) + 1;
52
+ const getDate = (date: T) => ops.getDate(date);
53
+ const getHours = (date: TimeLike<T>) =>
54
+ isDateString(date) ? parseTimePiece(timePiece(date, 0), 'hours', date) : ops.getHours(date);
55
+ const getMinutes = (date: TimeLike<T>) =>
56
+ isDateString(date) ? parseTimePiece(timePiece(date, 1), 'minutes', date) : ops.getMinutes(date);
57
+ const getSeconds = (date: TimeLike<T>) =>
58
+ isDateString(date) ? parseTimePiece(timePiece(date, 2), 'seconds', date) : ops.getSeconds(date);
59
+ const getMilliseconds = (date: TimeLike<T>) =>
60
+ isDateString(date)
61
+ ? parseTimePiece(
62
+ timePiece(date, 2) === undefined ? undefined : timePiece(date, 2)!.split('.')[1] || '0',
63
+ 'milliseconds',
64
+ date,
65
+ )
66
+ : ops.getMilliseconds(date);
67
+
68
+ // ---- edges of a period
69
+
70
+ type Edge = (date: YearLike<T>) => T;
71
+ type Neighbor = (date: YearLike<T>, offset?: number) => T;
72
+
73
+ const range = (start: Edge, end: Edge) => (date: YearLike<T>) =>
74
+ [start(date), end(date)] as [T, T];
75
+
76
+ /** Builds start, end, previous, next and range helpers of a period measured in `unit`s. */
77
+ const period = (
78
+ unit: number,
79
+ startOf: (date: T) => T,
80
+ endOf: (date: T) => T,
81
+ shift: (date: T, amount: number) => T,
82
+ alignStart: (date: T) => T = startOf,
83
+ ) => {
84
+ const start: Edge = (date) => alignStart(dateOf(date));
85
+ const end: Edge = (date) => endOf(alignStart(dateOf(date)));
86
+ const previous = (edge: Edge, offset: number): Neighbor => {
87
+ return (date, amount = offset) => edge(shift(alignStart(dateOf(date)), amount));
88
+ };
89
+ return {
90
+ start,
91
+ end,
92
+ previousStart: previous(start, -unit),
93
+ nextStart: previous(start, unit),
94
+ previousEnd: previous(end, -unit),
95
+ nextEnd: previous(end, unit),
96
+ range: range(start, end),
97
+ };
98
+ };
99
+
100
+ // A century runs from year 1 to 100, 101 to 200, ...: 2001 to 2100 is the 21st. Same for decades.
101
+ const alignedYear = (year: number, size: number) => year + ((-year + 1) % size);
102
+ const alignedStart = (size: number) => (date: T) =>
103
+ ops.startOfYear(ops.setYear(date, alignedYear(ops.getYear(date), size)));
104
+ const alignedEnd = (size: number) => (date: T) =>
105
+ ops.endOfYear(ops.addYears(ops.setYear(date, alignedYear(ops.getYear(date), size)), size - 1));
106
+
107
+ const century = period(100, alignedStart(100), alignedEnd(100), ops.addYears, alignedStart(100));
108
+ const decade = period(10, alignedStart(10), alignedEnd(10), ops.addYears, alignedStart(10));
109
+ const year = period(1, ops.startOfYear, ops.endOfYear, ops.addYears);
110
+ const month = period(1, ops.startOfMonth, ops.endOfMonth, ops.addMonths);
111
+ const day = period(1, ops.startOfDay, ops.endOfDay, ops.addDays);
112
+
113
+ const getDaysInMonth = (date: T) => ops.getDaysInMonth(date);
114
+
115
+ // ---- ISO-like local formatting
116
+
117
+ const getHoursMinutes = (date: TimeLike<T>) =>
118
+ `${padStart(getHours(date))}:${padStart(getMinutes(date))}`;
119
+ const getHoursMinutesSeconds = (date: TimeLike<T>) =>
120
+ `${getHoursMinutes(date)}:${padStart(getSeconds(date))}`;
121
+ const getISOLocalMonth = (date: T) =>
122
+ `${padStart(ops.getYear(date), 4)}-${padStart(getMonthHuman(date))}`;
123
+ const getISOLocalDate = (date: T) => `${getISOLocalMonth(date)}-${padStart(ops.getDate(date))}`;
124
+ const getISOLocalDateTime = (date: T) =>
125
+ `${getISOLocalDate(date)}T${getHoursMinutesSeconds(date)}`;
126
+
127
+ return {
128
+ adapter,
129
+
130
+ getYear,
131
+ getMonth,
132
+ getMonthHuman,
133
+ getDate,
134
+ getHours,
135
+ getMinutes,
136
+ getSeconds,
137
+ getMilliseconds,
138
+
139
+ getCenturyStart: century.start,
140
+ getPreviousCenturyStart: century.previousStart,
141
+ getNextCenturyStart: century.nextStart,
142
+ getCenturyEnd: century.end,
143
+ getPreviousCenturyEnd: century.previousEnd,
144
+ getNextCenturyEnd: century.nextEnd,
145
+ getCenturyRange: century.range,
146
+
147
+ getDecadeStart: decade.start,
148
+ getPreviousDecadeStart: decade.previousStart,
149
+ getNextDecadeStart: decade.nextStart,
150
+ getDecadeEnd: decade.end,
151
+ getPreviousDecadeEnd: decade.previousEnd,
152
+ getNextDecadeEnd: decade.nextEnd,
153
+ getDecadeRange: decade.range,
154
+
155
+ getYearStart: year.start,
156
+ getPreviousYearStart: year.previousStart,
157
+ getNextYearStart: year.nextStart,
158
+ getYearEnd: year.end,
159
+ getPreviousYearEnd: year.previousEnd,
160
+ getNextYearEnd: year.nextEnd,
161
+ getYearRange: year.range,
162
+
163
+ getMonthStart: month.start,
164
+ getPreviousMonthStart: month.previousStart,
165
+ getNextMonthStart: month.nextStart,
166
+ getMonthEnd: month.end,
167
+ getPreviousMonthEnd: month.previousEnd,
168
+ getNextMonthEnd: month.nextEnd,
169
+ getMonthRange: month.range,
170
+
171
+ getDayStart: day.start,
172
+ getPreviousDayStart: day.previousStart,
173
+ getNextDayStart: day.nextStart,
174
+ getDayEnd: day.end,
175
+ getPreviousDayEnd: day.previousEnd,
176
+ getNextDayEnd: day.nextEnd,
177
+ getDayRange: day.range,
178
+
179
+ getDaysInMonth,
180
+ getHoursMinutes,
181
+ getHoursMinutesSeconds,
182
+ getISOLocalMonth,
183
+ getISOLocalDate,
184
+ getISOLocalDateTime,
185
+ };
186
+ }
187
+
188
+ export type DateUtils<T> = ReturnType<typeof createDateUtils<T>>;
@@ -0,0 +1,2 @@
1
+ export { AdapterDateFns } from './AdapterDateFns.js';
2
+ export type { AdapterDateFnsOptions } from './AdapterDateFns.js';
package/src/index.ts ADDED
@@ -0,0 +1,67 @@
1
+ import { AdapterDate } from './AdapterDate.js';
2
+ import { createDateUtils } from './createDateUtils.js';
3
+
4
+ export { AdapterDate } from './AdapterDate.js';
5
+ export type { AdapterDateOptions } from './AdapterDate.js';
6
+ export { createDateUtils } from './createDateUtils.js';
7
+ export type { DateUtils, TimeLike, YearLike } from './createDateUtils.js';
8
+ export type { DateAdapter } from './types.js';
9
+
10
+ /**
11
+ * The helpers on the native `Date`, with the names and behavior of `@wojtekmaj/date-utils`.
12
+ * For date-fns or Luxon, call `createDateUtils` with `AdapterDateFns` or `AdapterLuxon`
13
+ * from `svelte-date-utils/date-fns` or `svelte-date-utils/luxon`.
14
+ */
15
+ export const dateUtils = createDateUtils(new AdapterDate());
16
+
17
+ export const {
18
+ getYear,
19
+ getMonth,
20
+ getMonthHuman,
21
+ getDate,
22
+ getHours,
23
+ getMinutes,
24
+ getSeconds,
25
+ getMilliseconds,
26
+ getCenturyStart,
27
+ getPreviousCenturyStart,
28
+ getNextCenturyStart,
29
+ getCenturyEnd,
30
+ getPreviousCenturyEnd,
31
+ getNextCenturyEnd,
32
+ getCenturyRange,
33
+ getDecadeStart,
34
+ getPreviousDecadeStart,
35
+ getNextDecadeStart,
36
+ getDecadeEnd,
37
+ getPreviousDecadeEnd,
38
+ getNextDecadeEnd,
39
+ getDecadeRange,
40
+ getYearStart,
41
+ getPreviousYearStart,
42
+ getNextYearStart,
43
+ getYearEnd,
44
+ getPreviousYearEnd,
45
+ getNextYearEnd,
46
+ getYearRange,
47
+ getMonthStart,
48
+ getPreviousMonthStart,
49
+ getNextMonthStart,
50
+ getMonthEnd,
51
+ getPreviousMonthEnd,
52
+ getNextMonthEnd,
53
+ getMonthRange,
54
+ getDayStart,
55
+ getPreviousDayStart,
56
+ getNextDayStart,
57
+ getDayEnd,
58
+ getPreviousDayEnd,
59
+ getNextDayEnd,
60
+ getDayRange,
61
+ getDaysInMonth,
62
+ getHoursMinutes,
63
+ getHoursMinutesSeconds,
64
+ getISOLocalMonth,
65
+ getISOLocalDate,
66
+ getISOLocalDateTime,
67
+ } = dateUtils;
package/src/luxon.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { AdapterLuxon } from './AdapterLuxon.js';
2
+ export type { AdapterLuxonOptions } from './AdapterLuxon.js';
package/src/types.ts ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The date operations the utilities need, over any date type `T` (`Date`, a date-fns `Date`, a
3
+ * Luxon `DateTime`, ...). The shape follows `MuiPickersAdapter` from `@mui/x-date-pickers`, cut
4
+ * down to what a calendar and a date input use. Months are 0-based in every adapter.
5
+ */
6
+ export interface DateAdapter<T> {
7
+ /** Name of the library behind the adapter. */
8
+ readonly lib: string;
9
+
10
+ /** The current time, or the date parsed from an ISO string. */
11
+ date(value?: string): T;
12
+ getInvalidDate(): T;
13
+ isValid(value: T | null | undefined): value is T;
14
+ toJsDate(value: T): Date;
15
+
16
+ formatByString(value: T, format: string): string;
17
+ parse(value: string, format: string): T | null;
18
+
19
+ isEqual(value: T | null, comparing: T | null): boolean;
20
+ isSameYear(value: T, comparing: T): boolean;
21
+ isSameMonth(value: T, comparing: T): boolean;
22
+ isSameDay(value: T, comparing: T): boolean;
23
+ isAfter(value: T, comparing: T): boolean;
24
+ isBefore(value: T, comparing: T): boolean;
25
+ isWithinRange(value: T, range: [T, T]): boolean;
26
+
27
+ startOfYear(value: T): T;
28
+ startOfMonth(value: T): T;
29
+ startOfWeek(value: T): T;
30
+ startOfDay(value: T): T;
31
+ endOfYear(value: T): T;
32
+ endOfMonth(value: T): T;
33
+ endOfWeek(value: T): T;
34
+ endOfDay(value: T): T;
35
+
36
+ addYears(value: T, amount: number): T;
37
+ addMonths(value: T, amount: number): T;
38
+ addWeeks(value: T, amount: number): T;
39
+ addDays(value: T, amount: number): T;
40
+ addHours(value: T, amount: number): T;
41
+ addMinutes(value: T, amount: number): T;
42
+ addSeconds(value: T, amount: number): T;
43
+
44
+ getYear(value: T): number;
45
+ /** 0-based month. */
46
+ getMonth(value: T): number;
47
+ getDate(value: T): number;
48
+ getHours(value: T): number;
49
+ getMinutes(value: T): number;
50
+ getSeconds(value: T): number;
51
+ getMilliseconds(value: T): number;
52
+
53
+ setYear(value: T, year: number): T;
54
+ /** 0-based month. */
55
+ setMonth(value: T, month: number): T;
56
+ setDate(value: T, date: number): T;
57
+ setHours(value: T, hours: number): T;
58
+ setMinutes(value: T, minutes: number): T;
59
+ setSeconds(value: T, seconds: number): T;
60
+ setMilliseconds(value: T, milliseconds: number): T;
61
+
62
+ getDaysInMonth(value: T): number;
63
+ /** Weeks of the month of `value`, padded with days of the neighboring months. */
64
+ getWeekArray(value: T): T[][];
65
+ getWeekNumber(value: T): number;
66
+ /** 1 to 7, from the first day of the week of the locale. */
67
+ getDayOfWeek(value: T): number;
68
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.