UNPKG

10.6 kBTypeScriptView Raw
1import { DateTime, DateObject, DateTimeOptions, DiffOptions, ToISOTimeOptions } from './datetime';
2import { Duration, DurationInput, DurationUnit } from './duration';
3
4export interface IntervalObject {
5 start?: DateTime;
6 end?: DateTime;
7}
8
9export type DateInput = DateTime | DateObject | Date;
10
11/**
12 * An Interval object represents a half-open interval of time, where each endpoint is a {@link DateTime}.
13 * Conceptually, it's a container for those two endpoints, accompanied by methods for creating, parsing, interrogating,
14 * comparing, transforming, and formatting them.
15 *
16 * Here is a brief overview of the most commonly used methods and getters in Interval:
17 *
18 * * **Creation** To create an Interval, use {@link fromDateTimes}, {@link after}, {@link before}, or {@link fromISO}.
19 * * **Accessors** Use {@link start} and {@link end} to get the start and end.
20 * * **Interrogation** To analyze the Interval, use {@link count}, {@link length}, {@link hasSame}, {@link contains}, {@link isAfter}, or {@link isBefore}.
21 * * **Transformation** To create other Intervals out of this one, use {@link set}, {@link splitAt}, {@link splitBy}, {@link divideEqually}, {@link merge},
22 * {@link xor}, {@link union}, {@link intersection}, or {@link difference}.
23 * * **Comparison** To compare this Interval to another one, use {@link equals}, {@link overlaps}, {@link abutsStart}, {@link abutsEnd}, {@link engulfs}.
24 * * **Output** To convert the Interval into other representations, see {@link toString}, {@link toISO}, {@link toISODate}, {@link toISOTime}, {@link toFormat}, and {@link toDuration}.
25 */
26export class Interval {
27 /**
28 * Create an Interval from a start DateTime and a Duration to extend to.
29 */
30 static after(start: DateInput, duration: DurationInput): Interval;
31
32 /**
33 * Create an Interval from an end DateTime and a Duration to extend backwards to.
34 */
35 static before(end: DateInput, duration: DurationInput): Interval;
36
37 /**
38 * Create an Interval from a start DateTime and an end DateTime. Inclusive of the start but not the end.
39 */
40 static fromDateTimes(start: DateInput, end: DateInput): Interval;
41
42 /**
43 * Create an Interval from an ISO 8601 string.
44 * Accepts `<start>/<end>`, `<start>/<duration>`, and `<duration>/<end>` formats.
45 * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
46 */
47 static fromISO(text: string, options?: DateTimeOptions): Interval;
48
49 /**
50 * Create an invalid Interval.
51 * @param reason - simple string of why this Interval is invalid. Should not contain parameters or anything else data-dependent
52 * @param [explanation] - longer explanation, may include parameters and other useful debugging information
53 */
54 static invalid(reason: string, explanation?: string): Interval;
55
56 /**
57 * Check if an object is an Interval. Works across context boundaries
58 */
59 static isInterval(o: any): o is Interval;
60
61 /**
62 * Merge an array of Intervals into a equivalent minimal set of Intervals.
63 * Combines overlapping and adjacent Intervals.
64 */
65 static merge(intervals: Interval[]): Interval[];
66
67 /**
68 * Return an array of Intervals representing the spans of time that only appear in one of the specified Intervals.
69 */
70 static xor(intervals: Interval[]): Interval[];
71
72 /**
73 * Returns the end of the Interval
74 */
75 end: DateTime;
76
77 /**
78 * Returns an error code if this Interval is invalid, or null if the Interval is valid
79 */
80 invalidReason: string | null;
81
82 /**
83 * Returns an explanation of why this Interval became invalid, or null if the Interval is valid
84 */
85 invalidExplanation: string | null;
86
87 /**
88 * Returns whether this Interval's end is at least its start, meaning that the Interval isn't 'backwards'.
89 */
90 isValid: boolean;
91
92 /**
93 * Returns the start of the Interval
94 */
95 start: DateTime;
96
97 /**
98 * Return whether this Interval's start is adjacent to the specified Interval's end.
99 */
100 abutsEnd(other: Interval): boolean;
101
102 /**
103 * Return whether this Interval's end is adjacent to the specified Interval's start.
104 */
105 abutsStart(other: Interval): boolean;
106
107 /**
108 * Return whether this Interval contains the specified DateTime.
109 */
110 contains(dateTime: DateTime): boolean;
111
112 /**
113 * Returns the count of minutes, hours, days, months, or years included in the Interval, even in part.
114 * Unlike {@link length} this counts sections of the calendar, not periods of time, e.g. specifying 'day'
115 * asks 'what dates are included in this interval?', not 'how many days long is this interval?'
116 * @param [unit='milliseconds'] - the unit of time to count.
117 */
118 count(unit?: DurationUnit): number;
119
120 /**
121 * Return an Interval representing the span of time in this Interval that doesn't overlap with any of the specified Intervals.
122 */
123 difference(...intervals: Interval[]): Interval[];
124
125 /**
126 * Split this Interval into the specified number of smaller intervals.
127 * @param numberOfParts - The number of Intervals to divide the Interval into.
128 */
129 divideEqually(numberOfParts: number): Interval[];
130
131 /**
132 * Return whether this Interval engulfs the start and end of the specified Interval.
133 */
134 engulfs(other: Interval): boolean;
135
136 /**
137 * Return whether this Interval has the same start and end as the specified Interval.
138 * Two DateTimes are equal if they represent the same millisecond, have the same zone and location, and are both valid.
139 */
140 equals(other: Interval): boolean;
141
142 /**
143 * Returns whether this Interval's start and end are both in the same unit of time
144 * @param unit - the unit of time to check sameness on
145 */
146 hasSame(unit: DurationUnit): boolean;
147
148 /**
149 * Return an Interval representing the intersection of this Interval and the specified Interval.
150 * Specifically, the resulting Interval has the maximum start time and the minimum end time of the two Intervals.
151 * Returns null if the intersection is empty, meaning, the intervals don't intersect.
152 */
153 intersection(other: Interval): Interval | null;
154
155 /**
156 * Return whether this Interval's start is after the specified DateTime.
157 */
158 isAfter(dateTime: DateTime): boolean;
159
160 /**
161 * Return whether this Interval's end is before the specified DateTime.
162 */
163 isBefore(dateTime: DateTime): boolean;
164
165 /**
166 * Return whether this Interval has the same start and end DateTimes.
167 */
168 isEmpty(): boolean;
169
170 /**
171 * Returns the length of the Interval in the specified unit.
172 * @param [unit='milliseconds'] - the unit to return the length in.
173 */
174 length(unit?: DurationUnit): number;
175
176 /**
177 * Return whether this Interval overlaps with the specified Interval
178 */
179 overlaps(other: Interval): boolean;
180
181 /**
182 * "Sets" the start and/or end dates. Returns a newly-constructed Interval.
183 */
184 set(values?: IntervalObject): Interval;
185
186 /**
187 * Split this Interval at each of the specified DateTimes
188 */
189 splitAt(...dateTimes: DateTime[]): Interval[];
190
191 /**
192 * Split this Interval into smaller Intervals, each of the specified length.
193 * Left over time is grouped into a smaller interval
194 * @param duration - The length of each resulting interval.
195 */
196 splitBy(duration: DurationInput): Interval[];
197
198 /**
199 * Return a Duration representing the time spanned by this interval.
200 * @param [unit=['milliseconds']] - the unit or units to include in the duration.
201 * @param [options] - options that affect the creation of the Duration
202 * @param [options.conversionAccuracy='casual'] - the conversion system to use
203 * @example
204 * Interval.fromDateTimes(dt1, dt2).toDuration().toObject() //=> { milliseconds: 88489257 }
205 * @example
206 * Interval.fromDateTimes(dt1, dt2).toDuration('days').toObject() //=> { days: 1.0241812152777778 }
207 * @example
208 * Interval.fromDateTimes(dt1, dt2).toDuration(['hours', 'minutes']).toObject() //=> { hours: 24, minutes: 34.82095 }
209 * @example
210 * Interval.fromDateTimes(dt1, dt2).toDuration(['hours', 'minutes', 'seconds']).toObject() //=> { hours: 24, minutes: 34, seconds: 49.257 }
211 * @example
212 * Interval.fromDateTimes(dt1, dt2).toDuration('seconds').toObject() //=> { seconds: 88489.257 }
213 */
214 toDuration(unit?: DurationUnit | DurationUnit[], options?: DiffOptions): Duration;
215
216 /**
217 * Returns a string representation of this Interval formatted according to the specified format string.
218 * @param dateFormat - the format string. This string formats the start and end time. See {@link DateTime.toFormat} for details.
219 * @param [options] - options
220 * @param [options.separator=' - '] - a separator to place between the start and end representations
221 */
222 toFormat(
223 dateFormat: string,
224 options?: {
225 separator?: string;
226 },
227 ): string;
228
229 /**
230 * Returns an ISO 8601-compliant string representation of this Interval.
231 * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
232 */
233 toISO(options?: ToISOTimeOptions): string;
234
235 /**
236 * Returns an ISO 8601-compliant string representation of date of this Interval.
237 * The time components are ignored.
238 * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
239 */
240 toISODate(): string;
241
242 /**
243 * Returns an ISO 8601-compliant string representation of time of this Interval.
244 * The date components are ignored.
245 * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
246 */
247 toISOTime(options?: ToISOTimeOptions): string;
248
249 /**
250 * Returns a string representation of this Interval appropriate for debugging.
251 */
252 toString(): string;
253
254 /**
255 * Return an Interval representing the union of this Interval and the specified Interval.
256 * Specifically, the resulting Interval has the minimum start time and the maximum end time of the two Intervals.
257 */
258 union(other: Interval): Interval;
259
260 /**
261 * Run mapFn on the interval start and end, returning a new Interval from the resulting DateTimes
262 * @example
263 * Interval.fromDateTimes(dt1, dt2).mapEndpoints(endpoint => endpoint.toUTC())
264 * @example
265 * Interval.fromDateTimes(dt1, dt2).mapEndpoints(endpoint => endpoint.plus({ hours: 2 }))
266 */
267 mapEndpoints(mapFn: (d: DateTime) => DateTime): Interval;
268}