@formkit/tempo 0.1.2 → 1.1.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/README.md +22 -1
- package/dist/add.d.ts +11 -0
- package/dist/add.mjs +50 -0
- package/dist/add.mjs.map +1 -0
- package/dist/addDay.d.ts +4 -3
- package/dist/addDay.mjs.map +1 -1
- package/dist/addHour.d.ts +4 -3
- package/dist/addHour.mjs.map +1 -1
- package/dist/addMillisecond.d.ts +10 -0
- package/dist/addMillisecond.mjs +11 -0
- package/dist/addMillisecond.mjs.map +1 -0
- package/dist/addMinute.d.ts +5 -4
- package/dist/addMinute.mjs.map +1 -1
- package/dist/addMonth.d.ts +5 -5
- package/dist/addMonth.mjs +2 -12
- package/dist/addMonth.mjs.map +1 -1
- package/dist/addSecond.d.ts +4 -3
- package/dist/addSecond.mjs.map +1 -1
- package/dist/addYear.d.ts +5 -5
- package/dist/addYear.mjs +6 -12
- package/dist/addYear.mjs.map +1 -1
- package/dist/ap.mjs +1 -2
- package/dist/ap.mjs.map +1 -1
- package/dist/applyOffset.d.ts +5 -5
- package/dist/applyOffset.mjs +5 -11
- package/dist/applyOffset.mjs.map +1 -1
- package/dist/bundle.d.ts +365 -115
- package/dist/bundle.mjs +364 -180
- package/dist/bundle.mjs.map +1 -1
- package/dist/common.d.ts +27 -7
- package/dist/common.mjs +47 -42
- package/dist/common.mjs.map +1 -1
- package/dist/date.d.ts +2 -2
- package/dist/date.mjs +1 -3
- package/dist/date.mjs.map +1 -1
- package/dist/dayEnd.d.ts +3 -3
- package/dist/dayEnd.mjs.map +1 -1
- package/dist/dayOfYear.d.ts +3 -3
- package/dist/dayOfYear.mjs.map +1 -1
- package/dist/dayStart.d.ts +3 -3
- package/dist/dayStart.mjs +1 -1
- package/dist/dayStart.mjs.map +1 -1
- package/dist/diff.d.ts +38 -0
- package/dist/diff.mjs +86 -0
- package/dist/diff.mjs.map +1 -0
- package/dist/diffDays.d.ts +12 -5
- package/dist/diffDays.mjs +1 -0
- package/dist/diffDays.mjs.map +1 -1
- package/dist/diffHours.d.ts +12 -5
- package/dist/diffHours.mjs +1 -0
- package/dist/diffHours.mjs.map +1 -1
- package/dist/diffMilliseconds.d.ts +10 -4
- package/dist/diffMilliseconds.mjs.map +1 -1
- package/dist/diffMinutes.d.ts +11 -3
- package/dist/diffMinutes.mjs +5 -1
- package/dist/diffMinutes.mjs.map +1 -1
- package/dist/diffMonths.d.ts +10 -4
- package/dist/diffMonths.mjs.map +1 -1
- package/dist/diffSeconds.d.ts +12 -5
- package/dist/diffSeconds.mjs +5 -1
- package/dist/diffSeconds.mjs.map +1 -1
- package/dist/diffWeeks.d.ts +10 -3
- package/dist/diffWeeks.mjs.map +1 -1
- package/dist/diffYears.d.ts +10 -4
- package/dist/diffYears.mjs +4 -1
- package/dist/diffYears.mjs.map +1 -1
- package/dist/format.mjs +2 -3
- package/dist/format.mjs.map +1 -1
- package/dist/handleDateOverflow.d.ts +12 -0
- package/dist/handleDateOverflow.mjs +18 -0
- package/dist/handleDateOverflow.mjs.map +1 -0
- package/dist/hourEnd.d.ts +3 -3
- package/dist/hourEnd.mjs.map +1 -1
- package/dist/hourStart.d.ts +3 -3
- package/dist/hourStart.mjs +1 -1
- package/dist/hourStart.mjs.map +1 -1
- package/dist/index.cjs +380 -183
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +365 -115
- package/dist/index.d.ts +14 -1
- package/dist/index.mjs +26 -0
- package/dist/index.mjs.map +1 -1
- package/dist/isAfter.d.ts +6 -6
- package/dist/isAfter.mjs.map +1 -1
- package/dist/isBefore.d.ts +5 -5
- package/dist/isBefore.mjs.map +1 -1
- package/dist/isEqual.d.ts +13 -4
- package/dist/isEqual.mjs.map +1 -1
- package/dist/isFuture.d.ts +10 -0
- package/dist/isFuture.mjs +9 -0
- package/dist/isFuture.mjs.map +1 -0
- package/dist/isPast.d.ts +10 -0
- package/dist/isPast.mjs +9 -0
- package/dist/isPast.mjs.map +1 -0
- package/dist/iso8601.d.ts +1 -1
- package/dist/iso8601.mjs +4 -7
- package/dist/iso8601.mjs.map +1 -1
- package/dist/minuteEnd.d.ts +3 -3
- package/dist/minuteEnd.mjs.map +1 -1
- package/dist/minuteStart.d.ts +3 -3
- package/dist/minuteStart.mjs +1 -1
- package/dist/minuteStart.mjs.map +1 -1
- package/dist/monthDays.d.ts +3 -3
- package/dist/monthDays.mjs.map +1 -1
- package/dist/monthEnd.d.ts +3 -3
- package/dist/monthEnd.mjs.map +1 -1
- package/dist/monthStart.d.ts +3 -3
- package/dist/monthStart.mjs +1 -1
- package/dist/monthStart.mjs.map +1 -1
- package/dist/nearestDay.d.ts +3 -3
- package/dist/nearestDay.mjs +2 -4
- package/dist/nearestDay.mjs.map +1 -1
- package/dist/offset.d.ts +5 -5
- package/dist/offset.mjs +16 -16
- package/dist/offset.mjs.map +1 -1
- package/dist/parse.mjs +33 -23
- package/dist/parse.mjs.map +1 -1
- package/dist/parts.mjs +14 -24
- package/dist/parts.mjs.map +1 -1
- package/dist/range.mjs +1 -2
- package/dist/range.mjs.map +1 -1
- package/dist/removeOffset.d.ts +4 -4
- package/dist/removeOffset.mjs.map +1 -1
- package/dist/sameDay.d.ts +8 -2
- package/dist/sameDay.mjs.map +1 -1
- package/dist/sameHour.d.ts +8 -2
- package/dist/sameHour.mjs.map +1 -1
- package/dist/sameMillisecond.d.ts +16 -0
- package/dist/sameMillisecond.mjs +11 -0
- package/dist/sameMillisecond.mjs.map +1 -0
- package/dist/sameMinute.d.ts +8 -2
- package/dist/sameMinute.mjs.map +1 -1
- package/dist/sameMonth.d.ts +16 -0
- package/dist/sameMonth.mjs +11 -0
- package/dist/sameMonth.mjs.map +1 -0
- package/dist/sameSecond.d.ts +8 -2
- package/dist/sameSecond.mjs.map +1 -1
- package/dist/sameYear.d.ts +8 -2
- package/dist/sameYear.mjs.map +1 -1
- package/dist/setDayOfMonth.d.ts +11 -0
- package/dist/setDayOfMonth.mjs +16 -0
- package/dist/setDayOfMonth.mjs.map +1 -0
- package/dist/setHour.d.ts +10 -0
- package/dist/setHour.mjs +11 -0
- package/dist/setHour.mjs.map +1 -0
- package/dist/setMilliseconds.d.ts +10 -0
- package/dist/setMilliseconds.mjs +11 -0
- package/dist/setMilliseconds.mjs.map +1 -0
- package/dist/setMinutes.d.ts +10 -0
- package/dist/setMinutes.mjs +11 -0
- package/dist/setMinutes.mjs.map +1 -0
- package/dist/setMonth.d.ts +11 -0
- package/dist/setMonth.mjs +9 -0
- package/dist/setMonth.mjs.map +1 -0
- package/dist/setSeconds.d.ts +10 -0
- package/dist/setSeconds.mjs +11 -0
- package/dist/setSeconds.mjs.map +1 -0
- package/dist/setYear.d.ts +11 -0
- package/dist/setYear.mjs +9 -0
- package/dist/setYear.mjs.map +1 -0
- package/dist/types.d.ts +29 -7
- package/dist/tzDate.d.ts +5 -3
- package/dist/tzDate.mjs.map +1 -1
- package/dist/weekEnd.d.ts +4 -4
- package/dist/weekEnd.mjs +1 -1
- package/dist/weekEnd.mjs.map +1 -1
- package/dist/weekStart.d.ts +4 -4
- package/dist/weekStart.mjs +2 -3
- package/dist/weekStart.mjs.map +1 -1
- package/dist/yearDays.d.ts +3 -3
- package/dist/yearDays.mjs.map +1 -1
- package/dist/yearEnd.d.ts +3 -3
- package/dist/yearEnd.mjs +1 -2
- package/dist/yearEnd.mjs.map +1 -1
- package/dist/yearStart.d.ts +3 -3
- package/dist/yearStart.mjs +2 -3
- package/dist/yearStart.mjs.map +1 -1
- package/package.json +32 -23
package/dist/common.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NamedFormats, FormatPattern, FormatStyle,
|
|
1
|
+
import { NamedFormats, FormatPattern, FormatStyle, MaybeDateInput, Part, FilledPart, Format } from './types.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A date to use for determining various spec details.
|
|
@@ -28,6 +28,10 @@ declare const clock24: FormatPattern[];
|
|
|
28
28
|
* 12 hour format patterns.
|
|
29
29
|
*/
|
|
30
30
|
declare const clock12: FormatPattern[];
|
|
31
|
+
/**
|
|
32
|
+
* Fractional seconds patterns.
|
|
33
|
+
*/
|
|
34
|
+
declare const fractionalSeconds: FormatPattern[];
|
|
31
35
|
/**
|
|
32
36
|
* Tokens that have a fixed length.
|
|
33
37
|
*/
|
|
@@ -42,9 +46,10 @@ declare const fixedLength: {
|
|
|
42
46
|
ss: number;
|
|
43
47
|
};
|
|
44
48
|
/**
|
|
45
|
-
*
|
|
49
|
+
* Determines the length of a timezone offset string.
|
|
50
|
+
* Supports offsets with optional seconds component.
|
|
46
51
|
*/
|
|
47
|
-
declare function fixedLengthByOffset(offsetString: string): 6 | 5;
|
|
52
|
+
declare function fixedLengthByOffset(offsetString: string): 9 | 8 | 6 | 5;
|
|
48
53
|
/**
|
|
49
54
|
* Tokens that are genitive — in that they can have "possession" when used in
|
|
50
55
|
* a date phrase, "March’s 4th day" (but not in english).
|
|
@@ -85,19 +90,33 @@ declare const four: (n: number) => string;
|
|
|
85
90
|
declare function normStr(part: Intl.DateTimeFormatPart): Intl.DateTimeFormatPart;
|
|
86
91
|
/**
|
|
87
92
|
* Returns the parts filled with pertinent values.
|
|
88
|
-
* @param inputDate - The date to fill parts for
|
|
93
|
+
* @param [inputDate] - The date to fill parts for
|
|
89
94
|
* @param parts - An array of parts to fill
|
|
90
95
|
* @param locale - The locale to fill with.
|
|
91
96
|
* @param genitive - Whether to use genitive tokens values or not.
|
|
92
97
|
* @param offset - The explicit offset to fill with (ignores the date’s true offset).
|
|
93
98
|
*/
|
|
94
|
-
declare function fill(inputDate:
|
|
99
|
+
declare function fill(inputDate: MaybeDateInput, parts: Part[], locale: string, genitive?: boolean, offset?: string | null): FilledPart[];
|
|
100
|
+
/**
|
|
101
|
+
* Converts total seconds to an ISO8601 compatible offset (+04:00 or +0400).
|
|
102
|
+
* Only includes seconds in output if they are non-zero.
|
|
103
|
+
* @param totalSecs - The total offset in seconds (can be negative).
|
|
104
|
+
* @param token - "Z" for +HH:mm[:ss] or "ZZ" for +HHmm[ss]
|
|
105
|
+
*/
|
|
106
|
+
declare function secsToOffset(totalSecs: number, token?: string): string;
|
|
95
107
|
/**
|
|
96
108
|
* Converts minutes (300) to an ISO8601 compatible offset (+0400 or +04:00).
|
|
97
109
|
* @param timeDiffInMins - The difference in minutes between two timezones.
|
|
98
110
|
* @returns
|
|
99
111
|
*/
|
|
100
112
|
declare function minsToOffset(timeDiffInMins: number, token?: string): string;
|
|
113
|
+
/**
|
|
114
|
+
* Converts an offset (-05:32:11 or -053211) to total seconds.
|
|
115
|
+
* Supports offsets with optional seconds component.
|
|
116
|
+
* @param offset - The offset to convert to seconds.
|
|
117
|
+
* @param token - The timezone token format.
|
|
118
|
+
*/
|
|
119
|
+
declare function offsetToSecs(offset: string, token: TimezoneToken): number;
|
|
101
120
|
/**
|
|
102
121
|
* Converts an offset (-0500) to minutes (-300).
|
|
103
122
|
* @param offset - The offset to convert to minutes.
|
|
@@ -106,7 +125,8 @@ declare function minsToOffset(timeDiffInMins: number, token?: string): string;
|
|
|
106
125
|
declare function offsetToMins(offset: string, token: TimezoneToken): number;
|
|
107
126
|
/**
|
|
108
127
|
* Validates that an offset is valid according to the format:
|
|
109
|
-
* [+-]
|
|
128
|
+
* [+-]HH:mm or [+-]HH:mm:ss (Z token)
|
|
129
|
+
* [+-]HHmm or [+-]HHmmss (ZZ token)
|
|
110
130
|
* @param offset - The offset to validate.
|
|
111
131
|
* @param token - The timezone token format.
|
|
112
132
|
*/
|
|
@@ -134,4 +154,4 @@ declare function validate(parts: Part[]): Part[] | never;
|
|
|
134
154
|
*/
|
|
135
155
|
declare function getOffsetFormat(format: Format): TimezoneToken;
|
|
136
156
|
|
|
137
|
-
export { type TimezoneToken, clock12, clock24, clockAgnostic, dayPeriodMap, escapeTokens, fill, fixedLength, fixedLengthByOffset, four, genitiveTokens, getOffsetFormat, isNumeric, memoParts, minsToOffset, normStr, offsetToMins, specDate, styles, tokens, two, validOffset, validate };
|
|
157
|
+
export { type TimezoneToken, clock12, clock24, clockAgnostic, dayPeriodMap, escapeTokens, fill, fixedLength, fixedLengthByOffset, four, fractionalSeconds, genitiveTokens, getOffsetFormat, isNumeric, memoParts, minsToOffset, normStr, offsetToMins, offsetToSecs, secsToOffset, specDate, styles, tokens, two, validOffset, validate };
|
package/dist/common.mjs
CHANGED
|
@@ -32,6 +32,9 @@ var clock12 = [
|
|
|
32
32
|
["a", { dayPeriod: "narrow" }],
|
|
33
33
|
["A", { dayPeriod: "narrow" }]
|
|
34
34
|
];
|
|
35
|
+
var fractionalSeconds = [
|
|
36
|
+
["SSS", { fractionalSecond: "3-digit" }]
|
|
37
|
+
];
|
|
35
38
|
var fixedLength = {
|
|
36
39
|
DD: 2,
|
|
37
40
|
HH: 2,
|
|
@@ -43,6 +46,12 @@ var fixedLength = {
|
|
|
43
46
|
ss: 2
|
|
44
47
|
};
|
|
45
48
|
function fixedLengthByOffset(offsetString) {
|
|
49
|
+
if (/^[+-]\d{2}:\d{2}:\d{2}/.test(offsetString)) {
|
|
50
|
+
return 9;
|
|
51
|
+
}
|
|
52
|
+
if (/^[+-]\d{6}/.test(offsetString)) {
|
|
53
|
+
return 8;
|
|
54
|
+
}
|
|
46
55
|
if (/^[+-]\d{2}:\d{2}/.test(offsetString)) {
|
|
47
56
|
return 6;
|
|
48
57
|
}
|
|
@@ -53,17 +62,12 @@ function fixedLengthByOffset(offsetString) {
|
|
|
53
62
|
}
|
|
54
63
|
var genitiveTokens = ["MMMM", "MMM", "dddd", "ddd"];
|
|
55
64
|
var tokens = /* @__PURE__ */ new Map(
|
|
56
|
-
/* @__PURE__ */ [...clockAgnostic, ...clock24, ...clock12].map((format) => {
|
|
65
|
+
/* @__PURE__ */ [...clockAgnostic, ...clock24, ...clock12, ...fractionalSeconds].map((format) => {
|
|
57
66
|
return [format[0], format];
|
|
58
67
|
})
|
|
59
68
|
);
|
|
60
69
|
var dayPeriodMap = /* @__PURE__ */ new Map();
|
|
61
|
-
var styles = [
|
|
62
|
-
"full",
|
|
63
|
-
"long",
|
|
64
|
-
"medium",
|
|
65
|
-
"short"
|
|
66
|
-
];
|
|
70
|
+
var styles = ["full", "long", "medium", "short"];
|
|
67
71
|
var two = (n) => String(n).padStart(2, "0");
|
|
68
72
|
var four = (n) => String(n).padStart(2, "0");
|
|
69
73
|
function normStr(part) {
|
|
@@ -76,8 +80,7 @@ function fill(inputDate, parts, locale, genitive = false, offset = null) {
|
|
|
76
80
|
const partMap = createPartMap(inputDate, parts, locale, genitive);
|
|
77
81
|
const d = date(inputDate);
|
|
78
82
|
function value({ partName, partValue, token }) {
|
|
79
|
-
if (partName === "literal")
|
|
80
|
-
return partValue;
|
|
83
|
+
if (partName === "literal") return partValue;
|
|
81
84
|
const value2 = partMap[partName];
|
|
82
85
|
if (partName === "hour" && token === "H") {
|
|
83
86
|
return value2.replace(/^0/, "") || "0";
|
|
@@ -89,6 +92,9 @@ function fill(inputDate, parts, locale, genitive = false, offset = null) {
|
|
|
89
92
|
const p = ap(d.getUTCHours() < 12 ? "am" : "pm", locale);
|
|
90
93
|
return token === "A" ? p.toUpperCase() : p.toLowerCase();
|
|
91
94
|
}
|
|
95
|
+
if (partName === "fractionalSecond") {
|
|
96
|
+
return String(d.getUTCMilliseconds()).padStart(3, "0");
|
|
97
|
+
}
|
|
92
98
|
if (partName === "timeZoneName") {
|
|
93
99
|
return offset != null ? offset : minsToOffset(-1 * d.getTimezoneOffset(), token);
|
|
94
100
|
}
|
|
@@ -114,8 +120,7 @@ function createPartMap(inputDate, parts, locale, genitive = false) {
|
|
|
114
120
|
preciseLocale,
|
|
115
121
|
requestedParts.reduce(
|
|
116
122
|
(options, part) => {
|
|
117
|
-
if (part.partName === "literal")
|
|
118
|
-
return options;
|
|
123
|
+
if (part.partName === "literal") return options;
|
|
119
124
|
if (genitive && genitiveTokens.includes(part.token)) {
|
|
120
125
|
genitiveParts.push(part);
|
|
121
126
|
}
|
|
@@ -142,9 +147,7 @@ function createPartMap(inputDate, parts, locale, genitive = false) {
|
|
|
142
147
|
}).formatToParts(d).map(normStr);
|
|
143
148
|
break;
|
|
144
149
|
}
|
|
145
|
-
const genitiveFormattedPart = formattedParts.find(
|
|
146
|
-
(p) => p.type === part.partName
|
|
147
|
-
);
|
|
150
|
+
const genitiveFormattedPart = formattedParts.find((p) => p.type === part.partName);
|
|
148
151
|
const index = valueParts.findIndex((p) => p.type === part.partName);
|
|
149
152
|
if (genitiveFormattedPart && index > -1) {
|
|
150
153
|
valueParts[index] = genitiveFormattedPart;
|
|
@@ -152,50 +155,51 @@ function createPartMap(inputDate, parts, locale, genitive = false) {
|
|
|
152
155
|
}
|
|
153
156
|
}
|
|
154
157
|
}
|
|
155
|
-
if (hour12.length)
|
|
156
|
-
|
|
157
|
-
if (hour24.length)
|
|
158
|
-
addValues(hour24);
|
|
158
|
+
if (hour12.length) addValues(hour12, true);
|
|
159
|
+
if (hour24.length) addValues(hour24);
|
|
159
160
|
return valueParts.reduce((map, part) => {
|
|
160
161
|
map[part.type] = part.value;
|
|
161
162
|
return map;
|
|
162
163
|
}, {});
|
|
163
164
|
}
|
|
164
|
-
function
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
);
|
|
169
|
-
const
|
|
170
|
-
const sign = timeDiffInMins < 0 ? "-" : "+";
|
|
165
|
+
function secsToOffset(totalSecs, token = "Z") {
|
|
166
|
+
const sign = totalSecs < 0 ? "-" : "+";
|
|
167
|
+
const absSecs = Math.abs(totalSecs);
|
|
168
|
+
const hours = String(Math.floor(absSecs / 3600)).padStart(2, "0");
|
|
169
|
+
const mins = String(Math.floor(absSecs % 3600 / 60)).padStart(2, "0");
|
|
170
|
+
const secs = Math.round(absSecs % 60);
|
|
171
171
|
if (token === "ZZ") {
|
|
172
|
-
return `${sign}${hours}${mins}`;
|
|
172
|
+
return secs === 0 ? `${sign}${hours}${mins}` : `${sign}${hours}${mins}${String(secs).padStart(2, "0")}`;
|
|
173
173
|
}
|
|
174
|
-
return `${sign}${hours}:${mins}`;
|
|
174
|
+
return secs === 0 ? `${sign}${hours}:${mins}` : `${sign}${hours}:${mins}:${String(secs).padStart(2, "0")}`;
|
|
175
175
|
}
|
|
176
|
-
function
|
|
176
|
+
function minsToOffset(timeDiffInMins, token = "Z") {
|
|
177
|
+
return secsToOffset(timeDiffInMins * 60, token);
|
|
178
|
+
}
|
|
179
|
+
function offsetToSecs(offset, token) {
|
|
177
180
|
validOffset(offset, token);
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
const match = offset.match(/([+-])([0-3][0-9]):?([0-5][0-9])(?::?([0-5][0-9]))?/);
|
|
182
|
+
const [_, sign, hours, mins, secs = "0"] = match;
|
|
183
|
+
const totalSecs = Number(hours) * 3600 + Number(mins) * 60 + Number(secs);
|
|
184
|
+
return sign === "+" ? totalSecs : -totalSecs;
|
|
185
|
+
}
|
|
186
|
+
function offsetToMins(offset, token) {
|
|
187
|
+
return Math.round(offsetToSecs(offset, token) / 60);
|
|
183
188
|
}
|
|
184
189
|
function validOffset(offset, token = "Z") {
|
|
185
190
|
const valid = ((token2) => {
|
|
186
191
|
switch (token2) {
|
|
187
192
|
case "Z":
|
|
188
|
-
return /^([+-])[0-3][0-9]:[0-
|
|
193
|
+
return /^([+-])[0-3][0-9]:[0-5][0-9](?::[0-5][0-9])?$/.test(offset);
|
|
189
194
|
case "ZZ":
|
|
190
|
-
return /^([+-])[0-3][0-9][0-
|
|
195
|
+
return /^([+-])[0-3][0-9][0-5][0-9](?:[0-5][0-9])?$/.test(offset);
|
|
191
196
|
}
|
|
192
197
|
})(token);
|
|
193
|
-
if (!valid)
|
|
194
|
-
throw new Error(`Invalid offset: ${offset}`);
|
|
198
|
+
if (!valid) throw new Error(`Invalid offset: ${offset}`);
|
|
195
199
|
return offset;
|
|
196
200
|
}
|
|
197
201
|
function escapeTokens(str) {
|
|
198
|
-
return clockAgnostic.concat(clock24).concat(clock12).sort((a, b) => a[0].length > b[0].length ? 1 : -1).reduce((target, part) => {
|
|
202
|
+
return clockAgnostic.concat(clock24).concat(clock12).concat(fractionalSeconds).sort((a, b) => a[0].length > b[0].length ? 1 : -1).reduce((target, part) => {
|
|
199
203
|
return target.replace(part[0], `\\${part[0]}`);
|
|
200
204
|
}, str);
|
|
201
205
|
}
|
|
@@ -209,10 +213,8 @@ function validate(parts) {
|
|
|
209
213
|
throw new Error(`Numbers in format (${part.partValue}).`);
|
|
210
214
|
}
|
|
211
215
|
if (lastPart && lastPart.partName !== "literal" && part.partName !== "literal") {
|
|
212
|
-
if (!(lastPart.token in fixedLength) && !(part.token in fixedLength) && !(isNumeric(lastPart) && part.token.toLowerCase() === "a")) {
|
|
213
|
-
throw new Error(
|
|
214
|
-
`Illegal adjacent tokens (${lastPart.token}, ${part.token})`
|
|
215
|
-
);
|
|
216
|
+
if (!(lastPart.token in fixedLength) && !(part.token in fixedLength) && !(isNumeric(lastPart) && part.token.toLowerCase() === "a") && lastPart.token !== "SSS") {
|
|
217
|
+
throw new Error(`Illegal adjacent tokens (${lastPart.token}, ${part.token})`);
|
|
216
218
|
}
|
|
217
219
|
}
|
|
218
220
|
lastPart = part;
|
|
@@ -235,6 +237,7 @@ export {
|
|
|
235
237
|
fixedLength,
|
|
236
238
|
fixedLengthByOffset,
|
|
237
239
|
four,
|
|
240
|
+
fractionalSeconds,
|
|
238
241
|
genitiveTokens,
|
|
239
242
|
getOffsetFormat,
|
|
240
243
|
isNumeric,
|
|
@@ -242,6 +245,8 @@ export {
|
|
|
242
245
|
minsToOffset,
|
|
243
246
|
normStr,
|
|
244
247
|
offsetToMins,
|
|
248
|
+
offsetToSecs,
|
|
249
|
+
secsToOffset,
|
|
245
250
|
specDate,
|
|
246
251
|
styles,
|
|
247
252
|
tokens,
|
package/dist/common.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/common.ts"],"sourcesContent":["import { date } from \"./date\"\nimport { ap } from \"./ap\"\nimport type {\n DateInput,\n NamedFormats,\n FormatPattern,\n FormatStyle,\n Part,\n FilledPart,\n Format,\n} from \"./types\"\n\n/**\n * A date to use for determining various spec details.\n */\nexport const specDate = \"1999-03-04T02:05:01.000Z\"\n\n/**\n * A cache of Intl tokens and their respective formats.\n */\nexport const memoParts: Map<string, NamedFormats> = new Map()\n\n/**\n * Clock agnostic time format patterns.\n */\nexport const clockAgnostic: FormatPattern[] = [\n [\"YYYY\", { year: \"numeric\" }],\n [\"YY\", { year: \"2-digit\" }],\n [\"MMMM\", { month: \"long\" }],\n [\"MMM\", { month: \"short\" }],\n [\"MM\", { month: \"2-digit\" }],\n [\"M\", { month: \"numeric\" }],\n [\"DD\", { day: \"2-digit\" }],\n [\"D\", { day: \"numeric\" }],\n [\"dddd\", { weekday: \"long\" }],\n [\"ddd\", { weekday: \"short\" }],\n [\"d\", { weekday: \"narrow\" }],\n [\"mm\", { minute: \"2-digit\" }],\n [\"m\", { minute: \"numeric\" }],\n [\"ss\", { second: \"2-digit\" }],\n [\"s\", { second: \"numeric\" }],\n [\"ZZ\", { timeZoneName: \"long\" }],\n [\"Z\", { timeZoneName: \"short\" }],\n]\n\n/**\n * Timezone tokens.\n */\nconst timeZoneTokens = [\"Z\", \"ZZ\"] as const\n\n/**\n * Timezone token type.\n */\nexport type TimezoneToken = (typeof timeZoneTokens)[number]\n\n/**\n * 24 hour click format patterns.\n */\nexport const clock24: FormatPattern[] = [\n [\"HH\", { hour: \"2-digit\" }],\n [\"H\", { hour: \"numeric\" }],\n]\n\n/**\n * 12 hour format patterns.\n */\nexport const clock12: FormatPattern[] = [\n [\"hh\", { hour: \"2-digit\" }],\n [\"h\", { hour: \"numeric\" }],\n [\"a\", { dayPeriod: \"narrow\" }],\n [\"A\", { dayPeriod: \"narrow\" }],\n]\n\n/**\n * Tokens that have a fixed length.\n */\nexport const fixedLength = {\n DD: 2,\n HH: 2,\n MM: 2,\n YY: 2,\n YYYY: 4,\n hh: 2,\n mm: 2,\n ss: 2,\n}\n\n/**\n * token Z can have variable length depending on the actual value, so it's\n */\nexport function fixedLengthByOffset(offsetString: string): 6 | 5 {\n // starts with [+-]xx:xx\n if (/^[+-]\\d{2}:\\d{2}/.test(offsetString)) {\n return 6\n }\n\n // starts with [+-]xxxx\n if (/^[+-]\\d{4}/.test(offsetString)) {\n return 5\n }\n\n throw new Error(\"Invalid offset format\")\n}\n\n/**\n * Tokens that are genitive — in that they can have \"possession\" when used in\n * a date phrase, \"March’s 4th day\" (but not in english).\n *\n * When computing a range for these, the range can be either genitive or not.\n * The same is true for parsing dates containing these tokens.\n */\nexport const genitiveTokens = [\"MMMM\", \"MMM\", \"dddd\", \"ddd\"]\n\n/**\n * A map of FormatPattern tuples to their respective token.\n */\nexport const tokens = /* @__PURE__ */ new Map(\n /* @__PURE__ */ [...clockAgnostic, ...clock24, ...clock12].map((format) => {\n return [format[0], format]\n })\n)\n\n/**\n * A map of locale’s am/pm.\n */\nexport const dayPeriodMap: Map<string, { am?: string; pm?: string }> = new Map()\n\n/**\n * An array of all available date styles.\n */\nexport const styles: ReadonlyArray<FormatStyle> = [\n \"full\",\n \"long\",\n \"medium\",\n \"short\",\n]\n\n/**\n * Creates a leading zero string of 2 digits.\n * @param n - A number.\n */\nexport const two = (n: number) => String(n).padStart(2, \"0\")\n/**\n * Creates a leading zero string of 4 digits.\n * @param n - A number.\n */\nexport const four = (n: number) => String(n).padStart(2, \"0\")\n\n/**\n * Normalizes a given part to NFKC.\n * @param part - The part to normalize.\n */\nexport function normStr(\n part: Intl.DateTimeFormatPart\n): Intl.DateTimeFormatPart {\n if (part.type === \"literal\") {\n part.value = part.value.normalize(\"NFKC\")\n }\n return part\n}\n\n/**\n * Returns the parts filled with pertinent values.\n * @param inputDate - The date to fill parts for\n * @param parts - An array of parts to fill\n * @param locale - The locale to fill with.\n * @param genitive - Whether to use genitive tokens values or not.\n * @param offset - The explicit offset to fill with (ignores the date’s true offset).\n */\nexport function fill(\n inputDate: DateInput,\n parts: Part[],\n locale: string,\n genitive = false,\n offset: string | null = null\n): FilledPart[] {\n const partMap = createPartMap(inputDate, parts, locale, genitive)\n const d = date(inputDate)\n\n /**\n * Not all values get returned \"properly\" as our tokens would suggest. For\n * example, at times Intl returns leading zeros when it shouldn't. This fn\n * is used to clean up those irregular values.\n * @param param - Part\n */\n function value({ partName, partValue, token }: Part) {\n if (partName === \"literal\") return partValue\n const value = partMap[partName]\n if (partName === \"hour\" && token === \"H\") {\n return value.replace(/^0/, \"\") || \"0\"\n }\n if ([\"mm\", \"ss\", \"MM\"].includes(token) && value.length === 1) {\n // Some tokens are supposed to have leading zeros, but Intl doesn't\n // always return them, depending on the locale and the format.\n return `0${value}`\n }\n if (partName === \"dayPeriod\") {\n const p = ap(d.getUTCHours() < 12 ? \"am\" : \"pm\", locale)\n return token === \"A\" ? p.toUpperCase() : p.toLowerCase()\n }\n if (partName === \"timeZoneName\") {\n return offset ?? minsToOffset(-1 * d.getTimezoneOffset(), token)\n }\n return value\n }\n\n return parts.map((part): FilledPart => {\n return {\n ...part,\n value: value(part),\n }\n })\n}\n\n/**\n * Creates a map of part names to their respective values.\n * @param inputDate - The date to format\n * @param parts - The individual parts the need to be formatted.\n * @param locale - The locale to format the parts with.\n * @param genitive - Whether to use genitive tokens values or not.\n */\nfunction createPartMap(\n inputDate: DateInput,\n parts: Part[],\n locale: string,\n genitive = false\n): Record<keyof Intl.DateTimeFormatPartTypesRegistry, string> {\n const d = date(inputDate)\n const hour12 = parts.filter((part) => part.hour12)\n const hour24 = parts.filter((part) => !part.hour12)\n const valueParts: Intl.DateTimeFormatPart[] = []\n const genitiveParts: Part[] = []\n\n function addValues(requestedParts: Part[], hour12 = false) {\n const preciseLocale = `${locale}-u-hc-${hour12 ? \"h12\" : \"h23\"}`\n valueParts.push(\n ...new Intl.DateTimeFormat(\n preciseLocale,\n requestedParts.reduce(\n (options, part) => {\n if (part.partName === \"literal\") return options\n // Side effect! Genitive parts get shoved into a separate array.\n if (genitive && genitiveTokens.includes(part.token)) {\n genitiveParts.push(part)\n }\n return Object.assign(options, part.option)\n },\n { timeZone: \"UTC\" } as Intl.DateTimeFormatOptions\n )\n )\n .formatToParts(d)\n .map(normStr)\n )\n if (genitive && genitiveParts.length) {\n for (const part of genitiveParts) {\n let formattedParts: Intl.DateTimeFormatPart[] = []\n switch (part.token) {\n case \"MMMM\":\n formattedParts = new Intl.DateTimeFormat(preciseLocale, {\n dateStyle: \"long\",\n timeZone: \"UTC\",\n })\n .formatToParts(d)\n .map(normStr)\n break\n case \"MMM\":\n formattedParts = new Intl.DateTimeFormat(preciseLocale, {\n dateStyle: \"medium\",\n timeZone: \"UTC\",\n })\n .formatToParts(d)\n .map(normStr)\n break\n }\n const genitiveFormattedPart = formattedParts.find(\n (p) => p.type === part.partName\n )\n const index = valueParts.findIndex((p) => p.type === part.partName)\n if (genitiveFormattedPart && index > -1) {\n valueParts[index] = genitiveFormattedPart\n }\n }\n }\n }\n\n if (hour12.length) addValues(hour12, true)\n if (hour24.length) addValues(hour24)\n\n return valueParts.reduce((map, part) => {\n map[part.type] = part.value\n return map\n }, {} as Record<keyof Intl.DateTimeFormatPartTypesRegistry, string>)\n}\n\n/**\n * Converts minutes (300) to an ISO8601 compatible offset (+0400 or +04:00).\n * @param timeDiffInMins - The difference in minutes between two timezones.\n * @returns\n */\nexport function minsToOffset(\n timeDiffInMins: number,\n token: string = \"Z\"\n): string {\n const hours = String(Math.floor(Math.abs(timeDiffInMins / 60))).padStart(\n 2,\n \"0\"\n )\n const mins = String(Math.abs(timeDiffInMins % 60)).padStart(2, \"0\")\n const sign = timeDiffInMins < 0 ? \"-\" : \"+\"\n\n if (token === \"ZZ\") {\n return `${sign}${hours}${mins}`\n }\n\n return `${sign}${hours}:${mins}`\n}\n\n/**\n * Converts an offset (-0500) to minutes (-300).\n * @param offset - The offset to convert to minutes.\n * @param token - The timezone token format.\n */\nexport function offsetToMins(offset: string, token: TimezoneToken): number {\n validOffset(offset, token)\n const [_, sign, hours, mins] = offset.match(\n /([+-])([0-3][0-9]):?([0-6][0-9])/\n )!\n const offsetInMins = Number(hours) * 60 + Number(mins)\n return sign === \"+\" ? offsetInMins : -offsetInMins\n}\n\n/**\n * Validates that an offset is valid according to the format:\n * [+-]HHmm or [+-]HH:mm\n * @param offset - The offset to validate.\n * @param token - The timezone token format.\n */\nexport function validOffset(offset: string, token: TimezoneToken = \"Z\") {\n const valid = ((token: TimezoneToken): boolean => {\n switch (token) {\n case \"Z\":\n return /^([+-])[0-3][0-9]:[0-6][0-9]$/.test(offset)\n case \"ZZ\":\n return /^([+-])[0-3][0-9][0-6][0-9]$/.test(offset)\n }\n })(token)\n\n if (!valid) throw new Error(`Invalid offset: ${offset}`)\n return offset\n}\n\n/**\n * Given a string of tokens, escape any characters that are tokens.\n * @param str - The string to escape tokens in.\n * @returns The escaped string.\n */\nexport function escapeTokens(str: string): string {\n return clockAgnostic\n .concat(clock24)\n .concat(clock12)\n .sort((a, b) => (a[0].length > b[0].length ? 1 : -1))\n .reduce((target, part) => {\n return target.replace(part[0], `\\\\${part[0]}`)\n }, str)\n}\n\n/**\n * Checks if a given part should have a numeric value.\n * @param part - A part to check\n */\nexport function isNumeric(part: Part) {\n return [\"numeric\", \"2-digit\"].includes(part.partValue)\n}\n\n/**\n * Validates that an array of Parts can be parsed.\n * @param parts - Parts to validate for parsing ability.\n */\nexport function validate(parts: Part[]): Part[] | never {\n let lastPart: Part | undefined = undefined\n for (const part of parts) {\n if (part.partName === \"literal\" && !isNaN(parseFloat(part.partValue))) {\n throw new Error(`Numbers in format (${part.partValue}).`)\n }\n if (\n lastPart &&\n lastPart.partName !== \"literal\" &&\n part.partName !== \"literal\"\n ) {\n if (\n !(lastPart.token in fixedLength) &&\n !(part.token in fixedLength) &&\n !(isNumeric(lastPart) && part.token.toLowerCase() === \"a\")\n ) {\n throw new Error(\n `Illegal adjacent tokens (${lastPart.token}, ${part.token})`\n )\n }\n }\n lastPart = part\n }\n return parts\n}\n\n/**\n * Returns the timezone token format from a given format.\n * @param format - The format to check.\n * @returns The timezone token format (\"Z\" or \"ZZ\").\n */\nexport function getOffsetFormat(format: Format): TimezoneToken {\n if (typeof format === \"string\") {\n return format.includes(\"ZZ\") ? \"ZZ\" : \"Z\"\n }\n return \"time\" in format && format.time === \"full\" ? \"Z\" : \"ZZ\"\n}\n"],"mappings":"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","names":["value","hour12","token"]}
|
|
1
|
+
{"version":3,"sources":["../src/common.ts"],"sourcesContent":["import { date } from \"./date\"\nimport { ap } from \"./ap\"\nimport type {\n DateInput,\n NamedFormats,\n FormatPattern,\n FormatStyle,\n Part,\n FilledPart,\n Format,\n MaybeDateInput,\n ExtendedPartTypes,\n} from \"./types\"\n\n/**\n * A date to use for determining various spec details.\n */\nexport const specDate = \"1999-03-04T02:05:01.000Z\"\n\n/**\n * A cache of Intl tokens and their respective formats.\n */\nexport const memoParts: Map<string, NamedFormats> = new Map()\n\n/**\n * Clock agnostic time format patterns.\n */\nexport const clockAgnostic: FormatPattern[] = [\n [\"YYYY\", { year: \"numeric\" }],\n [\"YY\", { year: \"2-digit\" }],\n [\"MMMM\", { month: \"long\" }],\n [\"MMM\", { month: \"short\" }],\n [\"MM\", { month: \"2-digit\" }],\n [\"M\", { month: \"numeric\" }],\n [\"DD\", { day: \"2-digit\" }],\n [\"D\", { day: \"numeric\" }],\n [\"dddd\", { weekday: \"long\" }],\n [\"ddd\", { weekday: \"short\" }],\n [\"d\", { weekday: \"narrow\" }],\n [\"mm\", { minute: \"2-digit\" }],\n [\"m\", { minute: \"numeric\" }],\n [\"ss\", { second: \"2-digit\" }],\n [\"s\", { second: \"numeric\" }],\n [\"ZZ\", { timeZoneName: \"long\" }],\n [\"Z\", { timeZoneName: \"short\" }],\n]\n\n/**\n * Timezone tokens.\n */\nconst timeZoneTokens = [\"Z\", \"ZZ\"] as const\n\n/**\n * Timezone token type.\n */\nexport type TimezoneToken = (typeof timeZoneTokens)[number]\n\n/**\n * 24 hour click format patterns.\n */\nexport const clock24: FormatPattern[] = [\n [\"HH\", { hour: \"2-digit\" }],\n [\"H\", { hour: \"numeric\" }],\n]\n\n/**\n * 12 hour format patterns.\n */\nexport const clock12: FormatPattern[] = [\n [\"hh\", { hour: \"2-digit\" }],\n [\"h\", { hour: \"numeric\" }],\n [\"a\", { dayPeriod: \"narrow\" }],\n [\"A\", { dayPeriod: \"narrow\" }],\n]\n\n/**\n * Fractional seconds patterns.\n */\nexport const fractionalSeconds: FormatPattern[] = [\n [\"SSS\", { fractionalSecond: \"3-digit\" }],\n]\n\n/**\n * Tokens that have a fixed length.\n */\nexport const fixedLength = {\n DD: 2,\n HH: 2,\n MM: 2,\n YY: 2,\n YYYY: 4,\n hh: 2,\n mm: 2,\n ss: 2,\n}\n\n/**\n * Determines the length of a timezone offset string.\n * Supports offsets with optional seconds component.\n */\nexport function fixedLengthByOffset(offsetString: string): 9 | 8 | 6 | 5 {\n // starts with [+-]xx:xx:xx (9 chars, Z format with seconds)\n if (/^[+-]\\d{2}:\\d{2}:\\d{2}/.test(offsetString)) {\n return 9\n }\n\n // starts with [+-]xxxxxx (8 chars, ZZ format with seconds)\n if (/^[+-]\\d{6}/.test(offsetString)) {\n return 8\n }\n\n // starts with [+-]xx:xx (6 chars, Z format)\n if (/^[+-]\\d{2}:\\d{2}/.test(offsetString)) {\n return 6\n }\n\n // starts with [+-]xxxx (5 chars, ZZ format)\n if (/^[+-]\\d{4}/.test(offsetString)) {\n return 5\n }\n\n throw new Error(\"Invalid offset format\")\n}\n\n/**\n * Tokens that are genitive — in that they can have \"possession\" when used in\n * a date phrase, \"March’s 4th day\" (but not in english).\n *\n * When computing a range for these, the range can be either genitive or not.\n * The same is true for parsing dates containing these tokens.\n */\nexport const genitiveTokens = [\"MMMM\", \"MMM\", \"dddd\", \"ddd\"]\n\n/**\n * A map of FormatPattern tuples to their respective token.\n */\nexport const tokens = /* @__PURE__ */ new Map(\n /* @__PURE__ */ [...clockAgnostic, ...clock24, ...clock12, ...fractionalSeconds].map((format) => {\n return [format[0], format]\n })\n)\n\n/**\n * A map of locale’s am/pm.\n */\nexport const dayPeriodMap: Map<string, { am?: string; pm?: string }> = new Map()\n\n/**\n * An array of all available date styles.\n */\nexport const styles: ReadonlyArray<FormatStyle> = [\"full\", \"long\", \"medium\", \"short\"]\n\n/**\n * Creates a leading zero string of 2 digits.\n * @param n - A number.\n */\nexport const two = (n: number) => String(n).padStart(2, \"0\")\n/**\n * Creates a leading zero string of 4 digits.\n * @param n - A number.\n */\nexport const four = (n: number) => String(n).padStart(2, \"0\")\n\n/**\n * Normalizes a given part to NFKC.\n * @param part - The part to normalize.\n */\nexport function normStr(part: Intl.DateTimeFormatPart): Intl.DateTimeFormatPart {\n if (part.type === \"literal\") {\n part.value = part.value.normalize(\"NFKC\")\n }\n return part\n}\n\n/**\n * Returns the parts filled with pertinent values.\n * @param [inputDate] - The date to fill parts for\n * @param parts - An array of parts to fill\n * @param locale - The locale to fill with.\n * @param genitive - Whether to use genitive tokens values or not.\n * @param offset - The explicit offset to fill with (ignores the date’s true offset).\n */\nexport function fill(\n inputDate: MaybeDateInput,\n parts: Part[],\n locale: string,\n genitive = false,\n offset: string | null = null\n): FilledPart[] {\n const partMap = createPartMap(inputDate, parts, locale, genitive)\n const d = date(inputDate)\n\n /**\n * Not all values get returned \"properly\" as our tokens would suggest. For\n * example, at times Intl returns leading zeros when it shouldn't. This fn\n * is used to clean up those irregular values.\n * @param param - Part\n */\n function value({ partName, partValue, token }: Part) {\n if (partName === \"literal\") return partValue\n const value = partMap[partName]\n if (partName === \"hour\" && token === \"H\") {\n return value.replace(/^0/, \"\") || \"0\"\n }\n if ([\"mm\", \"ss\", \"MM\"].includes(token) && value.length === 1) {\n // Some tokens are supposed to have leading zeros, but Intl doesn't\n // always return them, depending on the locale and the format.\n return `0${value}`\n }\n if (partName === \"dayPeriod\") {\n const p = ap(d.getUTCHours() < 12 ? \"am\" : \"pm\", locale)\n return token === \"A\" ? p.toUpperCase() : p.toLowerCase()\n }\n if (partName === \"fractionalSecond\") {\n return String(d.getUTCMilliseconds()).padStart(3, \"0\")\n }\n if (partName === \"timeZoneName\") {\n return offset ?? minsToOffset(-1 * d.getTimezoneOffset(), token)\n }\n return value\n }\n\n return parts.map((part): FilledPart => {\n return {\n ...part,\n value: value(part),\n }\n })\n}\n\n/**\n * Creates a map of part names to their respective values.\n * @param [inputDate] - The date to format\n * @param parts - The individual parts the need to be formatted.\n * @param locale - The locale to format the parts with.\n * @param genitive - Whether to use genitive tokens values or not.\n */\nfunction createPartMap(\n inputDate: MaybeDateInput,\n parts: Part[],\n locale: string,\n genitive = false\n): Record<ExtendedPartTypes, string> {\n const d = date(inputDate)\n const hour12 = parts.filter((part) => part.hour12)\n const hour24 = parts.filter((part) => !part.hour12)\n const valueParts: Intl.DateTimeFormatPart[] = []\n const genitiveParts: Part[] = []\n\n function addValues(requestedParts: Part[], hour12 = false) {\n const preciseLocale = `${locale}-u-hc-${hour12 ? \"h12\" : \"h23\"}`\n valueParts.push(\n ...new Intl.DateTimeFormat(\n preciseLocale,\n requestedParts.reduce(\n (options, part) => {\n if (part.partName === \"literal\") return options\n // Side effect! Genitive parts get shoved into a separate array.\n if (genitive && genitiveTokens.includes(part.token)) {\n genitiveParts.push(part)\n }\n return Object.assign(options, part.option)\n },\n { timeZone: \"UTC\" } as Intl.DateTimeFormatOptions\n )\n )\n .formatToParts(d)\n .map(normStr)\n )\n if (genitive && genitiveParts.length) {\n for (const part of genitiveParts) {\n let formattedParts: Intl.DateTimeFormatPart[] = []\n switch (part.token) {\n case \"MMMM\":\n formattedParts = new Intl.DateTimeFormat(preciseLocale, {\n dateStyle: \"long\",\n timeZone: \"UTC\",\n })\n .formatToParts(d)\n .map(normStr)\n break\n case \"MMM\":\n formattedParts = new Intl.DateTimeFormat(preciseLocale, {\n dateStyle: \"medium\",\n timeZone: \"UTC\",\n })\n .formatToParts(d)\n .map(normStr)\n break\n }\n const genitiveFormattedPart = formattedParts.find((p) => p.type === part.partName)\n const index = valueParts.findIndex((p) => p.type === part.partName)\n if (genitiveFormattedPart && index > -1) {\n valueParts[index] = genitiveFormattedPart\n }\n }\n }\n }\n\n if (hour12.length) addValues(hour12, true)\n if (hour24.length) addValues(hour24)\n\n return valueParts.reduce((map, part) => {\n map[part.type as ExtendedPartTypes] = part.value\n return map\n }, {} as Record<ExtendedPartTypes, string>)\n}\n\n/**\n * Converts total seconds to an ISO8601 compatible offset (+04:00 or +0400).\n * Only includes seconds in output if they are non-zero.\n * @param totalSecs - The total offset in seconds (can be negative).\n * @param token - \"Z\" for +HH:mm[:ss] or \"ZZ\" for +HHmm[ss]\n */\nexport function secsToOffset(totalSecs: number, token: string = \"Z\"): string {\n const sign = totalSecs < 0 ? \"-\" : \"+\"\n const absSecs = Math.abs(totalSecs)\n const hours = String(Math.floor(absSecs / 3600)).padStart(2, \"0\")\n const mins = String(Math.floor((absSecs % 3600) / 60)).padStart(2, \"0\")\n const secs = Math.round(absSecs % 60)\n\n if (token === \"ZZ\") {\n return secs === 0\n ? `${sign}${hours}${mins}`\n : `${sign}${hours}${mins}${String(secs).padStart(2, \"0\")}`\n }\n return secs === 0\n ? `${sign}${hours}:${mins}`\n : `${sign}${hours}:${mins}:${String(secs).padStart(2, \"0\")}`\n}\n\n/**\n * Converts minutes (300) to an ISO8601 compatible offset (+0400 or +04:00).\n * @param timeDiffInMins - The difference in minutes between two timezones.\n * @returns\n */\nexport function minsToOffset(timeDiffInMins: number, token: string = \"Z\"): string {\n return secsToOffset(timeDiffInMins * 60, token)\n}\n\n/**\n * Converts an offset (-05:32:11 or -053211) to total seconds.\n * Supports offsets with optional seconds component.\n * @param offset - The offset to convert to seconds.\n * @param token - The timezone token format.\n */\nexport function offsetToSecs(offset: string, token: TimezoneToken): number {\n validOffset(offset, token)\n const match = offset.match(/([+-])([0-3][0-9]):?([0-5][0-9])(?::?([0-5][0-9]))?/)!\n const [_, sign, hours, mins, secs = \"0\"] = match\n const totalSecs = Number(hours) * 3600 + Number(mins) * 60 + Number(secs)\n return sign === \"+\" ? totalSecs : -totalSecs\n}\n\n/**\n * Converts an offset (-0500) to minutes (-300).\n * @param offset - The offset to convert to minutes.\n * @param token - The timezone token format.\n */\nexport function offsetToMins(offset: string, token: TimezoneToken): number {\n return Math.round(offsetToSecs(offset, token) / 60)\n}\n\n/**\n * Validates that an offset is valid according to the format:\n * [+-]HH:mm or [+-]HH:mm:ss (Z token)\n * [+-]HHmm or [+-]HHmmss (ZZ token)\n * @param offset - The offset to validate.\n * @param token - The timezone token format.\n */\nexport function validOffset(offset: string, token: TimezoneToken = \"Z\") {\n const valid = ((token: TimezoneToken): boolean => {\n switch (token) {\n case \"Z\":\n return /^([+-])[0-3][0-9]:[0-5][0-9](?::[0-5][0-9])?$/.test(offset)\n case \"ZZ\":\n return /^([+-])[0-3][0-9][0-5][0-9](?:[0-5][0-9])?$/.test(offset)\n }\n })(token)\n\n if (!valid) throw new Error(`Invalid offset: ${offset}`)\n return offset\n}\n\n/**\n * Given a string of tokens, escape any characters that are tokens.\n * @param str - The string to escape tokens in.\n * @returns The escaped string.\n */\nexport function escapeTokens(str: string): string {\n return clockAgnostic\n .concat(clock24)\n .concat(clock12)\n .concat(fractionalSeconds)\n .sort((a, b) => (a[0].length > b[0].length ? 1 : -1))\n .reduce((target, part) => {\n return target.replace(part[0], `\\\\${part[0]}`)\n }, str)\n}\n\n/**\n * Checks if a given part should have a numeric value.\n * @param part - A part to check\n */\nexport function isNumeric(part: Part) {\n return [\"numeric\", \"2-digit\"].includes(part.partValue)\n}\n\n/**\n * Validates that an array of Parts can be parsed.\n * @param parts - Parts to validate for parsing ability.\n */\nexport function validate(parts: Part[]): Part[] | never {\n let lastPart: Part | undefined = undefined\n for (const part of parts) {\n if (part.partName === \"literal\" && !isNaN(parseFloat(part.partValue))) {\n throw new Error(`Numbers in format (${part.partValue}).`)\n }\n if (lastPart && lastPart.partName !== \"literal\" && part.partName !== \"literal\") {\n if (\n !(lastPart.token in fixedLength) &&\n !(part.token in fixedLength) &&\n !(isNumeric(lastPart) && part.token.toLowerCase() === \"a\") &&\n lastPart.token !== \"SSS\" // SSS can be followed by anything (greedy digit consumer)\n ) {\n throw new Error(`Illegal adjacent tokens (${lastPart.token}, ${part.token})`)\n }\n }\n lastPart = part\n }\n return parts\n}\n\n/**\n * Returns the timezone token format from a given format.\n * @param format - The format to check.\n * @returns The timezone token format (\"Z\" or \"ZZ\").\n */\nexport function getOffsetFormat(format: Format): TimezoneToken {\n if (typeof format === \"string\") {\n return format.includes(\"ZZ\") ? \"ZZ\" : \"Z\"\n }\n return \"time\" in format && format.time === \"full\" ? \"Z\" : \"ZZ\"\n}\n"],"mappings":"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","names":["value","hour12","token"]}
|
package/dist/date.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MaybeDateInput } from './types.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A date to parse.
|
|
5
5
|
* @param date - A Date object or an ISO 8601 date.
|
|
6
6
|
*/
|
|
7
|
-
declare function date(date?:
|
|
7
|
+
declare function date(date?: MaybeDateInput): Date;
|
|
8
8
|
|
|
9
9
|
export { date };
|
package/dist/date.mjs
CHANGED
package/dist/date.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/date.ts"],"sourcesContent":["import { iso8601, iso8601Match } from \"./iso8601\"\nimport type {
|
|
1
|
+
{"version":3,"sources":["../src/date.ts"],"sourcesContent":["import { iso8601, iso8601Match } from \"./iso8601\"\nimport type { MaybeDateInput } from \"./types\"\n\n/**\n * Normalizes a \"short\" date like 2012-01-01 to 2012-01-01T00:00:00 to prevent\n * automatic coercion to UTC.\n * @param date - A string representation of the date.\n */\nfunction normalize(date: string) {\n const matches = date.match(iso8601Match)\n if (matches && typeof matches[4] === \"undefined\") {\n return (date += \"T00:00:00\")\n }\n return date\n}\n\n/**\n * A date to parse.\n * @param date - A Date object or an ISO 8601 date.\n */\nexport function date(date?: MaybeDateInput): Date {\n if (!date) {\n date = new Date()\n }\n if (date instanceof Date) {\n return new Date(date)\n }\n date = date.trim()\n if (iso8601(date)) {\n return new Date(normalize(date))\n }\n throw new Error(`Non ISO 8601 compliant date (${date}).`)\n}\n"],"mappings":";AAAA,SAAS,SAAS,oBAAoB;AAQtC,SAAS,UAAUA,OAAc;AAC/B,QAAM,UAAUA,MAAK,MAAM,YAAY;AACvC,MAAI,WAAW,OAAO,QAAQ,CAAC,MAAM,aAAa;AAChD,WAAQA,SAAQ;AAAA,EAClB;AACA,SAAOA;AACT;AAMO,SAAS,KAAKA,OAA6B;AAChD,MAAI,CAACA,OAAM;AACT,IAAAA,QAAO,oBAAI,KAAK;AAAA,EAClB;AACA,MAAIA,iBAAgB,MAAM;AACxB,WAAO,IAAI,KAAKA,KAAI;AAAA,EACtB;AACA,EAAAA,QAAOA,MAAK,KAAK;AACjB,MAAI,QAAQA,KAAI,GAAG;AACjB,WAAO,IAAI,KAAK,UAAUA,KAAI,CAAC;AAAA,EACjC;AACA,QAAM,IAAI,MAAM,gCAAgCA,KAAI,IAAI;AAC1D;","names":["date"]}
|
package/dist/dayEnd.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MaybeDateInput } from './types.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns a Date object for end of the given day.
|
|
5
|
-
* @param inputDate - A string or
|
|
5
|
+
* @param [inputDate] - A string, Date object or nothing for the current day
|
|
6
6
|
*/
|
|
7
|
-
declare function dayEnd(inputDate
|
|
7
|
+
declare function dayEnd(inputDate?: MaybeDateInput): Date;
|
|
8
8
|
|
|
9
9
|
export { dayEnd };
|
package/dist/dayEnd.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dayEnd.ts"],"sourcesContent":["import { date } from \"./date\"\nimport type {
|
|
1
|
+
{"version":3,"sources":["../src/dayEnd.ts"],"sourcesContent":["import { date } from \"./date\"\nimport type { MaybeDateInput } from \"./types\"\n\n/**\n * Returns a Date object for end of the given day.\n * @param [inputDate] - A string, Date object or nothing for the current day\n */\nexport function dayEnd(inputDate?: MaybeDateInput): Date {\n const d = date(inputDate)\n d.setHours(23, 59, 59, 999)\n return d\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAOd,SAAS,OAAO,WAAkC;AACvD,QAAM,IAAI,KAAK,SAAS;AACxB,IAAE,SAAS,IAAI,IAAI,IAAI,GAAG;AAC1B,SAAO;AACT;","names":[]}
|
package/dist/dayOfYear.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MaybeDateInput } from './types.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Gets the what day of the year a given date is. For example, August 1st is
|
|
5
5
|
* the 213th day of the year on non- years and 214th on leap years.
|
|
6
|
-
* @param inputDate - The input date.
|
|
6
|
+
* @param [inputDate] - The input date or nothing for the current day.
|
|
7
7
|
*/
|
|
8
|
-
declare function dayOfYear(inputDate
|
|
8
|
+
declare function dayOfYear(inputDate?: MaybeDateInput): number;
|
|
9
9
|
|
|
10
10
|
export { dayOfYear };
|
package/dist/dayOfYear.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dayOfYear.ts"],"sourcesContent":["import { date } from \"./date\"\nimport type {
|
|
1
|
+
{"version":3,"sources":["../src/dayOfYear.ts"],"sourcesContent":["import { date } from \"./date\"\nimport type { MaybeDateInput } from \"./types\"\n\n/**\n * Gets the what day of the year a given date is. For example, August 1st is\n * the 213th day of the year on non- years and 214th on leap years.\n * @param [inputDate] - The input date or nothing for the current day.\n */\nexport function dayOfYear(inputDate?: MaybeDateInput): number {\n const d = date(inputDate)\n return Math.round(\n (new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0).getTime() -\n new Date(d.getFullYear(), 0, 0).getTime()) /\n 86400000\n )\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAQd,SAAS,UAAU,WAAoC;AAC5D,QAAM,IAAI,KAAK,SAAS;AACxB,SAAO,KAAK;AAAA,KACT,IAAI,KAAK,EAAE,YAAY,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,GAAG,GAAG,CAAC,EAAE,QAAQ,IAClE,IAAI,KAAK,EAAE,YAAY,GAAG,GAAG,CAAC,EAAE,QAAQ,KACxC;AAAA,EACJ;AACF;","names":[]}
|
package/dist/dayStart.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MaybeDateInput } from './types.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Returns a Date object for start of the given day.
|
|
5
|
-
* @param inputDate - A string or
|
|
5
|
+
* @param [inputDate] - A string, Date object or nothing for the current day
|
|
6
6
|
*/
|
|
7
|
-
declare function dayStart(inputDate
|
|
7
|
+
declare function dayStart(inputDate?: MaybeDateInput): Date;
|
|
8
8
|
|
|
9
9
|
export { dayStart };
|
package/dist/dayStart.mjs
CHANGED
package/dist/dayStart.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dayStart.ts"],"sourcesContent":["import { date } from \"./date\"\nimport type {
|
|
1
|
+
{"version":3,"sources":["../src/dayStart.ts"],"sourcesContent":["import { date } from \"./date\"\nimport type { MaybeDateInput } from \"./types\"\n\n/**\n * Returns a Date object for start of the given day.\n * @param [inputDate] - A string, Date object or nothing for the current day\n */\nexport function dayStart(inputDate?: MaybeDateInput): Date {\n const d = date(inputDate)\n d.setHours(0, 0, 0, 0)\n return d\n}\n"],"mappings":";AAAA,SAAS,YAAY;AAOd,SAAS,SAAS,WAAkC;AACzD,QAAM,IAAI,KAAK,SAAS;AACxB,IAAE,SAAS,GAAG,GAAG,GAAG,CAAC;AACrB,SAAO;AACT;","names":[]}
|
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Duration, DateInput, MaybeDateInput } from './types.js';
|
|
2
|
+
|
|
3
|
+
type DurationKey = keyof Duration;
|
|
4
|
+
/**
|
|
5
|
+
* Options for `diff` function
|
|
6
|
+
*/
|
|
7
|
+
interface DiffOptions {
|
|
8
|
+
/**
|
|
9
|
+
* whether the difference should be absolute (not negative)
|
|
10
|
+
*/
|
|
11
|
+
abs?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* units you want to skip, for example weeks
|
|
14
|
+
*/
|
|
15
|
+
skip?: DurationKey[] | Set<DurationKey>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns the difference between 2 dates in an object
|
|
19
|
+
* @param dateA - A date to compare with the right date
|
|
20
|
+
* @param [dateB] - A date to compare with the left date or nothing to compare with the current time
|
|
21
|
+
* @param [options] additional options
|
|
22
|
+
* @param [options.skip] units you want skip
|
|
23
|
+
* @param [options.abs] whether the difference should be absolute
|
|
24
|
+
* @returns an object which could be used with `Intl.DurationFormat.format'`
|
|
25
|
+
*/
|
|
26
|
+
declare function diff(dateA: DateInput, dateB?: MaybeDateInput, options?: DiffOptions): Duration;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the difference between 2 dates in an object
|
|
29
|
+
* @param [dateA] - A date to compare with the right date or null to compare with the current time
|
|
30
|
+
* @param dateB - A date to compare with the left date
|
|
31
|
+
* @param [options] additional options
|
|
32
|
+
* @param [options.skip] units you want skip
|
|
33
|
+
* @param [options.abs] whether the difference should be absolute
|
|
34
|
+
* @returns an object which could be used with `Intl.DurationFormat.format'`
|
|
35
|
+
*/
|
|
36
|
+
declare function diff(dateA: MaybeDateInput, dateB: DateInput, options?: DiffOptions): Duration;
|
|
37
|
+
|
|
38
|
+
export { type DiffOptions, diff };
|
package/dist/diff.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// src/diff.ts
|
|
2
|
+
import { addDay } from "./addDay.mjs";
|
|
3
|
+
import { addHour } from "./addHour.mjs";
|
|
4
|
+
import { addMinute } from "./addMinute.mjs";
|
|
5
|
+
import { addMonth } from "./addMonth.mjs";
|
|
6
|
+
import { addSecond } from "./addSecond.mjs";
|
|
7
|
+
import { addYear } from "./addYear.mjs";
|
|
8
|
+
import { date } from "./date.mjs";
|
|
9
|
+
import { diffDays } from "./diffDays.mjs";
|
|
10
|
+
import { diffHours } from "./diffHours.mjs";
|
|
11
|
+
import { diffMilliseconds } from "./diffMilliseconds.mjs";
|
|
12
|
+
import { diffMinutes } from "./diffMinutes.mjs";
|
|
13
|
+
import { diffMonths } from "./diffMonths.mjs";
|
|
14
|
+
import { diffSeconds } from "./diffSeconds.mjs";
|
|
15
|
+
import { diffWeeks } from "./diffWeeks.mjs";
|
|
16
|
+
import { diffYears } from "./diffYears.mjs";
|
|
17
|
+
function negateDuration(duration) {
|
|
18
|
+
const negated = {};
|
|
19
|
+
for (const unit of Object.keys(duration)) {
|
|
20
|
+
negated[unit] = -duration[unit];
|
|
21
|
+
}
|
|
22
|
+
return negated;
|
|
23
|
+
}
|
|
24
|
+
function calendarDiff(current, target, diffUnit, addUnit) {
|
|
25
|
+
let amount = diffUnit(current, target);
|
|
26
|
+
let next = addUnit(current, -amount);
|
|
27
|
+
while (amount > 0 && next < target) {
|
|
28
|
+
amount--;
|
|
29
|
+
next = addUnit(current, -amount);
|
|
30
|
+
}
|
|
31
|
+
return [amount, next];
|
|
32
|
+
}
|
|
33
|
+
function diff(dateA, dateB, options) {
|
|
34
|
+
let a = date(dateA);
|
|
35
|
+
let b = date(dateB);
|
|
36
|
+
if (a < b) {
|
|
37
|
+
const duration2 = diff(b, a, options);
|
|
38
|
+
return (options == null ? void 0 : options.abs) ? duration2 : negateDuration(duration2);
|
|
39
|
+
}
|
|
40
|
+
const skip = new Set(options == null ? void 0 : options.skip);
|
|
41
|
+
const duration = {};
|
|
42
|
+
if (!skip.has("years")) {
|
|
43
|
+
const [years, next] = calendarDiff(a, b, diffYears, addYear);
|
|
44
|
+
a = next;
|
|
45
|
+
if (years) duration.years = years;
|
|
46
|
+
}
|
|
47
|
+
if (!skip.has("months")) {
|
|
48
|
+
const [months, next] = calendarDiff(a, b, diffMonths, addMonth);
|
|
49
|
+
a = next;
|
|
50
|
+
if (months) duration.months = months;
|
|
51
|
+
}
|
|
52
|
+
if (!skip.has("weeks")) {
|
|
53
|
+
const weeks = diffWeeks(a, b);
|
|
54
|
+
a = addDay(a, -(weeks * 7));
|
|
55
|
+
if (weeks) duration.weeks = weeks;
|
|
56
|
+
}
|
|
57
|
+
if (!skip.has("days")) {
|
|
58
|
+
const days = diffDays(a, b);
|
|
59
|
+
a = addDay(a, -days);
|
|
60
|
+
if (days) duration.days = days;
|
|
61
|
+
}
|
|
62
|
+
if (!skip.has("hours")) {
|
|
63
|
+
const hours = diffHours(a, b);
|
|
64
|
+
a = addHour(a, -hours);
|
|
65
|
+
if (hours) duration.hours = hours;
|
|
66
|
+
}
|
|
67
|
+
if (!skip.has("minutes")) {
|
|
68
|
+
const minutes = diffMinutes(a, b);
|
|
69
|
+
a = addMinute(a, -minutes);
|
|
70
|
+
if (minutes) duration.minutes = minutes;
|
|
71
|
+
}
|
|
72
|
+
if (!skip.has("seconds")) {
|
|
73
|
+
const seconds = diffSeconds(a, b);
|
|
74
|
+
a = addSecond(a, -seconds);
|
|
75
|
+
if (seconds) duration.seconds = seconds;
|
|
76
|
+
}
|
|
77
|
+
if (!skip.has("milliseconds")) {
|
|
78
|
+
const ms = diffMilliseconds(a, b);
|
|
79
|
+
if (ms) duration.milliseconds = ms;
|
|
80
|
+
}
|
|
81
|
+
return duration;
|
|
82
|
+
}
|
|
83
|
+
export {
|
|
84
|
+
diff
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=diff.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/diff.ts"],"sourcesContent":["import { addDay } from \"./addDay\"\nimport { addHour } from \"./addHour\"\nimport { addMinute } from \"./addMinute\"\nimport { addMonth } from \"./addMonth\"\nimport { addSecond } from \"./addSecond\"\nimport { addYear } from \"./addYear\"\nimport { date } from \"./date\"\nimport { diffDays } from \"./diffDays\"\nimport { diffHours } from \"./diffHours\"\nimport { diffMilliseconds } from \"./diffMilliseconds\"\nimport { diffMinutes } from \"./diffMinutes\"\nimport { diffMonths } from \"./diffMonths\"\nimport { diffSeconds } from \"./diffSeconds\"\nimport { diffWeeks } from \"./diffWeeks\"\nimport { diffYears } from \"./diffYears\"\nimport type { DateInput, Duration, MaybeDateInput } from \"./types\"\n\ntype DurationKey = keyof Duration\n\nfunction negateDuration(duration: Duration): Duration {\n const negated: Duration = {}\n for (const unit of Object.keys(duration) as DurationKey[]) {\n negated[unit] = -duration[unit]!\n }\n return negated\n}\n\nfunction calendarDiff(\n current: Date,\n target: Date,\n diffUnit: (dateA: Date, dateB: Date) => number,\n addUnit: (date: Date, count: number) => Date\n): [number, Date] {\n let amount = diffUnit(current, target)\n let next = addUnit(current, -amount)\n while (amount > 0 && next < target) {\n amount--\n next = addUnit(current, -amount)\n }\n return [amount, next]\n}\n\n/**\n * Options for `diff` function\n */\nexport interface DiffOptions {\n /**\n * whether the difference should be absolute (not negative)\n */\n abs?: boolean\n /**\n * units you want to skip, for example weeks\n */\n skip?: DurationKey[] | Set<DurationKey>\n}\n\n/**\n * Returns the difference between 2 dates in an object\n * @param dateA - A date to compare with the right date\n * @param [dateB] - A date to compare with the left date or nothing to compare with the current time\n * @param [options] additional options\n * @param [options.skip] units you want skip\n * @param [options.abs] whether the difference should be absolute\n * @returns an object which could be used with `Intl.DurationFormat.format'`\n */\nexport function diff(\n dateA: DateInput,\n dateB?: MaybeDateInput,\n options?: DiffOptions\n): Duration\n\n/**\n * Returns the difference between 2 dates in an object\n * @param [dateA] - A date to compare with the right date or null to compare with the current time\n * @param dateB - A date to compare with the left date\n * @param [options] additional options\n * @param [options.skip] units you want skip\n * @param [options.abs] whether the difference should be absolute\n * @returns an object which could be used with `Intl.DurationFormat.format'`\n */\nexport function diff(\n dateA: MaybeDateInput,\n dateB: DateInput,\n options?: DiffOptions\n): Duration\n\nexport function diff(\n dateA: MaybeDateInput,\n dateB?: MaybeDateInput,\n options?: DiffOptions\n): Duration {\n let a = date(dateA)\n let b = date(dateB)\n\n if (a < b) {\n const duration = diff(b, a, options)\n return options?.abs ? duration : negateDuration(duration)\n }\n\n const skip = new Set(options?.skip)\n const duration: Duration = {}\n\n if (!skip.has(\"years\")) {\n const [years, next] = calendarDiff(a, b, diffYears, addYear)\n a = next\n if (years) duration.years = years\n }\n\n if (!skip.has(\"months\")) {\n const [months, next] = calendarDiff(a, b, diffMonths, addMonth)\n a = next\n if (months) duration.months = months\n }\n\n if (!skip.has(\"weeks\")) {\n const weeks = diffWeeks(a, b)\n a = addDay(a, -(weeks * 7))\n if (weeks) duration.weeks = weeks\n }\n\n if (!skip.has(\"days\")) {\n const days = diffDays(a, b)\n a = addDay(a, -days)\n if (days) duration.days = days\n }\n\n if (!skip.has(\"hours\")) {\n const hours = diffHours(a, b)\n a = addHour(a, -hours)\n if (hours) duration.hours = hours\n }\n\n if (!skip.has(\"minutes\")) {\n const minutes = diffMinutes(a, b)\n a = addMinute(a, -minutes)\n if (minutes) duration.minutes = minutes\n }\n\n if (!skip.has(\"seconds\")) {\n const seconds = diffSeconds(a, b)\n a = addSecond(a, -seconds)\n if (seconds) duration.seconds = seconds\n }\n\n if (!skip.has(\"milliseconds\")) {\n const ms = diffMilliseconds(a, b)\n // removing ms isn't needed as it's the last\n if (ms) duration.milliseconds = ms\n }\n return duration\n}\n"],"mappings":";AAAA,SAAS,cAAc;AACvB,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAK1B,SAAS,eAAe,UAA8B;AACpD,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO,KAAK,QAAQ,GAAoB;AACzD,YAAQ,IAAI,IAAI,CAAC,SAAS,IAAI;AAAA,EAChC;AACA,SAAO;AACT;AAEA,SAAS,aACP,SACA,QACA,UACA,SACgB;AAChB,MAAI,SAAS,SAAS,SAAS,MAAM;AACrC,MAAI,OAAO,QAAQ,SAAS,CAAC,MAAM;AACnC,SAAO,SAAS,KAAK,OAAO,QAAQ;AAClC;AACA,WAAO,QAAQ,SAAS,CAAC,MAAM;AAAA,EACjC;AACA,SAAO,CAAC,QAAQ,IAAI;AACtB;AA8CO,SAAS,KACd,OACA,OACA,SACU;AACV,MAAI,IAAI,KAAK,KAAK;AAClB,MAAI,IAAI,KAAK,KAAK;AAElB,MAAI,IAAI,GAAG;AACT,UAAMA,YAAW,KAAK,GAAG,GAAG,OAAO;AACnC,YAAO,mCAAS,OAAMA,YAAW,eAAeA,SAAQ;AAAA,EAC1D;AAEA,QAAM,OAAO,IAAI,IAAI,mCAAS,IAAI;AAClC,QAAM,WAAqB,CAAC;AAE5B,MAAI,CAAC,KAAK,IAAI,OAAO,GAAG;AACtB,UAAM,CAAC,OAAO,IAAI,IAAI,aAAa,GAAG,GAAG,WAAW,OAAO;AAC3D,QAAI;AACJ,QAAI,MAAO,UAAS,QAAQ;AAAA,EAC9B;AAEA,MAAI,CAAC,KAAK,IAAI,QAAQ,GAAG;AACvB,UAAM,CAAC,QAAQ,IAAI,IAAI,aAAa,GAAG,GAAG,YAAY,QAAQ;AAC9D,QAAI;AACJ,QAAI,OAAQ,UAAS,SAAS;AAAA,EAChC;AAEA,MAAI,CAAC,KAAK,IAAI,OAAO,GAAG;AACtB,UAAM,QAAQ,UAAU,GAAG,CAAC;AAC5B,QAAI,OAAO,GAAG,EAAE,QAAQ,EAAE;AAC1B,QAAI,MAAO,UAAS,QAAQ;AAAA,EAC9B;AAEA,MAAI,CAAC,KAAK,IAAI,MAAM,GAAG;AACrB,UAAM,OAAO,SAAS,GAAG,CAAC;AAC1B,QAAI,OAAO,GAAG,CAAC,IAAI;AACnB,QAAI,KAAM,UAAS,OAAO;AAAA,EAC5B;AAEA,MAAI,CAAC,KAAK,IAAI,OAAO,GAAG;AACtB,UAAM,QAAQ,UAAU,GAAG,CAAC;AAC5B,QAAI,QAAQ,GAAG,CAAC,KAAK;AACrB,QAAI,MAAO,UAAS,QAAQ;AAAA,EAC9B;AAEA,MAAI,CAAC,KAAK,IAAI,SAAS,GAAG;AACxB,UAAM,UAAU,YAAY,GAAG,CAAC;AAChC,QAAI,UAAU,GAAG,CAAC,OAAO;AACzB,QAAI,QAAS,UAAS,UAAU;AAAA,EAClC;AAEA,MAAI,CAAC,KAAK,IAAI,SAAS,GAAG;AACxB,UAAM,UAAU,YAAY,GAAG,CAAC;AAChC,QAAI,UAAU,GAAG,CAAC,OAAO;AACzB,QAAI,QAAS,UAAS,UAAU;AAAA,EAClC;AAEA,MAAI,CAAC,KAAK,IAAI,cAAc,GAAG;AAC7B,UAAM,KAAK,iBAAiB,GAAG,CAAC;AAEhC,QAAI,GAAI,UAAS,eAAe;AAAA,EAClC;AACA,SAAO;AACT;","names":["duration"]}
|