UNPKG

18.5 kBTypeScriptView Raw
1import { CanBeInvalid, DefaultValidity, IfValid, Invalid, Valid } from "./_util";
2import { ConversionAccuracy } from "./datetime";
3import { NumberingSystem } from "./misc";
4
5export interface DurationOptions {
6 locale?: string | undefined;
7 numberingSystem?: NumberingSystem | undefined;
8 conversionAccuracy?: ConversionAccuracy | undefined;
9}
10
11export interface DurationObjectUnits {
12 years?: number | undefined;
13 quarters?: number | undefined;
14 months?: number | undefined;
15 weeks?: number | undefined;
16 days?: number | undefined;
17 hours?: number | undefined;
18 minutes?: number | undefined;
19 seconds?: number | undefined;
20 milliseconds?: number | undefined;
21}
22
23export interface DurationLikeObject extends DurationObjectUnits {
24 year?: number | undefined;
25 quarter?: number | undefined;
26 month?: number | undefined;
27 week?: number | undefined;
28 day?: number | undefined;
29 hour?: number | undefined;
30 minute?: number | undefined;
31 second?: number | undefined;
32 millisecond?: number | undefined;
33}
34
35export type DurationUnit = keyof DurationLikeObject;
36export type DurationUnits = DurationUnit | DurationUnit[];
37
38export type ToISOFormat = "basic" | "extended";
39
40export interface ToISOTimeDurationOptions {
41 /**
42 * Include the `T` prefix
43 * @default false
44 */
45 includePrefix?: boolean | undefined;
46 /**
47 * Exclude milliseconds from the format if they are 0
48 * @default false
49 */
50 suppressMilliseconds?: boolean | undefined;
51 /**
52 * Exclude seconds from the format if they are 0
53 * @default false
54 */
55 suppressSeconds?: boolean | undefined;
56 /**
57 * Choose between the basic and extended format
58 * @default 'extended'
59 */
60 format?: ToISOFormat | undefined;
61}
62
63export interface ToHumanDurationOptions extends Intl.NumberFormatOptions {
64 listStyle?: "long" | "short" | "narrow" | undefined;
65}
66
67/**
68 * Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
69 *
70 * @deprecated Use DurationLike instead.
71 */
72export type DurationInput = Duration | number | DurationLikeObject;
73
74/**
75 * Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
76 */
77export type DurationLike = Duration | DurationLikeObject | number;
78
79export type DurationMaybeValid = CanBeInvalid extends true ? (Duration<Valid> | Duration<Invalid>) : Duration;
80
81/**
82 * A Duration object represents a period of time, like "2 months" or "1 day, 1 hour".
83 * Conceptually, it is just a map of units to their quantities, accompanied by some additional configuration and methods for creating, parsing, interrogating, transforming, and formatting them.
84 * They can be used on their own or in conjunction with other Luxon types; for example, you can use {@link DateTime.plus} to add a Duration object to a DateTime, producing another DateTime.
85 *
86 * Here is a brief overview of commonly used methods and getters in Duration:
87 *
88 * * **Creation** To create a Duration, use {@link Duration.fromMillis}, {@link Duration.fromObject}, or {@link Duration.fromISO}.
89 * * **Unit values** See the {@link Duration#years}, {@link Duration.months}, {@link Duration#weeks}, {@link Duration#days}, {@link Duration#hours}, {@link Duration#minutes},
90 * * {@link Duration#seconds}, {@link Duration#milliseconds} accessors.
91 * * **Configuration** See {@link Duration#locale} and {@link Duration#numberingSystem} accessors.
92 * * **Transformation** To create new Durations out of old ones use {@link Duration#plus}, {@link Duration#minus}, {@link Duration#normalize}, {@link Duration#set}, {@link Duration#reconfigure},
93 * * {@link Duration#shiftTo}, and {@link Duration#negate}.
94 * * **Output** To convert the Duration into other representations, see {@link Duration#as}, {@link Duration#toISO}, {@link Duration#toFormat}, and {@link Duration#toJSON}
95 *
96 * There's are more methods documented below. In addition, for more information on subtler topics like internationalization and validity, see the external documentation.
97 */
98export class Duration<IsValid extends boolean = DefaultValidity> {
99 /**
100 * Create Duration from a number of milliseconds.
101 *
102 * @param count - of milliseconds
103 * @param opts - options for parsing
104 * @param opts.locale - the locale to use
105 * @param opts.numberingSystem - the numbering system to use
106 * @param opts.conversionAccuracy - the conversion system to use
107 */
108 static fromMillis(count: number, opts?: DurationOptions): Duration<Valid>;
109
110 /**
111 * Create a Duration from a JavaScript object with keys like 'years' and 'hours'.
112 * If this object is empty then a zero milliseconds duration is returned.
113 *
114 * @param obj - the object to create the Duration from
115 * @param obj.years
116 * @param obj.quarters
117 * @param obj.months
118 * @param obj.weeks
119 * @param obj.days
120 * @param obj.hours
121 * @param obj.minutes
122 * @param obj.seconds
123 * @param obj.milliseconds
124 * @param opts - options for creating this Duration. Defaults to {}.
125 * @param opts.locale - the locale to use. Defaults to 'en-US'.
126 * @param opts.numberingSystem - the numbering system to use
127 * @param opts.conversionAccuracy - the conversion system to use. Defaults to 'casual'.
128 */
129 static fromObject(obj: DurationLikeObject, opts?: DurationOptions): Duration<Valid>;
130
131 /**
132 * Create a Duration from DurationLike.
133 *
134 * @param durationLike
135 * Either a Luxon Duration, a number of milliseconds, or the object argument to Duration.fromObject()
136 */
137 static fromDurationLike(durationLike: DurationLike): Duration<Valid>;
138
139 /**
140 * Create a Duration from an ISO 8601 duration string.
141 * @see https://en.wikipedia.org/wiki/ISO_8601#Durations
142 *
143 * @param text - text to parse
144 * @param opts - options for parsing
145 * @param opts.locale - the locale to use. Defaults to 'en-US'.
146 * @param opts.numberingSystem - the numbering system to use
147 * @param opts.conversionAccuracy - the conversion system to use. Defaults to 'casual'.
148 *
149 * @example
150 * Duration.fromISO('P3Y6M1W4DT12H30M5S').toObject() //=> { years: 3, months: 6, weeks: 1, days: 4, hours: 12, minutes: 30, seconds: 5 }
151 * @example
152 * Duration.fromISO('PT23H').toObject() //=> { hours: 23 }
153 * @example
154 * Duration.fromISO('P5Y3M').toObject() //=> { years: 5, months: 3 }
155 */
156 static fromISO(text: string, opts?: DurationOptions): DurationMaybeValid;
157
158 /**
159 * Create a Duration from an ISO 8601 time string.
160 * @see https://en.wikipedia.org/wiki/ISO_8601#Times
161 *
162 * @param text - text to parse
163 * @param opts - options for parsing
164 * @param opts.locale - the locale to use. Defaults to 'en-US'.
165 * @param opts.numberingSystem - the numbering system to use
166 * @param opts.conversionAccuracy - the conversion system to use. Defaults to 'casual'.
167 *
168 * @example
169 * Duration.fromISOTime('11:22:33.444').toObject() //=> { hours: 11, minutes: 22, seconds: 33, milliseconds: 444 }
170 * @example
171 * Duration.fromISOTime('11:00').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
172 * @example
173 * Duration.fromISOTime('T11:00').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
174 * @example
175 * Duration.fromISOTime('1100').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
176 * @example
177 * Duration.fromISOTime('T1100').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
178 */
179 static fromISOTime(text: string, opts?: DurationOptions): DurationMaybeValid;
180
181 /**
182 * Create an invalid Duration.
183 *
184 * @param reason - simple string of why this datetime is invalid. Should not contain parameters or anything else data-dependent
185 * @param explanation - longer explanation, may include parameters and other useful debugging information. Defaults to null.
186 */
187 static invalid(reason: string, explanation?: string): Duration<Invalid>;
188
189 /**
190 * Check if an object is a Duration. Works across context boundaries
191 *
192 * @param o
193 */
194 static isDuration(o: unknown): o is DurationMaybeValid;
195
196 private constructor(config: unknown);
197
198 /**
199 * Get the locale of a Duration, such as 'en-GB'
200 */
201 get locale(): IfValid<string, null, IsValid>;
202
203 /**
204 * Get the numbering system of a Duration, such as 'beng'. The numbering system is used when formatting the Duration
205 */
206 get numberingSystem(): IfValid<string, null, IsValid>;
207
208 /**
209 * Returns a string representation of this Duration formatted according to the specified format string. You may use these tokens:
210 * * `S` for milliseconds
211 * * `s` for seconds
212 * * `m` for minutes
213 * * `h` for hours
214 * * `d` for days
215 * * `M` for months
216 * * `y` for years
217 * Notes:
218 * * Add padding by repeating the token, e.g. "yy" pads the years to two digits, "hhhh" pads the hours out to four digits
219 * * The duration will be converted to the set of units in the format string using {@link Duration.shiftTo} and the Duration's conversion accuracy setting.
220 *
221 * @param fmt - the format string
222 * @param opts - options
223 * @param opts.floor - floor numerical values. Defaults to true.
224 *
225 * @example
226 * Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("y d s") //=> "1 6 2"
227 * @example
228 * Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("yy dd sss") //=> "01 06 002"
229 * @example
230 * Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("M S") //=> "12 518402000"
231 */
232 toFormat(fmt: string, opts?: { floor?: boolean | undefined }): IfValid<string, "Invalid Duration", IsValid>;
233
234 /**
235 * Returns a string representation of a Duration with all units included
236 * To modify its behavior use the `listStyle` and any Intl.NumberFormat option, though `unitDisplay` is especially relevant. See {@link Intl.NumberFormat}.
237 *
238 * @example
239 * ```js
240 * var dur = Duration.fromObject({ days: 1, hours: 5, minutes: 6 })
241 * dur.toHuman() //=> '1 day, 5 hours, 6 minutes'
242 * dur.toHuman({ listStyle: "long" }) //=> '1 day, 5 hours, and 6 minutes'
243 * dur.toHuman({ unitDisplay: "short" }) //=> '1 day, 5 hr, 6 min'
244 * ```
245 */
246 toHuman(opts?: ToHumanDurationOptions): string;
247
248 /**
249 * Returns a JavaScript object with this Duration's values.
250 *
251 * @example
252 * Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toObject() //=> { years: 1, days: 6, seconds: 2 }
253 */
254 toObject(): DurationObjectUnits;
255
256 /**
257 * Returns an ISO 8601-compliant string representation of this Duration.
258 * @see https://en.wikipedia.org/wiki/ISO_8601#Durations
259 *
260 * @example
261 * Duration.fromObject({ years: 3, seconds: 45 }).toISO() //=> 'P3YT45S'
262 * @example
263 * Duration.fromObject({ months: 4, seconds: 45 }).toISO() //=> 'P4MT45S'
264 * @example
265 * Duration.fromObject({ months: 5 }).toISO() //=> 'P5M'
266 * @example
267 * Duration.fromObject({ minutes: 5 }).toISO() //=> 'PT5M'
268 * @example
269 * Duration.fromObject({ milliseconds: 6 }).toISO() //=> 'PT0.006S'
270 */
271 toISO(): IfValid<string, null, IsValid>;
272
273 /**
274 * Returns an ISO 8601-compliant string representation of this Duration, formatted as a time of day.
275 * @see https://en.wikipedia.org/wiki/ISO_8601#Times
276 *
277 * @param opts - options
278 * @param opts.suppressMilliseconds - exclude milliseconds from the format if they are 0. Defaults to false.
279 * @param opts.suppressSeconds - exclude seconds from the format if they're 0. Defaults to false.
280 * @param opts.includePrefix - include the `T` prefix. Defaults to false.
281 * @param opts.format - choose between the basic and extended format. Defaults to 'extended'.
282 *
283 * @example
284 * Duration.fromObject({ hours: 11 }).toISOTime() //=> '11:00:00.000'
285 * @example
286 * Duration.fromObject({ hours: 11 }).toISOTime({ suppressMilliseconds: true }) //=> '11:00:00'
287 * @example
288 * Duration.fromObject({ hours: 11 }).toISOTime({ suppressSeconds: true }) //=> '11:00'
289 * @example
290 * Duration.fromObject({ hours: 11 }).toISOTime({ includePrefix: true }) //=> 'T11:00:00.000'
291 * @example
292 * Duration.fromObject({ hours: 11 }).toISOTime({ format: 'basic' }) //=> '110000.000'
293 */
294 toISOTime(opts?: ToISOTimeDurationOptions): IfValid<string, null, IsValid>;
295
296 /**
297 * Returns an ISO 8601 representation of this Duration appropriate for use in JSON.
298 */
299 toJSON(): IfValid<string, null, IsValid>;
300
301 /**
302 * Returns an ISO 8601 representation of this Duration appropriate for use in debugging.
303 */
304 toString(): IfValid<string, null, IsValid>;
305
306 /**
307 * Returns a millisecond value of this Duration.
308 */
309 toMillis(): IfValid<number, typeof NaN, IsValid>;
310
311 /**
312 * Returns a millisecond value of this Duration. Alias of {@link toMillis}
313 */
314 valueOf(): IfValid<number, typeof NaN, IsValid>;
315
316 /**
317 * Make this Duration longer by the specified amount. Return a newly-constructed Duration.
318 *
319 * @param duration - The amount to add. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
320 */
321 plus(duration: DurationLike): this;
322
323 /**
324 * Make this Duration shorter by the specified amount. Return a newly-constructed Duration.
325 *
326 * @param duration - The amount to subtract. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
327 */
328 minus(duration: DurationLike): this;
329
330 /**
331 * Scale this Duration by the specified amount. Return a newly-constructed Duration.
332 *
333 * @example
334 * Duration.fromObject({ hours: 1, minutes: 30 }).mapUnit(x => x * 2) //=> { hours: 2, minutes: 60 }
335 * @example
336 * Duration.fromObject({ hours: 1, minutes: 30 }).mapUnit((x, u) => u === "hour" ? x * 2 : x) //=> { hours: 2, minutes: 30 }
337 */
338 mapUnits(fn: (x: number, u?: DurationUnit) => number): this;
339
340 /**
341 * Get the value of unit.
342 *
343 * @param unit - a unit such as 'minute' or 'day'
344 *
345 * @example
346 * Duration.fromObject({years: 2, days: 3}).get('years') //=> 2
347 * @example
348 * Duration.fromObject({years: 2, days: 3}).get('months') //=> 0
349 * @example
350 * Duration.fromObject({years: 2, days: 3}).get('days') //=> 3
351 */
352 get(unit: DurationUnit): IfValid<number, typeof NaN, IsValid>;
353
354 /**
355 * "Set" the values of specified units. Return a newly-constructed Duration.
356 *
357 * @param values - a mapping of units to numbers
358 *
359 * @example
360 * dur.set({ years: 2017 })
361 * @example
362 * dur.set({ hours: 8, minutes: 30 })
363 */
364 set(values: DurationLikeObject): this;
365
366 /**
367 * "Set" the locale and/or numberingSystem. Returns a newly-constructed Duration.
368 *
369 * @example
370 * dur.reconfigure({ locale: 'en-GB' })
371 */
372 reconfigure(opts?: DurationOptions): this;
373
374 /**
375 * Return the length of the duration in the specified unit.
376 *
377 * @param unit - a unit such as 'minutes' or 'days'
378 *
379 * @example
380 * Duration.fromObject({years: 1}).as('days') //=> 365
381 * @example
382 * Duration.fromObject({years: 1}).as('months') //=> 12
383 * @example
384 * Duration.fromObject({hours: 60}).as('days') //=> 2.5
385 */
386 as(unit: DurationUnit): IfValid<number, typeof NaN, IsValid>;
387
388 /**
389 * Reduce this Duration to its canonical representation in its current units.
390 *
391 * @example
392 * Duration.fromObject({ years: 2, days: 5000 }).normalize().toObject() //=> { years: 15, days: 255 }
393 * @example
394 * Duration.fromObject({ hours: 12, minutes: -45 }).normalize().toObject() //=> { hours: 11, minutes: 15 }
395 */
396 normalize(): this;
397
398 /**
399 * Rescale units to its largest representation.
400 *
401 * @example
402 * Duration.fromObject({ milliseconds: 90000 }).rescale().toObject() //=> { minutes: 1, seconds: 30 }
403 */
404 rescale(): this;
405
406 /**
407 * Convert this Duration into its representation in a different set of units.
408 *
409 * @example
410 * Duration.fromObject({ hours: 1, seconds: 30 }).shiftTo('minutes', 'milliseconds').toObject() //=> { minutes: 60, milliseconds: 30000 }
411 */
412 shiftTo(...units: DurationUnit[]): this;
413
414 /**
415 * Shift this Duration to all available units.
416 * Same as shiftTo("years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds")
417 */
418 shiftToAll(): this;
419
420 /**
421 * Return the negative of this Duration.
422 *
423 * @example
424 * Duration.fromObject({ hours: 1, seconds: 30 }).negate().toObject() //=> { hours: -1, seconds: -30 }
425 */
426 negate(): this;
427
428 /**
429 * Get the years.
430 */
431 get years(): IfValid<number, typeof NaN, IsValid>;
432
433 /**
434 * Get the quarters.
435 */
436 get quarters(): IfValid<number, typeof NaN, IsValid>;
437
438 /**
439 * Get the months.
440 */
441 get months(): IfValid<number, typeof NaN, IsValid>;
442
443 /**
444 * Get the weeks
445 */
446 get weeks(): IfValid<number, typeof NaN, IsValid>;
447
448 /**
449 * Get the days.
450 */
451 get days(): IfValid<number, typeof NaN, IsValid>;
452
453 /**
454 * Get the hours.
455 */
456 get hours(): IfValid<number, typeof NaN, IsValid>;
457
458 /**
459 * Get the minutes.
460 */
461 get minutes(): IfValid<number, typeof NaN, IsValid>;
462
463 /**
464 * Get the seconds.
465 */
466 get seconds(): IfValid<number, typeof NaN, IsValid>;
467
468 /**
469 * Get the milliseconds.
470 */
471 get milliseconds(): IfValid<number, typeof NaN, IsValid>;
472
473 /**
474 * Returns whether the Duration is invalid.
475 * Diff operations on invalid DateTimes or Intervals return invalid Durations.
476 */
477 get isValid(): IfValid<true, false, IsValid>;
478
479 /**
480 * Returns an error code if this Duration became invalid, or null if the Duration is valid
481 */
482 get invalidReason(): IfValid<null, string, IsValid>;
483
484 /**
485 * Returns an explanation of why this Duration became invalid, or null if the Duration is valid
486 */
487 get invalidExplanation(): IfValid<null, string | null, IsValid>;
488
489 /**
490 * Equality check
491 * Two Durations are equal iff they have the same units and the same values for each unit.
492 */
493 equals(other: Duration): IfValid<boolean, false, IsValid>;
494}