PageSourceSearch

https://www.vincentguerlais.com/assets/npm/luxon/luxon-9c79b8e68058f64c1a454a42352ae7e8.js

js vincentguerlais.com collected 2026-09-26 10:09:02 UTC 254,635 bytes, 7,985 lines download raw bytes

vendor: 6,345 bytes, lines 1-394
1// these aren't really private, but nor are they really useful to document
2
3/**
4 * @private
5 */
6class LuxonError extends Error {}
7
8/**
9 * @private
10 */
11class InvalidDateTimeError extends LuxonError {
12  constructor(reason) {
13    super(`Invalid DateTime: ${reason.toMessage()}`);
14  }
15}
16
17/**
18 * @private
19 */
20class InvalidIntervalError extends LuxonError {
21  constructor(reason) {
22    super(`Invalid Interval: ${reason.toMessage()}`);
23  }
24}
25
26/**
27 * @private
28 */
29class InvalidDurationError extends LuxonError {
30  constructor(reason) {
31    super(`Invalid Duration: ${reason.toMessage()}`);
32  }
33}
34
35/**
36 * @private
37 */
38class ConflictingSpecificationError extends LuxonError {}
39
40/**
41 * @private
42 */
43class InvalidUnitError extends LuxonError {
44  constructor(unit) {
45    super(`Invalid unit ${unit}`);
46  }
47}
48
49/**
50 * @private
51 */
52class InvalidArgumentError extends LuxonError {}
53
54/**
55 * @private
56 */
57class ZoneIsAbstractError extends LuxonError {
58  constructor() {
59    super("Zone is an abstract class");
60  }
61}
62
63/**
64 * @private
65 */
66
67const n = "numeric",
68  s = "short",
69  l = "long";
70
71const DATE_SHORT = {
72  year: n,
73  month: n,
74  day: n,
75};
76
77const DATE_MED = {
78  year: n,
79  month: s,
80  day: n,
81};
82
83const DATE_MED_WITH_WEEKDAY = {
84  year: n,
85  month: s,
86  day: n,
87  weekday: s,
88};
89
90const DATE_FULL = {
91  year: n,
92  month: l,
93  day: n,
94};
95
96const DATE_HUGE = {
97  year: n,
98  month: l,
99  day: n,
100  weekday: l,
101};
102
103const TIME_SIMPLE = {
104  hour: n,
105  minute: n,
106};
107
108const TIME_WITH_SECONDS = {
109  hour: n,
110  minute: n,
111  second: n,
112};
113
114const TIME_WITH_SHORT_OFFSET = {
115  hour: n,
116  minute: n,
117  second: n,
118  timeZoneName: s,
119};
120
121const TIME_WITH_LONG_OFFSET = {
122  hour: n,
123  minute: n,
124  second: n,
125  timeZoneName: l,
126};
127
128const TIME_24_SIMPLE = {
129  hour: n,
130  minute: n,
131  hourCycle: "h23",
132};
133
134const TIME_24_WITH_SECONDS = {
135  hour: n,
136  minute: n,
137  second: n,
138  hourCycle: "h23",
139};
140
141const TIME_24_WITH_SHORT_OFFSET = {
142  hour: n,
143  minute: n,
144  second: n,
145  hourCycle: "h23",
146  timeZoneName: s,
147};
148
149const TIME_24_WITH_LONG_OFFSET = {
150  hour: n,
151  minute: n,
152  second: n,
153  hourCycle: "h23",
154  timeZoneName: l,
155};
156
157const DATETIME_SHORT = {
158  year: n,
159  month: n,
160  day: n,
161  hour: n,
162  minute: n,
163};
164
165const DATETIME_SHORT_WITH_SECONDS = {
166  year: n,
167  month: n,
168  day: n,
169  hour: n,
170  minute: n,
171  second: n,
172};
173
174const DATETIME_MED = {
175  year: n,
176  month: s,
177  day: n,
178  hour: n,
179  minute: n,
180};
181
182const DATETIME_MED_WITH_SECONDS = {
183  year: n,
184  month: s,
185  day: n,
186  hour: n,
187  minute: n,
188  second: n,
189};
190
191const DATETIME_MED_WITH_WEEKDAY = {
192  year: n,
193  month: s,
194  day: n,
195  weekday: s,
196  hour: n,
197  minute: n,
198};
199
200const DATETIME_FULL = {
201  year: n,
202  month: l,
203  day: n,
204  hour: n,
205  minute: n,
206  timeZoneName: s,
207};
208
209const DATETIME_FULL_WITH_SECONDS = {
210  year: n,
211  month: l,
212  day: n,
213  hour: n,
214  minute: n,
215  second: n,
216  timeZoneName: s,
217};
218
219const DATETIME_HUGE = {
220  year: n,
221  month: l,
222  day: n,
223  weekday: l,
224  hour: n,
225  minute: n,
226  timeZoneName: l,
227};
228
229const DATETIME_HUGE_WITH_SECONDS = {
230  year: n,
231  month: l,
232  day: n,
233  weekday: l,
234  hour: n,
235  minute: n,
236  second: n,
237  timeZoneName: l,
238};
239
240/**
241 * @interface
242 */
243class Zone {
244  /**
245   * The type of zone
246   * @abstract
247   * @type {string}
248   */
249  get type() {
250    throw new ZoneIsAbstractError();
251  }
252
253  /**
254   * The name of this zone.
255   * @abstract
256   * @type {string}
257   */
258  get name() {
259    throw new ZoneIsAbstractError();
260  }
261
262  /**
263   * The IANA name of this zone.
264   * Defaults to `name` if not overwritten by a subclass.
265   * @abstract
266   * @type {string}
267   */
268  get ianaName() {
269    return this.name;
270  }
271
272  /**
273   * Returns whether the offset is known to be fixed for the whole year.
274   * @abstract
275   * @type {boolean}
276   */
277  get isUniversal() {
278    throw new ZoneIsAbstractError();
279  }
280
281  /**
282   * Returns the offset's common name (such as EST) at the specified timestamp
283   * @abstract
284   * @param {number} ts - Epoch milliseconds for which to get the name
285   * @param {Object} opts - Options to affect the format
286   * @param {string} opts.format - What style of offset to return. Accepts 'long' or 'short'.
287   * @param {string} opts.locale - What locale to return the offset name in.
288   * @return {string}
289   */
290  offsetName(ts, opts) {
291    throw new ZoneIsAbstractError();
292  }
293
294  /**
295   * Returns the offset's value as a string
296   * @abstract
297   * @param {number} ts - Epoch milliseconds for which to get the offset
298   * @param {string} format - What style of offset to return.
299   *                          Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
300   * @return {string}
301   */
302  formatOffset(ts, format) {
303    throw new ZoneIsAbstractError();
304  }
305
306  /**
307   * Return the offset in minutes for this zone at the specified timestamp.
308   * @abstract
309   * @param {number} ts - Epoch milliseconds for which to compute the offset
310   * @return {number}
311   */
312  offset(ts) {
313    throw new ZoneIsAbstractError();
314  }
315
316  /**
317   * Return whether this Zone is equal to another zone
318   * @abstract
319   * @param {Zone} otherZone - the zone to compare
320   * @return {boolean}
321   */
322  equals(otherZone) {
323    throw new ZoneIsAbstractError();
324  }
325
326  /**
327   * Return whether this Zone is valid.
328   * @abstract
329   * @type {boolean}
330   */
331  get isValid() {
332    throw new ZoneIsAbstractError();
333  }
334}
335
336let singleton$1 = null;
337
338/**
339 * Represents the local zone for this JavaScript environment.
340 * @implements {Zone}
341 */
342class SystemZone extends Zone {
343  /**
344   * Get a singleton instance of the local zone
345   * @return {SystemZone}
346   */
347  static get instance() {
348    if (singleton$1 === null) {
349      singleton$1 = new SystemZone();
350    }
351    return singleton$1;
352  }
353
354  /** @override **/
355  get type() {
356    return "system";
357  }
358
359  /** @override **/
360  get name() {
361    return new Intl.DateTimeFormat().resolvedOptions().timeZone;
362  }
363
364  /** @override **/
365  get isUniversal() {
366    return false;
367  }
368
369  /** @override **/
370  offsetName(ts, { format, locale }) {
371    return parseZoneInfo(ts, format, locale);
372  }
373
374  /** @override **/
375  formatOffset(ts, format) {
376    return formatOffset(this.offset(ts), format);
377  }
378
379  /** @override **/
380  offset(ts) {
381    return -new Date(ts).getTimezoneOffset();
382  }
383
384  /** @override **/
385  equals(otherZone) {
386    return otherZone.type === "system";
387  }
388
389  /** @override **/
390  get isValid() {
391    return true;
392  }
393}
394
vendor: 23,084 bytes, lines 395-1242
395let dtfCache = {};
396function makeDTF(zone) {
397  if (!dtfCache[zone]) {
398    dtfCache[zone] = new Intl.DateTimeFormat("en-US", {
399      hour12: false,
400      timeZone: zone,
401      year: "numeric",
402      month: "2-digit",
403      day: "2-digit",
404      hour: "2-digit",
405      minute: "2-digit",
406      second: "2-digit",
407      era: "short",
408    });
409  }
410  return dtfCache[zone];
411}
412
413const typeToPos = {
414  year: 0,
415  month: 1,
416  day: 2,
417  era: 3,
418  hour: 4,
419  minute: 5,
420  second: 6,
421};
422
423function hackyOffset(dtf, date) {
424  const formatted = dtf.format(date).replace(/\u200E/g, ""),
425    parsed = /(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(formatted),
426    [, fMonth, fDay, fYear, fadOrBc, fHour, fMinute, fSecond] = parsed;
427  return [fYear, fMonth, fDay, fadOrBc, fHour, fMinute, fSecond];
428}
429
430function partsOffset(dtf, date) {
431  const formatted = dtf.formatToParts(date);
432  const filled = [];
433  for (let i = 0; i < formatted.length; i++) {
434    const { type, value } = formatted[i];
435    const pos = typeToPos[type];
436
437    if (type === "era") {
438      filled[pos] = value;
439    } else if (!isUndefined(pos)) {
440      filled[pos] = parseInt(value, 10);
441    }
442  }
443  return filled;
444}
445
446let ianaZoneCache = {};
447/**
448 * A zone identified by an IANA identifier, like America/New_York
449 * @implements {Zone}
450 */
451class IANAZone extends Zone {
452  /**
453   * @param {string} name - Zone name
454   * @return {IANAZone}
455   */
456  static create(name) {
457    if (!ianaZoneCache[name]) {
458      ianaZoneCache[name] = new IANAZone(name);
459    }
460    return ianaZoneCache[name];
461  }
462
463  /**
464   * Reset local caches. Should only be necessary in testing scenarios.
465   * @return {void}
466   */
467  static resetCache() {
468    ianaZoneCache = {};
469    dtfCache = {};
470  }
471
472  /**
473   * Returns whether the provided string is a valid specifier. This only checks the string's format, not that the specifier identifies a known zone; see isValidZone for that.
474   * @param {string} s - The string to check validity on
475   * @example IANAZone.isValidSpecifier("America/New_York") //=> true
476   * @example IANAZone.isValidSpecifier("Sport~~blorp") //=> false
477   * @deprecated For backward compatibility, this forwards to isValidZone, better use `isValidZone()` directly instead.
478   * @return {boolean}
479   */
480  static isValidSpecifier(s) {
481    return this.isValidZone(s);
482  }
483
484  /**
485   * Returns whether the provided string identifies a real zone
486   * @param {string} zone - The string to check
487   * @example IANAZone.isValidZone("America/New_York") //=> true
488   * @example IANAZone.isValidZone("Fantasia/Castle") //=> false
489   * @example IANAZone.isValidZone("Sport~~blorp") //=> false
490   * @return {boolean}
491   */
492  static isValidZone(zone) {
493    if (!zone) {
494      return false;
495    }
496    try {
497      new Intl.DateTimeFormat("en-US", { timeZone: zone }).format();
498      return true;
499    } catch (e) {
500      return false;
501    }
502  }
503
504  constructor(name) {
505    super();
506    /** @private **/
507    this.zoneName = name;
508    /** @private **/
509    this.valid = IANAZone.isValidZone(name);
510  }
511
512  /**
513   * The type of zone. `iana` for all instances of `IANAZone`.
514   * @override
515   * @type {string}
516   */
517  get type() {
518    return "iana";
519  }
520
521  /**
522   * The name of this zone (i.e. the IANA zone name).
523   * @override
524   * @type {string}
525   */
526  get name() {
527    return this.zoneName;
528  }
529
530  /**
531   * Returns whether the offset is known to be fixed for the whole year:
532   * Always returns false for all IANA zones.
533   * @override
534   * @type {boolean}
535   */
536  get isUniversal() {
537    return false;
538  }
539
540  /**
541   * Returns the offset's common name (such as EST) at the specified timestamp
542   * @override
543   * @param {number} ts - Epoch milliseconds for which to get the name
544   * @param {Object} opts - Options to affect the format
545   * @param {string} opts.format - What style of offset to return. Accepts 'long' or 'short'.
546   * @param {string} opts.locale - What locale to return the offset name in.
547   * @return {string}
548   */
549  offsetName(ts, { format, locale }) {
550    return parseZoneInfo(ts, format, locale, this.name);
551  }
552
553  /**
554   * Returns the offset's value as a string
555   * @override
556   * @param {number} ts - Epoch milliseconds for which to get the offset
557   * @param {string} format - What style of offset to return.
558   *                          Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
559   * @return {string}
560   */
561  formatOffset(ts, format) {
562    return formatOffset(this.offset(ts), format);
563  }
564
565  /**
566   * Return the offset in minutes for this zone at the specified timestamp.
567   * @override
568   * @param {number} ts - Epoch milliseconds for which to compute the offset
569   * @return {number}
570   */
571  offset(ts) {
572    const date = new Date(ts);
573
574    if (isNaN(date)) return NaN;
575
576    const dtf = makeDTF(this.name);
577    let [year, month, day, adOrBc, hour, minute, second] = dtf.formatToParts
578      ? partsOffset(dtf, date)
579      : hackyOffset(dtf, date);
580
581    if (adOrBc === "BC") {
582      year = -Math.abs(year) + 1;
583    }
584
585    // because we're using hour12 and https://bugs.chromium.org/p/chromium/issues/detail?id=1025564&can=2&q=%2224%3A00%22%20datetimeformat
586    const adjustedHour = hour === 24 ? 0 : hour;
587
588    const asUTC = objToLocalTS({
589      year,
590      month,
591      day,
592      hour: adjustedHour,
593      minute,
594      second,
595      millisecond: 0,
596    });
597
598    let asTS = +date;
599    const over = asTS % 1000;
600    asTS -= over >= 0 ? over : 1000 + over;
601    return (asUTC - asTS) / (60 * 1000);
602  }
603
604  /**
605   * Return whether this Zone is equal to another zone
606   * @override
607   * @param {Zone} otherZone - the zone to compare
608   * @return {boolean}
609   */
610  equals(otherZone) {
611    return otherZone.type === "iana" && otherZone.name === this.name;
612  }
613
614  /**
615   * Return whether this Zone is valid.
616   * @override
617   * @type {boolean}
618   */
619  get isValid() {
620    return this.valid;
621  }
622}
623
624// todo - remap caching
625
626let intlLFCache = {};
627function getCachedLF(locString, opts = {}) {
628  const key = JSON.stringify([locString, opts]);
629  let dtf = intlLFCache[key];
630  if (!dtf) {
631    dtf = new Intl.ListFormat(locString, opts);
632    intlLFCache[key] = dtf;
633  }
634  return dtf;
635}
636
637let intlDTCache = {};
638function getCachedDTF(locString, opts = {}) {
639  const key = JSON.stringify([locString, opts]);
640  let dtf = intlDTCache[key];
641  if (!dtf) {
642    dtf = new Intl.DateTimeFormat(locString, opts);
643    intlDTCache[key] = dtf;
644  }
645  return dtf;
646}
647
648let intlNumCache = {};
649function getCachedINF(locString, opts = {}) {
650  const key = JSON.stringify([locString, opts]);
651  let inf = intlNumCache[key];
652  if (!inf) {
653    inf = new Intl.NumberFormat(locString, opts);
654    intlNumCache[key] = inf;
655  }
656  return inf;
657}
658
659let intlRelCache = {};
660function getCachedRTF(locString, opts = {}) {
661  const { base, ...cacheKeyOpts } = opts; // exclude `base` from the options
662  const key = JSON.stringify([locString, cacheKeyOpts]);
663  let inf = intlRelCache[key];
664  if (!inf) {
665    inf = new Intl.RelativeTimeFormat(locString, opts);
666    intlRelCache[key] = inf;
667  }
668  return inf;
669}
670
671let sysLocaleCache = null;
672function systemLocale() {
673  if (sysLocaleCache) {
674    return sysLocaleCache;
675  } else {
676    sysLocaleCache = new Intl.DateTimeFormat().resolvedOptions().locale;
677    return sysLocaleCache;
678  }
679}
680
681let weekInfoCache = {};
682function getCachedWeekInfo(locString) {
683  let data = weekInfoCache[locString];
684  if (!data) {
685    const locale = new Intl.Locale(locString);
686    // browsers currently implement this as a property, but spec says it should be a getter function
687    data = "getWeekInfo" in locale ? locale.getWeekInfo() : locale.weekInfo;
688    weekInfoCache[locString] = data;
689  }
690  return data;
691}
692
693function parseLocaleString(localeStr) {
694  // I really want to avoid writing a BCP 47 parser
695  // see, e.g. https://github.com/wooorm/bcp-47
696  // Instead, we'll do this:
697
698  // a) if the string has no -u extensions, just leave it alone
699  // b) if it does, use Intl to resolve everything
700  // c) if Intl fails, try again without the -u
701
702  // private subtags and unicode subtags have ordering requirements,
703  // and we're not properly parsing this, so just strip out the
704  // private ones if they exist.
705  const xIndex = localeStr.indexOf("-x-");
706  if (xIndex !== -1) {
707    localeStr = localeStr.substring(0, xIndex);
708  }
709
710  const uIndex = localeStr.indexOf("-u-");
711  if (uIndex === -1) {
712    return [localeStr];
713  } else {
714    let options;
715    let selectedStr;
716    try {
717      options = getCachedDTF(localeStr).resolvedOptions();
718      selectedStr = localeStr;
719    } catch (e) {
720      const smaller = localeStr.substring(0, uIndex);
721      options = getCachedDTF(smaller).resolvedOptions();
722      selectedStr = smaller;
723    }
724
725    const { numberingSystem, calendar } = options;
726    return [selectedStr, numberingSystem, calendar];
727  }
728}
729
730function intlConfigString(localeStr, numberingSystem, outputCalendar) {
731  if (outputCalendar || numberingSystem) {
732    if (!localeStr.includes("-u-")) {
733      localeStr += "-u";
734    }
735
736    if (outputCalendar) {
737      localeStr += `-ca-${outputCalendar}`;
738    }
739
740    if (numberingSystem) {
741      localeStr += `-nu-${numberingSystem}`;
742    }
743    return localeStr;
744  } else {
745    return localeStr;
746  }
747}
748
749function mapMonths(f) {
750  const ms = [];
751  for (let i = 1; i <= 12; i++) {
752    const dt = DateTime.utc(2009, i, 1);
753    ms.push(f(dt));
754  }
755  return ms;
756}
757
758function mapWeekdays(f) {
759  const ms = [];
760  for (let i = 1; i <= 7; i++) {
761    const dt = DateTime.utc(2016, 11, 13 + i);
762    ms.push(f(dt));
763  }
764  return ms;
765}
766
767function listStuff(loc, length, englishFn, intlFn) {
768  const mode = loc.listingMode();
769
770  if (mode === "error") {
771    return null;
772  } else if (mode === "en") {
773    return englishFn(length);
774  } else {
775    return intlFn(length);
776  }
777}
778
779function supportsFastNumbers(loc) {
780  if (loc.numberingSystem && loc.numberingSystem !== "latn") {
781    return false;
782  } else {
783    return (
784      loc.numberingSystem === "latn" ||
785      !loc.locale ||
786      loc.locale.startsWith("en") ||
787      new Intl.DateTimeFormat(loc.intl).resolvedOptions().numberingSystem === "latn"
788    );
789  }
790}
791
792/**
793 * @private
794 */
795
796class PolyNumberFormatter {
797  constructor(intl, forceSimple, opts) {
798    this.padTo = opts.padTo || 0;
799    this.floor = opts.floor || false;
800
801    const { padTo, floor, ...otherOpts } = opts;
802
803    if (!forceSimple || Object.keys(otherOpts).length > 0) {
804      const intlOpts = { useGrouping: false, ...opts };
805      if (opts.padTo > 0) intlOpts.minimumIntegerDigits = opts.padTo;
806      this.inf = getCachedINF(intl, intlOpts);
807    }
808  }
809
810  format(i) {
811    if (this.inf) {
812      const fixed = this.floor ? Math.floor(i) : i;
813      return this.inf.format(fixed);
814    } else {
815      // to match the browser's numberformatter defaults
816      const fixed = this.floor ? Math.floor(i) : roundTo(i, 3);
817      return padStart(fixed, this.padTo);
818    }
819  }
820}
821
822/**
823 * @private
824 */
825
826class PolyDateFormatter {
827  constructor(dt, intl, opts) {
828    this.opts = opts;
829    this.originalZone = undefined;
830
831    let z = undefined;
832    if (this.opts.timeZone) {
833      // Don't apply any workarounds if a timeZone is explicitly provided in opts
834      this.dt = dt;
835    } else if (dt.zone.type === "fixed") {
836      // UTC-8 or Etc/UTC-8 are not part of tzdata, only Etc/GMT+8 and the like.
837      // That is why fixed-offset TZ is set to that unless it is:
838      // 1. Representing offset 0 when UTC is used to maintain previous behavior and does not become GMT.
839      // 2. Unsupported by the browser:
840      //    - some do not support Etc/
841      //    - < Etc/GMT-14, > Etc/GMT+12, and 30-minute or 45-minute offsets are not part of tzdata
842      const gmtOffset = -1 * (dt.offset / 60);
843      const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
844      if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) {
845        z = offsetZ;
846        this.dt = dt;
847      } else {
848        // Not all fixed-offset zones like Etc/+4:30 are present in tzdata so
849        // we manually apply the offset and substitute the zone as needed.
850        z = "UTC";
851        this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset });
852        this.originalZone = dt.zone;
853      }
854    } else if (dt.zone.type === "system") {
855      this.dt = dt;
856    } else if (dt.zone.type === "iana") {
857      this.dt = dt;
858      z = dt.zone.name;
859    } else {
860      // Custom zones can have any offset / offsetName so we just manually
861      // apply the offset and substitute the zone as needed.
862      z = "UTC";
863      this.dt = dt.setZone("UTC").plus({ minutes: dt.offset });
864      this.originalZone = dt.zone;
865    }
866
867    const intlOpts = { ...this.opts };
868    intlOpts.timeZone = intlOpts.timeZone || z;
869    this.dtf = getCachedDTF(intl, intlOpts);
870  }
871
872  format() {
873    if (this.originalZone) {
874      // If we have to substitute in the actual zone name, we have to use
875      // formatToParts so that the timezone can be replaced.
876      return this.formatToParts()
877        .map(({ value }) => value)
878        .join("");
879    }
880    return this.dtf.format(this.dt.toJSDate());
881  }
882
883  formatToParts() {
884    const parts = this.dtf.formatToParts(this.dt.toJSDate());
885    if (this.originalZone) {
886      return parts.map((part) => {
887        if (part.type === "timeZoneName") {
888          const offsetName = this.originalZone.offsetName(this.dt.ts, {
889            locale: this.dt.locale,
890            format: this.opts.timeZoneName,
891          });
892          return {
893            ...part,
894            value: offsetName,
895          };
896        } else {
897          return part;
898        }
899      });
900    }
901    return parts;
902  }
903
904  resolvedOptions() {
905    return this.dtf.resolvedOptions();
906  }
907}
908
909/**
910 * @private
911 */
912class PolyRelFormatter {
913  constructor(intl, isEnglish, opts) {
914    this.opts = { style: "long", ...opts };
915    if (!isEnglish && hasRelative()) {
916      this.rtf = getCachedRTF(intl, opts);
917    }
918  }
919
920  format(count, unit) {
921    if (this.rtf) {
922      return this.rtf.format(count, unit);
923    } else {
924      return formatRelativeTime(unit, count, this.opts.numeric, this.opts.style !== "long");
925    }
926  }
927
928  formatToParts(count, unit) {
929    if (this.rtf) {
930      return this.rtf.formatToParts(count, unit);
931    } else {
932      return [];
933    }
934  }
935}
936
937const fallbackWeekSettings = {
938  firstDay: 1,
939  minimalDays: 4,
940  weekend: [6, 7],
941};
942
943/**
944 * @private
945 */
946
947class Locale {
948  static fromOpts(opts) {
949    return Locale.create(
950      opts.locale,
951      opts.numberingSystem,
952      opts.outputCalendar,
953      opts.weekSettings,
954      opts.defaultToEN
955    );
956  }
957
958  static create(locale, numberingSystem, outputCalendar, weekSettings, defaultToEN = false) {
959    const specifiedLocale = locale || Settings.defaultLocale;
960    // the system locale is useful for human-readable strings but annoying for parsing/formatting known formats
961    const localeR = specifiedLocale || (defaultToEN ? "en-US" : systemLocale());
962    const numberingSystemR = numberingSystem || Settings.defaultNumberingSystem;
963    const outputCalendarR = outputCalendar || Settings.defaultOutputCalendar;
964    const weekSettingsR = validateWeekSettings(weekSettings) || Settings.defaultWeekSettings;
965    return new Locale(localeR, numberingSystemR, outputCalendarR, weekSettingsR, specifiedLocale);
966  }
967
968  static resetCache() {
969    sysLocaleCache = null;
970    intlDTCache = {};
971    intlNumCache = {};
972    intlRelCache = {};
973  }
974
975  static fromObject({ locale, numberingSystem, outputCalendar, weekSettings } = {}) {
976    return Locale.create(locale, numberingSystem, outputCalendar, weekSettings);
977  }
978
979  constructor(locale, numbering, outputCalendar, weekSettings, specifiedLocale) {
980    const [parsedLocale, parsedNumberingSystem, parsedOutputCalendar] = parseLocaleString(locale);
981
982    this.locale = parsedLocale;
983    this.numberingSystem = numbering || parsedNumberingSystem || null;
984    this.outputCalendar = outputCalendar || parsedOutputCalendar || null;
985    this.weekSettings = weekSettings;
986    this.intl = intlConfigString(this.locale, this.numberingSystem, this.outputCalendar);
987
988    this.weekdaysCache = { format: {}, standalone: {} };
989    this.monthsCache = { format: {}, standalone: {} };
990    this.meridiemCache = null;
991    this.eraCache = {};
992
993    this.specifiedLocale = specifiedLocale;
994    this.fastNumbersCached = null;
995  }
996
997  get fastNumbers() {
998    if (this.fastNumbersCached == null) {
999      this.fastNumbersCached = supportsFastNumbers(this);
1000    }
1001
1002    return this.fastNumbersCached;
1003  }
1004
1005  listingMode() {
1006    const isActuallyEn = this.isEnglish();
1007    const hasNoWeirdness =
1008      (this.numberingSystem === null || this.numberingSystem === "latn") &&
1009      (this.outputCalendar === null || this.outputCalendar === "gregory");
1010    return isActuallyEn && hasNoWeirdness ? "en" : "intl";
1011  }
1012
1013  clone(alts) {
1014    if (!alts || Object.getOwnPropertyNames(alts).length === 0) {
1015      return this;
1016    } else {
1017      return Locale.create(
1018        alts.locale || this.specifiedLocale,
1019        alts.numberingSystem || this.numberingSystem,
1020        alts.outputCalendar || this.outputCalendar,
1021        validateWeekSettings(alts.weekSettings) || this.weekSettings,
1022        alts.defaultToEN || false
1023      );
1024    }
1025  }
1026
1027  redefaultToEN(alts = {}) {
1028    return this.clone({ ...alts, defaultToEN: true });
1029  }
1030
1031  redefaultToSystem(alts = {}) {
1032    return this.clone({ ...alts, defaultToEN: false });
1033  }
1034
1035  months(length, format = false) {
1036    return listStuff(this, length, months, () => {
1037      const intl = format ? { month: length, day: "numeric" } : { month: length },
1038        formatStr = format ? "format" : "standalone";
1039      if (!this.monthsCache[formatStr][length]) {
1040        this.monthsCache[formatStr][length] = mapMonths((dt) => this.extract(dt, intl, "month"));
1041      }
1042      return this.monthsCache[formatStr][length];
1043    });
1044  }
1045
1046  weekdays(length, format = false) {
1047    return listStuff(this, length, weekdays, () => {
1048      const intl = format
1049          ? { weekday: length, year: "numeric", month: "long", day: "numeric" }
1050          : { weekday: length },
1051        formatStr = format ? "format" : "standalone";
1052      if (!this.weekdaysCache[formatStr][length]) {
1053        this.weekdaysCache[formatStr][length] = mapWeekdays((dt) =>
1054          this.extract(dt, intl, "weekday")
1055        );
1056      }
1057      return this.weekdaysCache[formatStr][length];
1058    });
1059  }
1060
1061  meridiems() {
1062    return listStuff(
1063      this,
1064      undefined,
1065      () => meridiems,
1066      () => {
1067        // In theory there could be aribitrary day periods. We're gonna assume there are exactly two
1068        // for AM and PM. This is probably wrong, but it's makes parsing way easier.
1069        if (!this.meridiemCache) {
1070          const intl = { hour: "numeric", hourCycle: "h12" };
1071          this.meridiemCache = [DateTime.utc(2016, 11, 13, 9), DateTime.utc(2016, 11, 13, 19)].map(
1072            (dt) => this.extract(dt, intl, "dayperiod")
1073          );
1074        }
1075
1076        return this.meridiemCache;
1077      }
1078    );
1079  }
1080
1081  eras(length) {
1082    return listStuff(this, length, eras, () => {
1083      const intl = { era: length };
1084
1085      // This is problematic. Different calendars are going to define eras totally differently. What I need is the minimum set of dates
1086      // to definitely enumerate them.
1087      if (!this.eraCache[length]) {
1088        this.eraCache[length] = [DateTime.utc(-40, 1, 1), DateTime.utc(2017, 1, 1)].map((dt) =>
1089          this.extract(dt, intl, "era")
1090        );
1091      }
1092
1093      return this.eraCache[length];
1094    });
1095  }
1096
1097  extract(dt, intlOpts, field) {
1098    const df = this.dtFormatter(dt, intlOpts),
1099      results = df.formatToParts(),
1100      matching = results.find((m) => m.type.toLowerCase() === field);
1101    return matching ? matching.value : null;
1102  }
1103
1104  numberFormatter(opts = {}) {
1105    // this forcesimple option is never used (the only caller short-circuits on it, but it seems safer to leave)
1106    // (in contrast, the rest of the condition is used heavily)
1107    return new PolyNumberFormatter(this.intl, opts.forceSimple || this.fastNumbers, opts);
1108  }
1109
1110  dtFormatter(dt, intlOpts = {}) {
1111    return new PolyDateFormatter(dt, this.intl, intlOpts);
1112  }
1113
1114  relFormatter(opts = {}) {
1115    return new PolyRelFormatter(this.intl, this.isEnglish(), opts);
1116  }
1117
1118  listFormatter(opts = {}) {
1119    return getCachedLF(this.intl, opts);
1120  }
1121
1122  isEnglish() {
1123    return (
1124      this.locale === "en" ||
1125      this.locale.toLowerCase() === "en-us" ||
1126      new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us")
1127    );
1128  }
1129
1130  getWeekSettings() {
1131    if (this.weekSettings) {
1132      return this.weekSettings;
1133    } else if (!hasLocaleWeekInfo()) {
1134      return fallbackWeekSettings;
1135    } else {
1136      return getCachedWeekInfo(this.locale);
1137    }
1138  }
1139
1140  getStartOfWeek() {
1141    return this.getWeekSettings().firstDay;
1142  }
1143
1144  getMinDaysInFirstWeek() {
1145    return this.getWeekSettings().minimalDays;
1146  }
1147
1148  getWeekendDays() {
1149    return this.getWeekSettings().weekend;
1150  }
1151
1152  equals(other) {
1153    return (
1154      this.locale === other.locale &&
1155      this.numberingSystem === other.numberingSystem &&
1156      this.outputCalendar === other.outputCalendar
1157    );
1158  }
1159
1160  toString() {
1161    return `Locale(${this.locale}, ${this.numberingSystem}, ${this.outputCalendar})`;
1162  }
1163}
1164
1165let singleton = null;
1166
1167/**
1168 * A zone with a fixed offset (meaning no DST)
1169 * @implements {Zone}
1170 */
1171class FixedOffsetZone extends Zone {
1172  /**
1173   * Get a singleton instance of UTC
1174   * @return {FixedOffsetZone}
1175   */
1176  static get utcInstance() {
1177    if (singleton === null) {
1178      singleton = new FixedOffsetZone(0);
1179    }
1180    return singleton;
1181  }
1182
1183  /**
1184   * Get an instance with a specified offset
1185   * @param {number} offset - The offset in minutes
1186   * @return {FixedOffsetZone}
1187   */
1188  static instance(offset) {
1189    return offset === 0 ? FixedOffsetZone.utcInstance : new FixedOffsetZone(offset);
1190  }
1191
1192  /**
1193   * Get an instance of FixedOffsetZone from a UTC offset string, like "UTC+6"
1194   * @param {string} s - The offset string to parse
1195   * @example FixedOffsetZone.parseSpecifier("UTC+6")
1196   * @example FixedOffsetZone.parseSpecifier("UTC+06")
1197   * @example FixedOffsetZone.parseSpecifier("UTC-6:00")
1198   * @return {FixedOffsetZone}
1199   */
1200  static parseSpecifier(s) {
1201    if (s) {
1202      const r = s.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i);
1203      if (r) {
1204        return new FixedOffsetZone(signedOffset(r[1], r[2]));
1205      }
1206    }
1207    return null;
1208  }
1209
1210  constructor(offset) {
1211    super();
1212    /** @private **/
1213    this.fixed = offset;
1214  }
1215
1216  /**
1217   * The type of zone. `fixed` for all instances of `FixedOffsetZone`.
1218   * @override
1219   * @type {string}
1220   */
1221  get type() {
1222    return "fixed";
1223  }
1224
1225  /**
1226   * The name of this zone.
1227   * All fixed zones' names always start with "UTC" (plus optional offset)
1228   * @override
1229   * @type {string}
1230   */
1231  get name() {
1232    return this.fixed === 0 ? "UTC" : `UTC${formatOffset(this.fixed, "narrow")}`;
1233  }
1234
1235  /**
1236   * The IANA name of this zone, i.e. `Etc/UTC` or `Etc/GMT+/-nn`
1237   *
1238   * @override
1239   * @type {string}
1240   */
1241  get ianaName() {
1242    if (this.fixed === 0) {
vendor: 5,540 bytes, lines 1243-1479
1243      return "Etc/UTC";
1244    } else {
1245      return `Etc/GMT${formatOffset(-this.fixed, "narrow")}`;
1246    }
1247  }
1248
1249  /**
1250   * Returns the offset's common name at the specified timestamp.
1251   *
1252   * For fixed offset zones this equals to the zone name.
1253   * @override
1254   */
1255  offsetName() {
1256    return this.name;
1257  }
1258
1259  /**
1260   * Returns the offset's value as a string
1261   * @override
1262   * @param {number} ts - Epoch milliseconds for which to get the offset
1263   * @param {string} format - What style of offset to return.
1264   *                          Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
1265   * @return {string}
1266   */
1267  formatOffset(ts, format) {
1268    return formatOffset(this.fixed, format);
1269  }
1270
1271  /**
1272   * Returns whether the offset is known to be fixed for the whole year:
1273   * Always returns true for all fixed offset zones.
1274   * @override
1275   * @type {boolean}
1276   */
1277  get isUniversal() {
1278    return true;
1279  }
1280
1281  /**
1282   * Return the offset in minutes for this zone at the specified timestamp.
1283   *
1284   * For fixed offset zones, this is constant and does not depend on a timestamp.
1285   * @override
1286   * @return {number}
1287   */
1288  offset() {
1289    return this.fixed;
1290  }
1291
1292  /**
1293   * Return whether this Zone is equal to another zone (i.e. also fixed and same offset)
1294   * @override
1295   * @param {Zone} otherZone - the zone to compare
1296   * @return {boolean}
1297   */
1298  equals(otherZone) {
1299    return otherZone.type === "fixed" && otherZone.fixed === this.fixed;
1300  }
1301
1302  /**
1303   * Return whether this Zone is valid:
1304   * All fixed offset zones are valid.
1305   * @override
1306   * @type {boolean}
1307   */
1308  get isValid() {
1309    return true;
1310  }
1311}
1312
1313/**
1314 * A zone that failed to parse. You should never need to instantiate this.
1315 * @implements {Zone}
1316 */
1317class InvalidZone extends Zone {
1318  constructor(zoneName) {
1319    super();
1320    /**  @private */
1321    this.zoneName = zoneName;
1322  }
1323
1324  /** @override **/
1325  get type() {
1326    return "invalid";
1327  }
1328
1329  /** @override **/
1330  get name() {
1331    return this.zoneName;
1332  }
1333
1334  /** @override **/
1335  get isUniversal() {
1336    return false;
1337  }
1338
1339  /** @override **/
1340  offsetName() {
1341    return null;
1342  }
1343
1344  /** @override **/
1345  formatOffset() {
1346    return "";
1347  }
1348
1349  /** @override **/
1350  offset() {
1351    return NaN;
1352  }
1353
1354  /** @override **/
1355  equals() {
1356    return false;
1357  }
1358
1359  /** @override **/
1360  get isValid() {
1361    return false;
1362  }
1363}
1364
1365/**
1366 * @private
1367 */
1368
1369function normalizeZone(input, defaultZone) {
1370  if (isUndefined(input) || input === null) {
1371    return defaultZone;
1372  } else if (input instanceof Zone) {
1373    return input;
1374  } else if (isString(input)) {
1375    const lowered = input.toLowerCase();
1376    if (lowered === "default") return defaultZone;
1377    else if (lowered === "local" || lowered === "system") return SystemZone.instance;
1378    else if (lowered === "utc" || lowered === "gmt") return FixedOffsetZone.utcInstance;
1379    else return FixedOffsetZone.parseSpecifier(lowered) || IANAZone.create(input);
1380  } else if (isNumber(input)) {
1381    return FixedOffsetZone.instance(input);
1382  } else if (typeof input === "object" && "offset" in input && typeof input.offset === "function") {
1383    // This is dumb, but the instanceof check above doesn't seem to really work
1384    // so we're duck checking it
1385    return input;
1386  } else {
1387    return new InvalidZone(input);
1388  }
1389}
1390
1391const numberingSystems = {
1392  arab: "[\u0660-\u0669]",
1393  arabext: "[\u06F0-\u06F9]",
1394  bali: "[\u1B50-\u1B59]",
1395  beng: "[\u09E6-\u09EF]",
1396  deva: "[\u0966-\u096F]",
1397  fullwide: "[\uFF10-\uFF19]",
1398  gujr: "[\u0AE6-\u0AEF]",
1399  hanidec: "[〇|一|二|三|四|五|六|七|八|九]",
1400  khmr: "[\u17E0-\u17E9]",
1401  knda: "[\u0CE6-\u0CEF]",
1402  laoo: "[\u0ED0-\u0ED9]",
1403  limb: "[\u1946-\u194F]",
1404  mlym: "[\u0D66-\u0D6F]",
1405  mong: "[\u1810-\u1819]",
1406  mymr: "[\u1040-\u1049]",
1407  orya: "[\u0B66-\u0B6F]",
1408  tamldec: "[\u0BE6-\u0BEF]",
1409  telu: "[\u0C66-\u0C6F]",
1410  thai: "[\u0E50-\u0E59]",
1411  tibt: "[\u0F20-\u0F29]",
1412  latn: "\\d",
1413};
1414
1415const numberingSystemsUTF16 = {
1416  arab: [1632, 1641],
1417  arabext: [1776, 1785],
1418  bali: [6992, 7001],
1419  beng: [2534, 2543],
1420  deva: [2406, 2415],
1421  fullwide: [65296, 65303],
1422  gujr: [2790, 2799],
1423  khmr: [6112, 6121],
1424  knda: [3302, 3311],
1425  laoo: [3792, 3801],
1426  limb: [6470, 6479],
1427  mlym: [3430, 3439],
1428  mong: [6160, 6169],
1429  mymr: [4160, 4169],
1430  orya: [2918, 2927],
1431  tamldec: [3046, 3055],
1432  telu: [3174, 3183],
1433  thai: [3664, 3673],
1434  tibt: [3872, 3881],
1435};
1436
1437const hanidecChars = numberingSystems.hanidec.replace(/[\[|\]]/g, "").split("");
1438
1439function parseDigits(str) {
1440  let value = parseInt(str, 10);
1441  if (isNaN(value)) {
1442    value = "";
1443    for (let i = 0; i < str.length; i++) {
1444      const code = str.charCodeAt(i);
1445
1446      if (str[i].search(numberingSystems.hanidec) !== -1) {
1447        value += hanidecChars.indexOf(str[i]);
1448      } else {
1449        for (const key in numberingSystemsUTF16) {
1450          const [min, max] = numberingSystemsUTF16[key];
1451          if (code >= min && code <= max) {
1452            value += code - min;
1453          }
1454        }
1455      }
1456    }
1457    return parseInt(value, 10);
1458  } else {
1459    return value;
1460  }
1461}
1462
1463// cache of {numberingSystem: {append: regex}}
1464let digitRegexCache = {};
1465function resetDigitRegexCache() {
1466  digitRegexCache = {};
1467}
1468
1469function digitRegex({ numberingSystem }, append = "") {
1470  const ns = numberingSystem || "latn";
1471
1472  if (!digitRegexCache[ns]) {
1473    digitRegexCache[ns] = {};
1474  }
1475  if (!digitRegexCache[ns][append]) {
1476    digitRegexCache[ns][append] = new RegExp(`${numberingSystems[ns]}${append}`);
1477  }
1478
1479  return digitRegexCache[ns][append]
vendor: 15,126 bytes, lines 1479-2020
1479;
1480}
1481
1482let now = () => Date.now(),
1483  defaultZone = "system",
1484  defaultLocale = null,
1485  defaultNumberingSystem = null,
1486  defaultOutputCalendar = null,
1487  twoDigitCutoffYear = 60,
1488  throwOnInvalid,
1489  defaultWeekSettings = null;
1490
1491/**
1492 * Settings contains static getters and setters that control Luxon's overall behavior. Luxon is a simple library with few options, but the ones it does have live here.
1493 */
1494class Settings {
1495  /**
1496   * Get the callback for returning the current timestamp.
1497   * @type {function}
1498   */
1499  static get now() {
1500    return now;
1501  }
1502
1503  /**
1504   * Set the callback for returning the current timestamp.
1505   * The function should return a number, which will be interpreted as an Epoch millisecond count
1506   * @type {function}
1507   * @example Settings.now = () => Date.now() + 3000 // pretend it is 3 seconds in the future
1508   * @example Settings.now = () => 0 // always pretend it's Jan 1, 1970 at midnight in UTC time
1509   */
1510  static set now(n) {
1511    now = n;
1512  }
1513
1514  /**
1515   * Set the default time zone to create DateTimes in. Does not affect existing instances.
1516   * Use the value "system" to reset this value to the system's time zone.
1517   * @type {string}
1518   */
1519  static set defaultZone(zone) {
1520    defaultZone = zone;
1521  }
1522
1523  /**
1524   * Get the default time zone object currently used to create DateTimes. Does not affect existing instances.
1525   * The default value is the system's time zone (the one set on the machine that runs this code).
1526   * @type {Zone}
1527   */
1528  static get defaultZone() {
1529    return normalizeZone(defaultZone, SystemZone.instance);
1530  }
1531
1532  /**
1533   * Get the default locale to create DateTimes with. Does not affect existing instances.
1534   * @type {string}
1535   */
1536  static get defaultLocale() {
1537    return defaultLocale;
1538  }
1539
1540  /**
1541   * Set the default locale to create DateTimes with. Does not affect existing instances.
1542   * @type {string}
1543   */
1544  static set defaultLocale(locale) {
1545    defaultLocale = locale;
1546  }
1547
1548  /**
1549   * Get the default numbering system to create DateTimes with. Does not affect existing instances.
1550   * @type {string}
1551   */
1552  static get defaultNumberingSystem() {
1553    return defaultNumberingSystem;
1554  }
1555
1556  /**
1557   * Set the default numbering system to create DateTimes with. Does not affect existing instances.
1558   * @type {string}
1559   */
1560  static set defaultNumberingSystem(numberingSystem) {
1561    defaultNumberingSystem = numberingSystem;
1562  }
1563
1564  /**
1565   * Get the default output calendar to create DateTimes with. Does not affect existing instances.
1566   * @type {string}
1567   */
1568  static get defaultOutputCalendar() {
1569    return defaultOutputCalendar;
1570  }
1571
1572  /**
1573   * Set the default output calendar to create DateTimes with. Does not affect existing instances.
1574   * @type {string}
1575   */
1576  static set defaultOutputCalendar(outputCalendar) {
1577    defaultOutputCalendar = outputCalendar;
1578  }
1579
1580  /**
1581   * @typedef {Object} WeekSettings
1582   * @property {number} firstDay
1583   * @property {number} minimalDays
1584   * @property {number[]} weekend
1585   */
1586
1587  /**
1588   * @return {WeekSettings|null}
1589   */
1590  static get defaultWeekSettings() {
1591    return defaultWeekSettings;
1592  }
1593
1594  /**
1595   * Allows overriding the default locale week settings, i.e. the start of the week, the weekend and
1596   * how many days are required in the first week of a year.
1597   * Does not affect existing instances.
1598   *
1599   * @param {WeekSettings|null} weekSettings
1600   */
1601  static set defaultWeekSettings(weekSettings) {
1602    defaultWeekSettings = validateWeekSettings(weekSettings);
1603  }
1604
1605  /**
1606   * Get the cutoff year for whether a 2-digit year string is interpreted in the current or previous century. Numbers higher than the cutoff will be considered to mean 19xx and numbers lower or equal to the cutoff will be considered 20xx.
1607   * @type {number}
1608   */
1609  static get twoDigitCutoffYear() {
1610    return twoDigitCutoffYear;
1611  }
1612
1613  /**
1614   * Set the cutoff year for whether a 2-digit year string is interpreted in the current or previous century. Numbers higher than the cutoff will be considered to mean 19xx and numbers lower or equal to the cutoff will be considered 20xx.
1615   * @type {number}
1616   * @example Settings.twoDigitCutoffYear = 0 // all 'yy' are interpreted as 20th century
1617   * @example Settings.twoDigitCutoffYear = 99 // all 'yy' are interpreted as 21st century
1618   * @example Settings.twoDigitCutoffYear = 50 // '49' -> 2049; '50' -> 1950
1619   * @example Settings.twoDigitCutoffYear = 1950 // interpreted as 50
1620   * @example Settings.twoDigitCutoffYear = 2050 // ALSO interpreted as 50
1621   */
1622  static set twoDigitCutoffYear(cutoffYear) {
1623    twoDigitCutoffYear = cutoffYear % 100;
1624  }
1625
1626  /**
1627   * Get whether Luxon will throw when it encounters invalid DateTimes, Durations, or Intervals
1628   * @type {boolean}
1629   */
1630  static get throwOnInvalid() {
1631    return throwOnInvalid;
1632  }
1633
1634  /**
1635   * Set whether Luxon will throw when it encounters invalid DateTimes, Durations, or Intervals
1636   * @type {boolean}
1637   */
1638  static set throwOnInvalid(t) {
1639    throwOnInvalid = t;
1640  }
1641
1642  /**
1643   * Reset Luxon's global caches. Should only be necessary in testing scenarios.
1644   * @return {void}
1645   */
1646  static resetCaches() {
1647    Locale.resetCache();
1648    IANAZone.resetCache();
1649    DateTime.resetCache();
1650    resetDigitRegexCache();
1651  }
1652}
1653
1654class Invalid {
1655  constructor(reason, explanation) {
1656    this.reason = reason;
1657    this.explanation = explanation;
1658  }
1659
1660  toMessage() {
1661    if (this.explanation) {
1662      return `${this.reason}: ${this.explanation}`;
1663    } else {
1664      return this.reason;
1665    }
1666  }
1667}
1668
1669const nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
1670  leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
1671
1672function unitOutOfRange(unit, value) {
1673  return new Invalid(
1674    "unit out of range",
1675    `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`
1676  );
1677}
1678
1679function dayOfWeek(year, month, day) {
1680  const d = new Date(Date.UTC(year, month - 1, day));
1681
1682  if (year < 100 && year >= 0) {
1683    d.setUTCFullYear(d.getUTCFullYear() - 1900);
1684  }
1685
1686  const js = d.getUTCDay();
1687
1688  return js === 0 ? 7 : js;
1689}
1690
1691function computeOrdinal(year, month, day) {
1692  return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1];
1693}
1694
1695function uncomputeOrdinal(year, ordinal) {
1696  const table = isLeapYear(year) ? leapLadder : nonLeapLadder,
1697    month0 = table.findIndex((i) => i < ordinal),
1698    day = ordinal - table[month0];
1699  return { month: month0 + 1, day };
1700}
1701
1702function isoWeekdayToLocal(isoWeekday, startOfWeek) {
1703  return ((isoWeekday - startOfWeek + 7) % 7) + 1;
1704}
1705
1706/**
1707 * @private
1708 */
1709
1710function gregorianToWeek(gregObj, minDaysInFirstWeek = 4, startOfWeek = 1) {
1711  const { year, month, day } = gregObj,
1712    ordinal = computeOrdinal(year, month, day),
1713    weekday = isoWeekdayToLocal(dayOfWeek(year, month, day), startOfWeek);
1714
1715  let weekNumber = Math.floor((ordinal - weekday + 14 - minDaysInFirstWeek) / 7),
1716    weekYear;
1717
1718  if (weekNumber < 1) {
1719    weekYear = year - 1;
1720    weekNumber = weeksInWeekYear(weekYear, minDaysInFirstWeek, startOfWeek);
1721  } else if (weekNumber > weeksInWeekYear(year, minDaysInFirstWeek, startOfWeek)) {
1722    weekYear = year + 1;
1723    weekNumber = 1;
1724  } else {
1725    weekYear = year;
1726  }
1727
1728  return { weekYear, weekNumber, weekday, ...timeObject(gregObj) };
1729}
1730
1731function weekToGregorian(weekData, minDaysInFirstWeek = 4, startOfWeek = 1) {
1732  const { weekYear, weekNumber, weekday } = weekData,
1733    weekdayOfJan4 = isoWeekdayToLocal(dayOfWeek(weekYear, 1, minDaysInFirstWeek), startOfWeek),
1734    yearInDays = daysInYear(weekYear);
1735
1736  let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 7 + minDaysInFirstWeek,
1737    year;
1738
1739  if (ordinal < 1) {
1740    year = weekYear - 1;
1741    ordinal += daysInYear(year);
1742  } else if (ordinal > yearInDays) {
1743    year = weekYear + 1;
1744    ordinal -= daysInYear(weekYear);
1745  } else {
1746    year = weekYear;
1747  }
1748
1749  const { month, day } = uncomputeOrdinal(year, ordinal);
1750  return { year, month, day, ...timeObject(weekData) };
1751}
1752
1753function gregorianToOrdinal(gregData) {
1754  const { year, month, day } = gregData;
1755  const ordinal = computeOrdinal(year, month, day);
1756  return { year, ordinal, ...timeObject(gregData) };
1757}
1758
1759function ordinalToGregorian(ordinalData) {
1760  const { year, ordinal } = ordinalData;
1761  const { month, day } = uncomputeOrdinal(year, ordinal);
1762  return { year, month, day, ...timeObject(ordinalData) };
1763}
1764
1765/**
1766 * Check if local week units like localWeekday are used in obj.
1767 * If so, validates that they are not mixed with ISO week units and then copies them to the normal week unit properties.
1768 * Modifies obj in-place!
1769 * @param obj the object values
1770 */
1771function usesLocalWeekValues(obj, loc) {
1772  const hasLocaleWeekData =
1773    !isUndefined(obj.localWeekday) ||
1774    !isUndefined(obj.localWeekNumber) ||
1775    !isUndefined(obj.localWeekYear);
1776  if (hasLocaleWeekData) {
1777    const hasIsoWeekData =
1778      !isUndefined(obj.weekday) || !isUndefined(obj.weekNumber) || !isUndefined(obj.weekYear);
1779
1780    if (hasIsoWeekData) {
1781      throw new ConflictingSpecificationError(
1782        "Cannot mix locale-based week fields with ISO-based week fields"
1783      );
1784    }
1785    if (!isUndefined(obj.localWeekday)) obj.weekday = obj.localWeekday;
1786    if (!isUndefined(obj.localWeekNumber)) obj.weekNumber = obj.localWeekNumber;
1787    if (!isUndefined(obj.localWeekYear)) obj.weekYear = obj.localWeekYear;
1788    delete obj.localWeekday;
1789    delete obj.localWeekNumber;
1790    delete obj.localWeekYear;
1791    return {
1792      minDaysInFirstWeek: loc.getMinDaysInFirstWeek(),
1793      startOfWeek: loc.getStartOfWeek(),
1794    };
1795  } else {
1796    return { minDaysInFirstWeek: 4, startOfWeek: 1 };
1797  }
1798}
1799
1800function hasInvalidWeekData(obj, minDaysInFirstWeek = 4, startOfWeek = 1) {
1801  const validYear = isInteger(obj.weekYear),
1802    validWeek = integerBetween(
1803      obj.weekNumber,
1804      1,
1805      weeksInWeekYear(obj.weekYear, minDaysInFirstWeek, startOfWeek)
1806    ),
1807    validWeekday = integerBetween(obj.weekday, 1, 7);
1808
1809  if (!validYear) {
1810    return unitOutOfRange("weekYear", obj.weekYear);
1811  } else if (!validWeek) {
1812    return unitOutOfRange("week", obj.weekNumber);
1813  } else if (!validWeekday) {
1814    return unitOutOfRange("weekday", obj.weekday);
1815  } else return false;
1816}
1817
1818function hasInvalidOrdinalData(obj) {
1819  const validYear = isInteger(obj.year),
1820    validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year));
1821
1822  if (!validYear) {
1823    return unitOutOfRange("year", obj.year);
1824  } else if (!validOrdinal) {
1825    return unitOutOfRange("ordinal", obj.ordinal);
1826  } else return false;
1827}
1828
1829function hasInvalidGregorianData(obj) {
1830  const validYear = isInteger(obj.year),
1831    validMonth = integerBetween(obj.month, 1, 12),
1832    validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month));
1833
1834  if (!validYear) {
1835    return unitOutOfRange("year", obj.year);
1836  } else if (!validMonth) {
1837    return unitOutOfRange("month", obj.month);
1838  } else if (!validDay) {
1839    return unitOutOfRange("day", obj.day);
1840  } else return false;
1841}
1842
1843function hasInvalidTimeData(obj) {
1844  const { hour, minute, second, millisecond } = obj;
1845  const validHour =
1846      integerBetween(hour, 0, 23) ||
1847      (hour === 24 && minute === 0 && second === 0 && millisecond === 0),
1848    validMinute = integerBetween(minute, 0, 59),
1849    validSecond = integerBetween(second, 0, 59),
1850    validMillisecond = integerBetween(millisecond, 0, 999);
1851
1852  if (!validHour) {
1853    return unitOutOfRange("hour", hour);
1854  } else if (!validMinute) {
1855    return unitOutOfRange("minute", minute);
1856  } else if (!validSecond) {
1857    return unitOutOfRange("second", second);
1858  } else if (!validMillisecond) {
1859    return unitOutOfRange("millisecond", millisecond);
1860  } else return false;
1861}
1862
1863/*
1864  This is just a junk drawer, containing anything used across multiple classes.
1865  Because Luxon is small(ish), this should stay small and we won't worry about splitting
1866  it up into, say, parsingUtil.js and basicUtil.js and so on. But they are divided up by feature area.
1867*/
1868
1869/**
1870 * @private
1871 */
1872
1873// TYPES
1874
1875function isUndefined(o) {
1876  return typeof o === "undefined";
1877}
1878
1879function isNumber(o) {
1880  return typeof o === "number";
1881}
1882
1883function isInteger(o) {
1884  return typeof o === "number" && o % 1 === 0;
1885}
1886
1887function isString(o) {
1888  return typeof o === "string";
1889}
1890
1891function isDate(o) {
1892  return Object.prototype.toString.call(o) === "[object Date]";
1893}
1894
1895// CAPABILITIES
1896
1897function hasRelative() {
1898  try {
1899    return typeof Intl !== "undefined" && !!Intl.RelativeTimeFormat;
1900  } catch (e) {
1901    return false;
1902  }
1903}
1904
1905function hasLocaleWeekInfo() {
1906  try {
1907    return (
1908      typeof Intl !== "undefined" &&
1909      !!Intl.Locale &&
1910      ("weekInfo" in Intl.Locale.prototype || "getWeekInfo" in Intl.Locale.prototype)
1911    );
1912  } catch (e) {
1913    return false;
1914  }
1915}
1916
1917// OBJECTS AND ARRAYS
1918
1919function maybeArray(thing) {
1920  return Array.isArray(thing) ? thing : [thing];
1921}
1922
1923function bestBy(arr, by, compare) {
1924  if (arr.length === 0) {
1925    return undefined;
1926  }
1927  return arr.reduce((best, next) => {
1928    const pair = [by(next), next];
1929    if (!best) {
1930      return pair;
1931    } else if (compare(best[0], pair[0]) === best[0]) {
1932      return best;
1933    } else {
1934      return pair;
1935    }
1936  }, null)[1];
1937}
1938
1939function pick(obj, keys) {
1940  return keys.reduce((a, k) => {
1941    a[k] = obj[k];
1942    return a;
1943  }, {});
1944}
1945
1946function hasOwnProperty(obj, prop) {
1947  return Object.prototype.hasOwnProperty.call(obj, prop);
1948}
1949
1950function validateWeekSettings(settings) {
1951  if (settings == null) {
1952    return null;
1953  } else if (typeof settings !== "object") {
1954    throw new InvalidArgumentError("Week settings must be an object");
1955  } else {
1956    if (
1957      !integerBetween(settings.firstDay, 1, 7) ||
1958      !integerBetween(settings.minimalDays, 1, 7) ||
1959      !Array.isArray(settings.weekend) ||
1960      settings.weekend.some((v) => !integerBetween(v, 1, 7))
1961    ) {
1962      throw new InvalidArgumentError("Invalid week settings");
1963    }
1964    return {
1965      firstDay: settings.firstDay,
1966      minimalDays: settings.minimalDays,
1967      weekend: Array.from(settings.weekend),
1968    };
1969  }
1970}
1971
1972// NUMBERS AND STRINGS
1973
1974function integerBetween(thing, bottom, top) {
1975  return isInteger(thing) && thing >= bottom && thing <= top;
1976}
1977
1978// x % n but takes the sign of n instead of x
1979function floorMod(x, n) {
1980  return x - n * Math.floor(x / n);
1981}
1982
1983function padStart(input, n = 2) {
1984  const isNeg = input < 0;
1985  let padded;
1986  if (isNeg) {
1987    padded = "-" + ("" + -input).padStart(n, "0");
1988  } else {
1989    padded = ("" + input).padStart(n, "0");
1990  }
1991  return padded;
1992}
1993
1994function parseInteger(string) {
1995  if (isUndefined(string) || string === null || string === "") {
1996    return undefined;
1997  } else {
1998    return parseInt(string, 10);
1999  }
2000}
2001
2002function parseFloating(string) {
2003  if (isUndefined(string) || string === null || string === "") {
2004    return undefined;
2005  } else {
2006    return parseFloat(string);
2007  }
2008}
2009
2010function parseMillis(fraction) {
2011  // Return undefined (instead of 0) in these cases, where fraction is not set
2012  if (isUndefined(fraction) || fraction === null || fraction === "") {
2013    return undefined;
2014  } else {
2015    const f = parseFloat("0." + fraction) * 1000;
2016    return Math.floor(f);
2017  }
2018}
2019
2020function roundTo(number, digits, 
vendor: 4,020 bytes, lines 2020-2154
2020towardZero = false) {
2021  const factor = 10 ** digits,
2022    rounder = towardZero ? Math.trunc : Math.round;
2023  return rounder(number * factor) / factor;
2024}
2025
2026// DATE BASICS
2027
2028function isLeapYear(year) {
2029  return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
2030}
2031
2032function daysInYear(year) {
2033  return isLeapYear(year) ? 366 : 365;
2034}
2035
2036function daysInMonth(year, month) {
2037  const modMonth = floorMod(month - 1, 12) + 1,
2038    modYear = year + (month - modMonth) / 12;
2039
2040  if (modMonth === 2) {
2041    return isLeapYear(modYear) ? 29 : 28;
2042  } else {
2043    return [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][modMonth - 1];
2044  }
2045}
2046
2047// convert a calendar object to a local timestamp (epoch, but with the offset baked in)
2048function objToLocalTS(obj) {
2049  let d = Date.UTC(
2050    obj.year,
2051    obj.month - 1,
2052    obj.day,
2053    obj.hour,
2054    obj.minute,
2055    obj.second,
2056    obj.millisecond
2057  );
2058
2059  // for legacy reasons, years between 0 and 99 are interpreted as 19XX; revert that
2060  if (obj.year < 100 && obj.year >= 0) {
2061    d = new Date(d);
2062    // set the month and day again, this is necessary because year 2000 is a leap year, but year 100 is not
2063    // so if obj.year is in 99, but obj.day makes it roll over into year 100,
2064    // the calculations done by Date.UTC are using year 2000 - which is incorrect
2065    d.setUTCFullYear(obj.year, obj.month - 1, obj.day);
2066  }
2067  return +d;
2068}
2069
2070// adapted from moment.js: https://github.com/moment/moment/blob/000ac1800e620f770f4eb31b5ae908f6167b0ab2/src/lib/units/week-calendar-utils.js
2071function firstWeekOffset(year, minDaysInFirstWeek, startOfWeek) {
2072  const fwdlw = isoWeekdayToLocal(dayOfWeek(year, 1, minDaysInFirstWeek), startOfWeek);
2073  return -fwdlw + minDaysInFirstWeek - 1;
2074}
2075
2076function weeksInWeekYear(weekYear, minDaysInFirstWeek = 4, startOfWeek = 1) {
2077  const weekOffset = firstWeekOffset(weekYear, minDaysInFirstWeek, startOfWeek);
2078  const weekOffsetNext = firstWeekOffset(weekYear + 1, minDaysInFirstWeek, startOfWeek);
2079  return (daysInYear(weekYear) - weekOffset + weekOffsetNext) / 7;
2080}
2081
2082function untruncateYear(year) {
2083  if (year > 99) {
2084    return year;
2085  } else return year > Settings.twoDigitCutoffYear ? 1900 + year : 2000 + year;
2086}
2087
2088// PARSING
2089
2090function parseZoneInfo(ts, offsetFormat, locale, timeZone = null) {
2091  const date = new Date(ts),
2092    intlOpts = {
2093      hourCycle: "h23",
2094      year: "numeric",
2095      month: "2-digit",
2096      day: "2-digit",
2097      hour: "2-digit",
2098      minute: "2-digit",
2099    };
2100
2101  if (timeZone) {
2102    intlOpts.timeZone = timeZone;
2103  }
2104
2105  const modified = { timeZoneName: offsetFormat, ...intlOpts };
2106
2107  const parsed = new Intl.DateTimeFormat(locale, modified)
2108    .formatToParts(date)
2109    .find((m) => m.type.toLowerCase() === "timezonename");
2110  return parsed ? parsed.value : null;
2111}
2112
2113// signedOffset('-5', '30') -> -330
2114function signedOffset(offHourStr, offMinuteStr) {
2115  let offHour = parseInt(offHourStr, 10);
2116
2117  // don't || this because we want to preserve -0
2118  if (Number.isNaN(offHour)) {
2119    offHour = 0;
2120  }
2121
2122  const offMin = parseInt(offMinuteStr, 10) || 0,
2123    offMinSigned = offHour < 0 || Object.is(offHour, -0) ? -offMin : offMin;
2124  return offHour * 60 + offMinSigned;
2125}
2126
2127// COERCION
2128
2129function asNumber(value) {
2130  const numericValue = Number(value);
2131  if (typeof value === "boolean" || value === "" || Number.isNaN(numericValue))
2132    throw new InvalidArgumentError(`Invalid unit value ${value}`);
2133  return numericValue;
2134}
2135
2136function normalizeObject(obj, normalizer) {
2137  const normalized = {};
2138  for (const u in obj) {
2139    if (hasOwnProperty(obj, u)) {
2140      const v = obj[u];
2141      if (v === undefined || v === null) continue;
2142      normalized[normalizer(u)] = asNumber(v);
2143    }
2144  }
2145  return normalized;
2146}
2147
2148/**
2149 * Returns the offset's value as a string
2150 * @param {number} ts - Epoch milliseconds for which to get the offset
2151 * @param {string} format - What style of offset to return.
2152 *                          Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
2153 * @return {string}
2154 */
vendor: 72,141 bytes, lines 2154-4439
2154
2155function formatOffset(offset, format) {
2156  const hours = Math.trunc(Math.abs(offset / 60)),
2157    minutes = Math.trunc(Math.abs(offset % 60)),
2158    sign = offset >= 0 ? "+" : "-";
2159
2160  switch (format) {
2161    case "short":
2162      return `${sign}${padStart(hours, 2)}:${padStart(minutes, 2)}`;
2163    case "narrow":
2164      return `${sign}${hours}${minutes > 0 ? `:${minutes}` : ""}`;
2165    case "techie":
2166      return `${sign}${padStart(hours, 2)}${padStart(minutes, 2)}`;
2167    default:
2168      throw new RangeError(`Value format ${format} is out of range for property format`);
2169  }
2170}
2171
2172function timeObject(obj) {
2173  return pick(obj, ["hour", "minute", "second", "millisecond"]);
2174}
2175
2176/**
2177 * @private
2178 */
2179
2180const monthsLong = [
2181  "January",
2182  "February",
2183  "March",
2184  "April",
2185  "May",
2186  "June",
2187  "July",
2188  "August",
2189  "September",
2190  "October",
2191  "November",
2192  "December",
2193];
2194
2195const monthsShort = [
2196  "Jan",
2197  "Feb",
2198  "Mar",
2199  "Apr",
2200  "May",
2201  "Jun",
2202  "Jul",
2203  "Aug",
2204  "Sep",
2205  "Oct",
2206  "Nov",
2207  "Dec",
2208];
2209
2210const monthsNarrow = ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"];
2211
2212function months(length) {
2213  switch (length) {
2214    case "narrow":
2215      return [...monthsNarrow];
2216    case "short":
2217      return [...monthsShort];
2218    case "long":
2219      return [...monthsLong];
2220    case "numeric":
2221      return ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
2222    case "2-digit":
2223      return ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
2224    default:
2225      return null;
2226  }
2227}
2228
2229const weekdaysLong = [
2230  "Monday",
2231  "Tuesday",
2232  "Wednesday",
2233  "Thursday",
2234  "Friday",
2235  "Saturday",
2236  "Sunday",
2237];
2238
2239const weekdaysShort = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
2240
2241const weekdaysNarrow = ["M", "T", "W", "T", "F", "S", "S"];
2242
2243function weekdays(length) {
2244  switch (length) {
2245    case "narrow":
2246      return [...weekdaysNarrow];
2247    case "short":
2248      return [...weekdaysShort];
2249    case "long":
2250      return [...weekdaysLong];
2251    case "numeric":
2252      return ["1", "2", "3", "4", "5", "6", "7"];
2253    default:
2254      return null;
2255  }
2256}
2257
2258const meridiems = ["AM", "PM"];
2259
2260const erasLong = ["Before Christ", "Anno Domini"];
2261
2262const erasShort = ["BC", "AD"];
2263
2264const erasNarrow = ["B", "A"];
2265
2266function eras(length) {
2267  switch (length) {
2268    case "narrow":
2269      return [...erasNarrow];
2270    case "short":
2271      return [...erasShort];
2272    case "long":
2273      return [...erasLong];
2274    default:
2275      return null;
2276  }
2277}
2278
2279function meridiemForDateTime(dt) {
2280  return meridiems[dt.hour < 12 ? 0 : 1];
2281}
2282
2283function weekdayForDateTime(dt, length) {
2284  return weekdays(length)[dt.weekday - 1];
2285}
2286
2287function monthForDateTime(dt, length) {
2288  return months(length)[dt.month - 1];
2289}
2290
2291function eraForDateTime(dt, length) {
2292  return eras(length)[dt.year < 0 ? 0 : 1];
2293}
2294
2295function formatRelativeTime(unit, count, numeric = "always", narrow = false) {
2296  const units = {
2297    years: ["year", "yr."],
2298    quarters: ["quarter", "qtr."],
2299    months: ["month", "mo."],
2300    weeks: ["week", "wk."],
2301    days: ["day", "day", "days"],
2302    hours: ["hour", "hr."],
2303    minutes: ["minute", "min."],
2304    seconds: ["second", "sec."],
2305  };
2306
2307  const lastable = ["hours", "minutes", "seconds"].indexOf(unit) === -1;
2308
2309  if (numeric === "auto" && lastable) {
2310    const isDay = unit === "days";
2311    switch (count) {
2312      case 1:
2313        return isDay ? "tomorrow" : `next ${units[unit][0]}`;
2314      case -1:
2315        return isDay ? "yesterday" : `last ${units[unit][0]}`;
2316      case 0:
2317        return isDay ? "today" : `this ${units[unit][0]}`;
2318    }
2319  }
2320
2321  const isInPast = Object.is(count, -0) || count < 0,
2322    fmtValue = Math.abs(count),
2323    singular = fmtValue === 1,
2324    lilUnits = units[unit],
2325    fmtUnit = narrow
2326      ? singular
2327        ? lilUnits[1]
2328        : lilUnits[2] || lilUnits[1]
2329      : singular
2330      ? units[unit][0]
2331      : unit;
2332  return isInPast ? `${fmtValue} ${fmtUnit} ago` : `in ${fmtValue} ${fmtUnit}`;
2333}
2334
2335function stringifyTokens(splits, tokenToString) {
2336  let s = "";
2337  for (const token of splits) {
2338    if (token.literal) {
2339      s += token.val;
2340    } else {
2341      s += tokenToString(token.val);
2342    }
2343  }
2344  return s;
2345}
2346
2347const macroTokenToFormatOpts = {
2348  D: DATE_SHORT,
2349  DD: DATE_MED,
2350  DDD: DATE_FULL,
2351  DDDD: DATE_HUGE,
2352  t: TIME_SIMPLE,
2353  tt: TIME_WITH_SECONDS,
2354  ttt: TIME_WITH_SHORT_OFFSET,
2355  tttt: TIME_WITH_LONG_OFFSET,
2356  T: TIME_24_SIMPLE,
2357  TT: TIME_24_WITH_SECONDS,
2358  TTT: TIME_24_WITH_SHORT_OFFSET,
2359  TTTT: TIME_24_WITH_LONG_OFFSET,
2360  f: DATETIME_SHORT,
2361  ff: DATETIME_MED,
2362  fff: DATETIME_FULL,
2363  ffff: DATETIME_HUGE,
2364  F: DATETIME_SHORT_WITH_SECONDS,
2365  FF: DATETIME_MED_WITH_SECONDS,
2366  FFF: DATETIME_FULL_WITH_SECONDS,
2367  FFFF: DATETIME_HUGE_WITH_SECONDS,
2368};
2369
2370/**
2371 * @private
2372 */
2373
2374class Formatter {
2375  static create(locale, opts = {}) {
2376    return new Formatter(locale, opts);
2377  }
2378
2379  static parseFormat(fmt) {
2380    // white-space is always considered a literal in user-provided formats
2381    // the " " token has a special meaning (see unitForToken)
2382
2383    let current = null,
2384      currentFull = "",
2385      bracketed = false;
2386    const splits = [];
2387    for (let i = 0; i < fmt.length; i++) {
2388      const c = fmt.charAt(i);
2389      if (c === "'") {
2390        if (currentFull.length > 0) {
2391          splits.push({ literal: bracketed || /^\s+$/.test(currentFull), val: currentFull });
2392        }
2393        current = null;
2394        currentFull = "";
2395        bracketed = !bracketed;
2396      } else if (bracketed) {
2397        currentFull += c;
2398      } else if (c === current) {
2399        currentFull += c;
2400      } else {
2401        if (currentFull.length > 0) {
2402          splits.push({ literal: /^\s+$/.test(currentFull), val: currentFull });
2403        }
2404        currentFull = c;
2405        current = c;
2406      }
2407    }
2408
2409    if (currentFull.length > 0) {
2410      splits.push({ literal: bracketed || /^\s+$/.test(currentFull), val: currentFull });
2411    }
2412
2413    return splits;
2414  }
2415
2416  static macroTokenToFormatOpts(token) {
2417    return macroTokenToFormatOpts[token];
2418  }
2419
2420  constructor(locale, formatOpts) {
2421    this.opts = formatOpts;
2422    this.loc = locale;
2423    this.systemLoc = null;
2424  }
2425
2426  formatWithSystemDefault(dt, opts) {
2427    if (this.systemLoc === null) {
2428      this.systemLoc = this.loc.redefaultToSystem();
2429    }
2430    const df = this.systemLoc.dtFormatter(dt, { ...this.opts, ...opts });
2431    return df.format();
2432  }
2433
2434  dtFormatter(dt, opts = {}) {
2435    return this.loc.dtFormatter(dt, { ...this.opts, ...opts });
2436  }
2437
2438  formatDateTime(dt, opts) {
2439    return this.dtFormatter(dt, opts).format();
2440  }
2441
2442  formatDateTimeParts(dt, opts) {
2443    return this.dtFormatter(dt, opts).formatToParts();
2444  }
2445
2446  formatInterval(interval, opts) {
2447    const df = this.dtFormatter(interval.start, opts);
2448    return df.dtf.formatRange(interval.start.toJSDate(), interval.end.toJSDate());
2449  }
2450
2451  resolvedOptions(dt, opts) {
2452    return this.dtFormatter(dt, opts).resolvedOptions();
2453  }
2454
2455  num(n, p = 0) {
2456    // we get some perf out of doing this here, annoyingly
2457    if (this.opts.forceSimple) {
2458      return padStart(n, p);
2459    }
2460
2461    const opts = { ...this.opts };
2462
2463    if (p > 0) {
2464      opts.padTo = p;
2465    }
2466
2467    return this.loc.numberFormatter(opts).format(n);
2468  }
2469
2470  formatDateTimeFromString(dt, fmt) {
2471    const knownEnglish = this.loc.listingMode() === "en",
2472      useDateTimeFormatter = this.loc.outputCalendar && this.loc.outputCalendar !== "gregory",
2473      string = (opts, extract) => this.loc.extract(dt, opts, extract),
2474      formatOffset = (opts) => {
2475        if (dt.isOffsetFixed && dt.offset === 0 && opts.allowZ) {
2476          return "Z";
2477        }
2478
2479        return dt.isValid ? dt.zone.formatOffset(dt.ts, opts.format) : "";
2480      },
2481      meridiem = () =>
2482        knownEnglish
2483          ? meridiemForDateTime(dt)
2484          : string({ hour: "numeric", hourCycle: "h12" }, "dayperiod"),
2485      month = (length, standalone) =>
2486        knownEnglish
2487          ? monthForDateTime(dt, length)
2488          : string(standalone ? { month: length } : { month: length, day: "numeric" }, "month"),
2489      weekday = (length, standalone) =>
2490        knownEnglish
2491          ? weekdayForDateTime(dt, length)
2492          : string(
2493              standalone ? { weekday: length } : { weekday: length, month: "long", day: "numeric" },
2494              "weekday"
2495            ),
2496      maybeMacro = (token) => {
2497        const formatOpts = Formatter.macroTokenToFormatOpts(token);
2498        if (formatOpts) {
2499          return this.formatWithSystemDefault(dt, formatOpts);
2500        } else {
2501          return token;
2502        }
2503      },
2504      era = (length) =>
2505        knownEnglish ? eraForDateTime(dt, length) : string({ era: length }, "era"),
2506      tokenToString = (token) => {
2507        // Where possible: https://cldr.unicode.org/translation/date-time/date-time-symbols
2508        switch (token) {
2509          // ms
2510          case "S":
2511            return this.num(dt.millisecond);
2512          case "u":
2513          // falls through
2514          case "SSS":
2515            return this.num(dt.millisecond, 3);
2516          // seconds
2517          case "s":
2518            return this.num(dt.second);
2519          case "ss":
2520            return this.num(dt.second, 2);
2521          // fractional seconds
2522          case "uu":
2523            return this.num(Math.floor(dt.millisecond / 10), 2);
2524          case "uuu":
2525            return this.num(Math.floor(dt.millisecond / 100));
2526          // minutes
2527          case "m":
2528            return this.num(dt.minute);
2529          case "mm":
2530            return this.num(dt.minute, 2);
2531          // hours
2532          case "h":
2533            return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12);
2534          case "hh":
2535            return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12, 2);
2536          case "H":
2537            return this.num(dt.hour);
2538          case "HH":
2539            return this.num(dt.hour, 2);
2540          // offset
2541          case "Z":
2542            // like +6
2543            return formatOffset({ format: "narrow", allowZ: this.opts.allowZ });
2544          case "ZZ":
2545            // like +06:00
2546            return formatOffset({ format: "short", allowZ: this.opts.allowZ });
2547          case "ZZZ":
2548            // like +0600
2549            return formatOffset({ format: "techie", allowZ: this.opts.allowZ });
2550          case "ZZZZ":
2551            // like EST
2552            return dt.zone.offsetName(dt.ts, { format: "short", locale: this.loc.locale });
2553          case "ZZZZZ":
2554            // like Eastern Standard Time
2555            return dt.zone.offsetName(dt.ts, { format: "long", locale: this.loc.locale });
2556          // zone
2557          case "z":
2558            // like America/New_York
2559            return dt.zoneName;
2560          // meridiems
2561          case "a":
2562            return meridiem();
2563          // dates
2564          case "d":
2565            return useDateTimeFormatter ? string({ day: "numeric" }, "day") : this.num(dt.day);
2566          case "dd":
2567            return useDateTimeFormatter ? string({ day: "2-digit" }, "day") : this.num(dt.day, 2);
2568          // weekdays - standalone
2569          case "c":
2570            // like 1
2571            return this.num(dt.weekday);
2572          case "ccc":
2573            // like 'Tues'
2574            return weekday("short", true);
2575          case "cccc":
2576            // like 'Tuesday'
2577            return weekday("long", true);
2578          case "ccccc":
2579            // like 'T'
2580            return weekday("narrow", true);
2581          // weekdays - format
2582          case "E":
2583            // like 1
2584            return this.num(dt.weekday);
2585          case "EEE":
2586            // like 'Tues'
2587            return weekday("short", false);
2588          case "EEEE":
2589            // like 'Tuesday'
2590            return weekday("long", false);
2591          case "EEEEE":
2592            // like 'T'
2593            return weekday("narrow", false);
2594          // months - standalone
2595          case "L":
2596            // like 1
2597            return useDateTimeFormatter
2598              ? string({ month: "numeric", day: "numeric" }, "month")
2599              : this.num(dt.month);
2600          case "LL":
2601            // like 01, doesn't seem to work
2602            return useDateTimeFormatter
2603              ? string({ month: "2-digit", day: "numeric" }, "month")
2604              : this.num(dt.month, 2);
2605          case "LLL":
2606            // like Jan
2607            return month("short", true);
2608          case "LLLL":
2609            // like January
2610            return month("long", true);
2611          case "LLLLL":
2612            // like J
2613            return month("narrow", true);
2614          // months - format
2615          case "M":
2616            // like 1
2617            return useDateTimeFormatter
2618              ? string({ month: "numeric" }, "month")
2619              : this.num(dt.month);
2620          case "MM":
2621            // like 01
2622            return useDateTimeFormatter
2623              ? string({ month: "2-digit" }, "month")
2624              : this.num(dt.month, 2);
2625          case "MMM":
2626            // like Jan
2627            return month("short", false);
2628          case "MMMM":
2629            // like January
2630            return month("long", false);
2631          case "MMMMM":
2632            // like J
2633            return month("narrow", false);
2634          // years
2635          case "y":
2636            // like 2014
2637            return useDateTimeFormatter ? string({ year: "numeric" }, "year") : this.num(dt.year);
2638          case "yy":
2639            // like 14
2640            return useDateTimeFormatter
2641              ? string({ year: "2-digit" }, "year")
2642              : this.num(dt.year.toString().slice(-2), 2);
2643          case "yyyy":
2644            // like 0012
2645            return useDateTimeFormatter
2646              ? string({ year: "numeric" }, "year")
2647              : this.num(dt.year, 4);
2648          case "yyyyyy":
2649            // like 000012
2650            return useDateTimeFormatter
2651              ? string({ year: "numeric" }, "year")
2652              : this.num(dt.year, 6);
2653          // eras
2654          case "G":
2655            // like AD
2656            return era("short");
2657          case "GG":
2658            // like Anno Domini
2659            return era("long");
2660          case "GGGGG":
2661            return era("narrow");
2662          case "kk":
2663            return this.num(dt.weekYear.toString().slice(-2), 2);
2664          case "kkkk":
2665            return this.num(dt.weekYear, 4);
2666          case "W":
2667            return this.num(dt.weekNumber);
2668          case "WW":
2669            return this.num(dt.weekNumber, 2);
2670          case "n":
2671            return this.num(dt.localWeekNumber);
2672          case "nn":
2673            return this.num(dt.localWeekNumber, 2);
2674          case "ii":
2675            return this.num(dt.localWeekYear.toString().slice(-2), 2);
2676          case "iiii":
2677            return this.num(dt.localWeekYear, 4);
2678          case "o":
2679            return this.num(dt.ordinal);
2680          case "ooo":
2681            return this.num(dt.ordinal, 3);
2682          case "q":
2683            // like 1
2684            return this.num(dt.quarter);
2685          case "qq":
2686            // like 01
2687            return this.num(dt.quarter, 2);
2688          case "X":
2689            return this.num(Math.floor(dt.ts / 1000));
2690          case "x":
2691            return this.num(dt.ts);
2692          default:
2693            return maybeMacro(token);
2694        }
2695      };
2696
2697    return stringifyTokens(Formatter.parseFormat(fmt), tokenToString);
2698  }
2699
2700  formatDurationFromString(dur, fmt) {
2701    const tokenToField = (token) => {
2702        switch (token[0]) {
2703          case "S":
2704            return "millisecond";
2705          case "s":
2706            return "second";
2707          case "m":
2708            return "minute";
2709          case "h":
2710            return "hour";
2711          case "d":
2712            return "day";
2713          case "w":
2714            return "week";
2715          case "M":
2716            return "month";
2717          case "y":
2718            return "year";
2719          default:
2720            return null;
2721        }
2722      },
2723      tokenToString = (lildur) => (token) => {
2724        const mapped = tokenToField(token);
2725        if (mapped) {
2726          return this.num(lildur.get(mapped), token.length);
2727        } else {
2728          return token;
2729        }
2730      },
2731      tokens = Formatter.parseFormat(fmt),
2732      realTokens = tokens.reduce(
2733        (found, { literal, val }) => (literal ? found : found.concat(val)),
2734        []
2735      ),
2736      collapsed = dur.shiftTo(...realTokens.map(tokenToField).filter((t) => t));
2737    return stringifyTokens(tokens, tokenToString(collapsed));
2738  }
2739}
2740
2741/*
2742 * This file handles parsing for well-specified formats. Here's how it works:
2743 * Two things go into parsing: a regex to match with and an extractor to take apart the groups in the match.
2744 * An extractor is just a function that takes a regex match array and returns a { year: ..., month: ... } object
2745 * parse() does the work of executing the regex and applying the extractor. It takes multiple regex/extractor pairs to try in sequence.
2746 * Extractors can take a "cursor" representing the offset in the match to look at. This makes it easy to combine extractors.
2747 * combineExtractors() does the work of combining them, keeping track of the cursor through multiple extractions.
2748 * Some extractions are super dumb and simpleParse and fromStrings help DRY them.
2749 */
2750
2751const ianaRegex = /[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;
2752
2753function combineRegexes(...regexes) {
2754  const full = regexes.reduce((f, r) => f + r.source, "");
2755  return RegExp(`^${full}$`);
2756}
2757
2758function combineExtractors(...extractors) {
2759  return (m) =>
2760    extractors
2761      .reduce(
2762        ([mergedVals, mergedZone, cursor], ex) => {
2763          const [val, zone, next] = ex(m, cursor);
2764          return [{ ...mergedVals, ...val }, zone || mergedZone, next];
2765        },
2766        [{}, null, 1]
2767      )
2768      .slice(0, 2);
2769}
2770
2771function parse(s, ...patterns) {
2772  if (s == null) {
2773    return [null, null];
2774  }
2775
2776  for (const [regex, extractor] of patterns) {
2777    const m = regex.exec(s);
2778    if (m) {
2779      return extractor(m);
2780    }
2781  }
2782  return [null, null];
2783}
2784
2785function simpleParse(...keys) {
2786  return (match, cursor) => {
2787    const ret = {};
2788    let i;
2789
2790    for (i = 0; i < keys.length; i++) {
2791      ret[keys[i]] = parseInteger(match[cursor + i]);
2792    }
2793    return [ret, null, cursor + i];
2794  };
2795}
2796
2797// ISO and SQL parsing
2798const offsetRegex = /(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/;
2799const isoExtendedZone = `(?:${offsetRegex.source}?(?:\\[(${ianaRegex.source})\\])?)?`;
2800const isoTimeBaseRegex = /(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/;
2801const isoTimeRegex = RegExp(`${isoTimeBaseRegex.source}${isoExtendedZone}`);
2802const isoTimeExtensionRegex = RegExp(`(?:T${isoTimeRegex.source})?`);
2803const isoYmdRegex = /([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/;
2804const isoWeekRegex = /(\d{4})-?W(\d\d)(?:-?(\d))?/;
2805const isoOrdinalRegex = /(\d{4})-?(\d{3})/;
2806const extractISOWeekData = simpleParse("weekYear", "weekNumber", "weekDay");
2807const extractISOOrdinalData = simpleParse("year", "ordinal");
2808const sqlYmdRegex = /(\d{4})-(\d\d)-(\d\d)/; // dumbed-down version of the ISO one
2809const sqlTimeRegex = RegExp(
2810  `${isoTimeBaseRegex.source} ?(?:${offsetRegex.source}|(${ianaRegex.source}))?`
2811);
2812const sqlTimeExtensionRegex = RegExp(`(?: ${sqlTimeRegex.source})?`);
2813
2814function int(match, pos, fallback) {
2815  const m = match[pos];
2816  return isUndefined(m) ? fallback : parseInteger(m);
2817}
2818
2819function extractISOYmd(match, cursor) {
2820  const item = {
2821    year: int(match, cursor),
2822    month: int(match, cursor + 1, 1),
2823    day: int(match, cursor + 2, 1),
2824  };
2825
2826  return [item, null, cursor + 3];
2827}
2828
2829function extractISOTime(match, cursor) {
2830  const item = {
2831    hours: int(match, cursor, 0),
2832    minutes: int(match, cursor + 1, 0),
2833    seconds: int(match, cursor + 2, 0),
2834    milliseconds: parseMillis(match[cursor + 3]),
2835  };
2836
2837  return [item, null, cursor + 4];
2838}
2839
2840function extractISOOffset(match, cursor) {
2841  const local = !match[cursor] && !match[cursor + 1],
2842    fullOffset = signedOffset(match[cursor + 1], match[cursor + 2]),
2843    zone = local ? null : FixedOffsetZone.instance(fullOffset);
2844  return [{}, zone, cursor + 3];
2845}
2846
2847function extractIANAZone(match, cursor) {
2848  const zone = match[cursor] ? IANAZone.create(match[cursor]) : null;
2849  return [{}, zone, cursor + 1];
2850}
2851
2852// ISO time parsing
2853
2854const isoTimeOnly = RegExp(`^T?${isoTimeBaseRegex.source}$`);
2855
2856// ISO duration parsing
2857
2858const isoDuration =
2859  /^-?P(?:(?:(-?\d{1,20}(?:\.\d{1,20})?)Y)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20}(?:\.\d{1,20})?)W)?(?:(-?\d{1,20}(?:\.\d{1,20})?)D)?(?:T(?:(-?\d{1,20}(?:\.\d{1,20})?)H)?(?:(-?\d{1,20}(?:\.\d{1,20})?)M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,20}))?S)?)?)$/;
2860
2861function extractISODuration(match) {
2862  const [s, yearStr, monthStr, weekStr, dayStr, hourStr, minuteStr, secondStr, millisecondsStr] =
2863    match;
2864
2865  const hasNegativePrefix = s[0] === "-";
2866  const negativeSeconds = secondStr && secondStr[0] === "-";
2867
2868  const maybeNegate = (num, force = false) =>
2869    num !== undefined && (force || (num && hasNegativePrefix)) ? -num : num;
2870
2871  return [
2872    {
2873      years: maybeNegate(parseFloating(yearStr)),
2874      months: maybeNegate(parseFloating(monthStr)),
2875      weeks: maybeNegate(parseFloating(weekStr)),
2876      days: maybeNegate(parseFloating(dayStr)),
2877      hours: maybeNegate(parseFloating(hourStr)),
2878      minutes: maybeNegate(parseFloating(minuteStr)),
2879      seconds: maybeNegate(parseFloating(secondStr), secondStr === "-0"),
2880      milliseconds: maybeNegate(parseMillis(millisecondsStr), negativeSeconds),
2881    },
2882  ];
2883}
2884
2885// These are a little braindead. EDT *should* tell us that we're in, say, America/New_York
2886// and not just that we're in -240 *right now*. But since I don't think these are used that often
2887// I'm just going to ignore that
2888const obsOffsets = {
2889  GMT: 0,
2890  EDT: -4 * 60,
2891  EST: -5 * 60,
2892  CDT: -5 * 60,
2893  CST: -6 * 60,
2894  MDT: -6 * 60,
2895  MST: -7 * 60,
2896  PDT: -7 * 60,
2897  PST: -8 * 60,
2898};
2899
2900function fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
2901  const result = {
2902    year: yearStr.length === 2 ? untruncateYear(parseInteger(yearStr)) : parseInteger(yearStr),
2903    month: monthsShort.indexOf(monthStr) + 1,
2904    day: parseInteger(dayStr),
2905    hour: parseInteger(hourStr),
2906    minute: parseInteger(minuteStr),
2907  };
2908
2909  if (secondStr) result.second = parseInteger(secondStr);
2910  if (weekdayStr) {
2911    result.weekday =
2912      weekdayStr.length > 3
2913        ? weekdaysLong.indexOf(weekdayStr) + 1
2914        : weekdaysShort.indexOf(weekdayStr) + 1;
2915  }
2916
2917  return result;
2918}
2919
2920// RFC 2822/5322
2921const rfc2822 =
2922  /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;
2923
2924function extractRFC2822(match) {
2925  const [
2926      ,
2927      weekdayStr,
2928      dayStr,
2929      monthStr,
2930      yearStr,
2931      hourStr,
2932      minuteStr,
2933      secondStr,
2934      obsOffset,
2935      milOffset,
2936      offHourStr,
2937      offMinuteStr,
2938    ] = match,
2939    result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
2940
2941  let offset;
2942  if (obsOffset) {
2943    offset = obsOffsets[obsOffset];
2944  } else if (milOffset) {
2945    offset = 0;
2946  } else {
2947    offset = signedOffset(offHourStr, offMinuteStr);
2948  }
2949
2950  return [result, new FixedOffsetZone(offset)];
2951}
2952
2953function preprocessRFC2822(s) {
2954  // Remove comments and folding whitespace and replace multiple-spaces with a single space
2955  return s
2956    .replace(/\([^()]*\)|[\n\t]/g, " ")
2957    .replace(/(\s\s+)/g, " ")
2958    .trim();
2959}
2960
2961// http date
2962
2963const rfc1123 =
2964    /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/,
2965  rfc850 =
2966    /^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/,
2967  ascii =
2968    /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;
2969
2970function extractRFC1123Or850(match) {
2971  const [, weekdayStr, dayStr, monthStr, yearStr, hourStr, minuteStr, secondStr] = match,
2972    result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
2973  return [result, FixedOffsetZone.utcInstance];
2974}
2975
2976function extractASCII(match) {
2977  const [, weekdayStr, monthStr, dayStr, hourStr, minuteStr, secondStr, yearStr] = match,
2978    result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
2979  return [result, FixedOffsetZone.utcInstance];
2980}
2981
2982const isoYmdWithTimeExtensionRegex = combineRegexes(isoYmdRegex, isoTimeExtensionRegex);
2983const isoWeekWithTimeExtensionRegex = combineRegexes(isoWeekRegex, isoTimeExtensionRegex);
2984const isoOrdinalWithTimeExtensionRegex = combineRegexes(isoOrdinalRegex, isoTimeExtensionRegex);
2985const isoTimeCombinedRegex = combineRegexes(isoTimeRegex);
2986
2987const extractISOYmdTimeAndOffset = combineExtractors(
2988  extractISOYmd,
2989  extractISOTime,
2990  extractISOOffset,
2991  extractIANAZone
2992);
2993const extractISOWeekTimeAndOffset = combineExtractors(
2994  extractISOWeekData,
2995  extractISOTime,
2996  extractISOOffset,
2997  extractIANAZone
2998);
2999const extractISOOrdinalDateAndTime = combineExtractors(
3000  extractISOOrdinalData,
3001  extractISOTime,
3002  extractISOOffset,
3003  extractIANAZone
3004);
3005const extractISOTimeAndOffset = combineExtractors(
3006  extractISOTime,
3007  extractISOOffset,
3008  extractIANAZone
3009);
3010
3011/*
3012 * @private
3013 */
3014
3015function parseISODate(s) {
3016  return parse(
3017    s,
3018    [isoYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset],
3019    [isoWeekWithTimeExtensionRegex, extractISOWeekTimeAndOffset],
3020    [isoOrdinalWithTimeExtensionRegex, extractISOOrdinalDateAndTime],
3021    [isoTimeCombinedRegex, extractISOTimeAndOffset]
3022  );
3023}
3024
3025function parseRFC2822Date(s) {
3026  return parse(preprocessRFC2822(s), [rfc2822, extractRFC2822]);
3027}
3028
3029function parseHTTPDate(s) {
3030  return parse(
3031    s,
3032    [rfc1123, extractRFC1123Or850],
3033    [rfc850, extractRFC1123Or850],
3034    [ascii, extractASCII]
3035  );
3036}
3037
3038function parseISODuration(s) {
3039  return parse(s, [isoDuration, extractISODuration]);
3040}
3041
3042const extractISOTimeOnly = combineExtractors(extractISOTime);
3043
3044function parseISOTimeOnly(s) {
3045  return parse(s, [isoTimeOnly, extractISOTimeOnly]);
3046}
3047
3048const sqlYmdWithTimeExtensionRegex = combineRegexes(sqlYmdRegex, sqlTimeExtensionRegex);
3049const sqlTimeCombinedRegex = combineRegexes(sqlTimeRegex);
3050
3051const extractISOTimeOffsetAndIANAZone = combineExtractors(
3052  extractISOTime,
3053  extractISOOffset,
3054  extractIANAZone
3055);
3056
3057function parseSQL(s) {
3058  return parse(
3059    s,
3060    [sqlYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset],
3061    [sqlTimeCombinedRegex, extractISOTimeOffsetAndIANAZone]
3062  );
3063}
3064
3065const INVALID$2 = "Invalid Duration";
3066
3067// unit conversion constants
3068const lowOrderMatrix = {
3069    weeks: {
3070      days: 7,
3071      hours: 7 * 24,
3072      minutes: 7 * 24 * 60,
3073      seconds: 7 * 24 * 60 * 60,
3074      milliseconds: 7 * 24 * 60 * 60 * 1000,
3075    },
3076    days: {
3077      hours: 24,
3078      minutes: 24 * 60,
3079      seconds: 24 * 60 * 60,
3080      milliseconds: 24 * 60 * 60 * 1000,
3081    },
3082    hours: { minutes: 60, seconds: 60 * 60, milliseconds: 60 * 60 * 1000 },
3083    minutes: { seconds: 60, milliseconds: 60 * 1000 },
3084    seconds: { milliseconds: 1000 },
3085  },
3086  casualMatrix = {
3087    years: {
3088      quarters: 4,
3089      months: 12,
3090      weeks: 52,
3091      days: 365,
3092      hours: 365 * 24,
3093      minutes: 365 * 24 * 60,
3094      seconds: 365 * 24 * 60 * 60,
3095      milliseconds: 365 * 24 * 60 * 60 * 1000,
3096    },
3097    quarters: {
3098      months: 3,
3099      weeks: 13,
3100      days: 91,
3101      hours: 91 * 24,
3102      minutes: 91 * 24 * 60,
3103      seconds: 91 * 24 * 60 * 60,
3104      milliseconds: 91 * 24 * 60 * 60 * 1000,
3105    },
3106    months: {
3107      weeks: 4,
3108      days: 30,
3109      hours: 30 * 24,
3110      minutes: 30 * 24 * 60,
3111      seconds: 30 * 24 * 60 * 60,
3112      milliseconds: 30 * 24 * 60 * 60 * 1000,
3113    },
3114
3115    ...lowOrderMatrix,
3116  },
3117  daysInYearAccurate = 146097.0 / 400,
3118  daysInMonthAccurate = 146097.0 / 4800,
3119  accurateMatrix = {
3120    years: {
3121      quarters: 4,
3122      months: 12,
3123      weeks: daysInYearAccurate / 7,
3124      days: daysInYearAccurate,
3125      hours: daysInYearAccurate * 24,
3126      minutes: daysInYearAccurate * 24 * 60,
3127      seconds: daysInYearAccurate * 24 * 60 * 60,
3128      milliseconds: daysInYearAccurate * 24 * 60 * 60 * 1000,
3129    },
3130    quarters: {
3131      months: 3,
3132      weeks: daysInYearAccurate / 28,
3133      days: daysInYearAccurate / 4,
3134      hours: (daysInYearAccurate * 24) / 4,
3135      minutes: (daysInYearAccurate * 24 * 60) / 4,
3136      seconds: (daysInYearAccurate * 24 * 60 * 60) / 4,
3137      milliseconds: (daysInYearAccurate * 24 * 60 * 60 * 1000) / 4,
3138    },
3139    months: {
3140      weeks: daysInMonthAccurate / 7,
3141      days: daysInMonthAccurate,
3142      hours: daysInMonthAccurate * 24,
3143      minutes: daysInMonthAccurate * 24 * 60,
3144      seconds: daysInMonthAccurate * 24 * 60 * 60,
3145      milliseconds: daysInMonthAccurate * 24 * 60 * 60 * 1000,
3146    },
3147    ...lowOrderMatrix,
3148  };
3149
3150// units ordered by size
3151const orderedUnits$1 = [
3152  "years",
3153  "quarters",
3154  "months",
3155  "weeks",
3156  "days",
3157  "hours",
3158  "minutes",
3159  "seconds",
3160  "milliseconds",
3161];
3162
3163const reverseUnits = orderedUnits$1.slice(0).reverse();
3164
3165// clone really means "create another instance just like this one, but with these changes"
3166function clone$1(dur, alts, clear = false) {
3167  // deep merge for vals
3168  const conf = {
3169    values: clear ? alts.values : { ...dur.values, ...(alts.values || {}) },
3170    loc: dur.loc.clone(alts.loc),
3171    conversionAccuracy: alts.conversionAccuracy || dur.conversionAccuracy,
3172    matrix: alts.matrix || dur.matrix,
3173  };
3174  return new Duration(conf);
3175}
3176
3177function durationToMillis(matrix, vals) {
3178  let sum = vals.milliseconds ?? 0;
3179  for (const unit of reverseUnits.slice(1)) {
3180    if (vals[unit]) {
3181      sum += vals[unit] * matrix[unit]["milliseconds"];
3182    }
3183  }
3184  return sum;
3185}
3186
3187// NB: mutates parameters
3188function normalizeValues(matrix, vals) {
3189  // the logic below assumes the overall value of the duration is positive
3190  // if this is not the case, factor is used to make it so
3191  const factor = durationToMillis(matrix, vals) < 0 ? -1 : 1;
3192
3193  orderedUnits$1.reduceRight((previous, current) => {
3194    if (!isUndefined(vals[current])) {
3195      if (previous) {
3196        const previousVal = vals[previous] * factor;
3197        const conv = matrix[current][previous];
3198
3199        // if (previousVal < 0):
3200        // lower order unit is negative (e.g. { years: 2, days: -2 })
3201        // normalize this by reducing the higher order unit by the appropriate amount
3202        // and increasing the lower order unit
3203        // this can never make the higher order unit negative, because this function only operates
3204        // on positive durations, so the amount of time represented by the lower order unit cannot
3205        // be larger than the higher order unit
3206        // else:
3207        // lower order unit is positive (e.g. { years: 2, days: 450 } or { years: -2, days: 450 })
3208        // in this case we attempt to convert as much as possible from the lower order unit into
3209        // the higher order one
3210        //
3211        // Math.floor takes care of both of these cases, rounding away from 0
3212        // if previousVal < 0 it makes the absolute value larger
3213        // if previousVal >= it makes the absolute value smaller
3214        const rollUp = Math.floor(previousVal / conv);
3215        vals[current] += rollUp * factor;
3216        vals[previous] -= rollUp * conv * factor;
3217      }
3218      return current;
3219    } else {
3220      return previous;
3221    }
3222  }, null);
3223
3224  // try to convert any decimals into smaller units if possible
3225  // for example for { years: 2.5, days: 0, seconds: 0 } we want to get { years: 2, days: 182, hours: 12 }
3226  orderedUnits$1.reduce((previous, current) => {
3227    if (!isUndefined(vals[current])) {
3228      if (previous) {
3229        const fraction = vals[previous] % 1;
3230        vals[previous] -= fraction;
3231        vals[current] += fraction * matrix[previous][current];
3232      }
3233      return current;
3234    } else {
3235      return previous;
3236    }
3237  }, null);
3238}
3239
3240// Remove all properties with a value of 0 from an object
3241function removeZeroes(vals) {
3242  const newVals = {};
3243  for (const [key, value] of Object.entries(vals)) {
3244    if (value !== 0) {
3245      newVals[key] = value;
3246    }
3247  }
3248  return newVals;
3249}
3250
3251/**
3252 * A Duration object represents a period of time, like "2 months" or "1 day, 1 hour". Conceptually, it's just a map of units to their quantities, accompanied by some additional configuration and methods for creating, parsing, interrogating, transforming, and formatting them. 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.
3253 *
3254 * Here is a brief overview of commonly used methods and getters in Duration:
3255 *
3256 * * **Creation** To create a Duration, use {@link Duration.fromMillis}, {@link Duration.fromObject}, or {@link Duration.fromISO}.
3257 * * **Unit values** See the {@link Duration#years}, {@link Duration#months}, {@link Duration#weeks}, {@link Duration#days}, {@link Duration#hours}, {@link Duration#minutes}, {@link Duration#seconds}, {@link Duration#milliseconds} accessors.
3258 * * **Configuration** See  {@link Duration#locale} and {@link Duration#numberingSystem} accessors.
3259 * * **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}, {@link Duration#shiftTo}, and {@link Duration#negate}.
3260 * * **Output** To convert the Duration into other representations, see {@link Duration#as}, {@link Duration#toISO}, {@link Duration#toFormat}, and {@link Duration#toJSON}
3261 *
3262 * There's are more methods documented below. In addition, for more information on subtler topics like internationalization and validity, see the external documentation.
3263 */
3264class Duration {
3265  /**
3266   * @private
3267   */
3268  constructor(config) {
3269    const accurate = config.conversionAccuracy === "longterm" || false;
3270    let matrix = accurate ? accurateMatrix : casualMatrix;
3271
3272    if (config.matrix) {
3273      matrix = config.matrix;
3274    }
3275
3276    /**
3277     * @access private
3278     */
3279    this.values = config.values;
3280    /**
3281     * @access private
3282     */
3283    this.loc = config.loc || Locale.create();
3284    /**
3285     * @access private
3286     */
3287    this.conversionAccuracy = accurate ? "longterm" : "casual";
3288    /**
3289     * @access private
3290     */
3291    this.invalid = config.invalid || null;
3292    /**
3293     * @access private
3294     */
3295    this.matrix = matrix;
3296    /**
3297     * @access private
3298     */
3299    this.isLuxonDuration = true;
3300  }
3301
3302  /**
3303   * Create Duration from a number of milliseconds.
3304   * @param {number} count of milliseconds
3305   * @param {Object} opts - options for parsing
3306   * @param {string} [opts.locale='en-US'] - the locale to use
3307   * @param {string} opts.numberingSystem - the numbering system to use
3308   * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use
3309   * @return {Duration}
3310   */
3311  static fromMillis(count, opts) {
3312    return Duration.fromObject({ milliseconds: count }, opts);
3313  }
3314
3315  /**
3316   * Create a Duration from a JavaScript object with keys like 'years' and 'hours'.
3317   * If this object is empty then a zero milliseconds duration is returned.
3318   * @param {Object} obj - the object to create the DateTime from
3319   * @param {number} obj.years
3320   * @param {number} obj.quarters
3321   * @param {number} obj.months
3322   * @param {number} obj.weeks
3323   * @param {number} obj.days
3324   * @param {number} obj.hours
3325   * @param {number} obj.minutes
3326   * @param {number} obj.seconds
3327   * @param {number} obj.milliseconds
3328   * @param {Object} [opts=[]] - options for creating this Duration
3329   * @param {string} [opts.locale='en-US'] - the locale to use
3330   * @param {string} opts.numberingSystem - the numbering system to use
3331   * @param {string} [opts.conversionAccuracy='casual'] - the preset conversion system to use
3332   * @param {string} [opts.matrix=Object] - the custom conversion system to use
3333   * @return {Duration}
3334   */
3335  static fromObject(obj, opts = {}) {
3336    if (obj == null || typeof obj !== "object") {
3337      throw new InvalidArgumentError(
3338        `Duration.fromObject: argument expected to be an object, got ${
3339          obj === null ? "null" : typeof obj
3340        }`
3341      );
3342    }
3343
3344    return new Duration({
3345      values: normalizeObject(obj, Duration.normalizeUnit),
3346      loc: Locale.fromObject(opts),
3347      conversionAccuracy: opts.conversionAccuracy,
3348      matrix: opts.matrix,
3349    });
3350  }
3351
3352  /**
3353   * Create a Duration from DurationLike.
3354   *
3355   * @param {Object | number | Duration} durationLike
3356   * One of:
3357   * - object with keys like 'years' and 'hours'.
3358   * - number representing milliseconds
3359   * - Duration instance
3360   * @return {Duration}
3361   */
3362  static fromDurationLike(durationLike) {
3363    if (isNumber(durationLike)) {
3364      return Duration.fromMillis(durationLike);
3365    } else if (Duration.isDuration(durationLike)) {
3366      return durationLike;
3367    } else if (typeof durationLike === "object") {
3368      return Duration.fromObject(durationLike);
3369    } else {
3370      throw new InvalidArgumentError(
3371        `Unknown duration argument ${durationLike} of type ${typeof durationLike}`
3372      );
3373    }
3374  }
3375
3376  /**
3377   * Create a Duration from an ISO 8601 duration string.
3378   * @param {string} text - text to parse
3379   * @param {Object} opts - options for parsing
3380   * @param {string} [opts.locale='en-US'] - the locale to use
3381   * @param {string} opts.numberingSystem - the numbering system to use
3382   * @param {string} [opts.conversionAccuracy='casual'] - the preset conversion system to use
3383   * @param {string} [opts.matrix=Object] - the preset conversion system to use
3384   * @see https://en.wikipedia.org/wiki/ISO_8601#Durations
3385   * @example Duration.fromISO('P3Y6M1W4DT12H30M5S').toObject() //=> { years: 3, months: 6, weeks: 1, days: 4, hours: 12, minutes: 30, seconds: 5 }
3386   * @example Duration.fromISO('PT23H').toObject() //=> { hours: 23 }
3387   * @example Duration.fromISO('P5Y3M').toObject() //=> { years: 5, months: 3 }
3388   * @return {Duration}
3389   */
3390  static fromISO(text, opts) {
3391    const [parsed] = parseISODuration(text);
3392    if (parsed) {
3393      return Duration.fromObject(parsed, opts);
3394    } else {
3395      return Duration.invalid("unparsable", `the input "${text}" can't be parsed as ISO 8601`);
3396    }
3397  }
3398
3399  /**
3400   * Create a Duration from an ISO 8601 time string.
3401   * @param {string} text - text to parse
3402   * @param {Object} opts - options for parsing
3403   * @param {string} [opts.locale='en-US'] - the locale to use
3404   * @param {string} opts.numberingSystem - the numbering system to use
3405   * @param {string} [opts.conversionAccuracy='casual'] - the preset conversion system to use
3406   * @param {string} [opts.matrix=Object] - the conversion system to use
3407   * @see https://en.wikipedia.org/wiki/ISO_8601#Times
3408   * @example Duration.fromISOTime('11:22:33.444').toObject() //=> { hours: 11, minutes: 22, seconds: 33, milliseconds: 444 }
3409   * @example Duration.fromISOTime('11:00').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
3410   * @example Duration.fromISOTime('T11:00').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
3411   * @example Duration.fromISOTime('1100').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
3412   * @example Duration.fromISOTime('T1100').toObject() //=> { hours: 11, minutes: 0, seconds: 0 }
3413   * @return {Duration}
3414   */
3415  static fromISOTime(text, opts) {
3416    const [parsed] = parseISOTimeOnly(text);
3417    if (parsed) {
3418      return Duration.fromObject(parsed, opts);
3419    } else {
3420      return Duration.invalid("unparsable", `the input "${text}" can't be parsed as ISO 8601`);
3421    }
3422  }
3423
3424  /**
3425   * Create an invalid Duration.
3426   * @param {string} reason - simple string of why this datetime is invalid. Should not contain parameters or anything else data-dependent
3427   * @param {string} [explanation=null] - longer explanation, may include parameters and other useful debugging information
3428   * @return {Duration}
3429   */
3430  static invalid(reason, explanation = null) {
3431    if (!reason) {
3432      throw new InvalidArgumentError("need to specify a reason the Duration is invalid");
3433    }
3434
3435    const invalid = reason instanceof Invalid ? reason : new Invalid(reason, explanation);
3436
3437    if (Settings.throwOnInvalid) {
3438      throw new InvalidDurationError(invalid);
3439    } else {
3440      return new Duration({ invalid });
3441    }
3442  }
3443
3444  /**
3445   * @private
3446   */
3447  static normalizeUnit(unit) {
3448    const normalized = {
3449      year: "years",
3450      years: "years",
3451      quarter: "quarters",
3452      quarters: "quarters",
3453      month: "months",
3454      months: "months",
3455      week: "weeks",
3456      weeks: "weeks",
3457      day: "days",
3458      days: "days",
3459      hour: "hours",
3460      hours: "hours",
3461      minute: "minutes",
3462      minutes: "minutes",
3463      second: "seconds",
3464      seconds: "seconds",
3465      millisecond: "milliseconds",
3466      milliseconds: "milliseconds",
3467    }[unit ? unit.toLowerCase() : unit];
3468
3469    if (!normalized) throw new InvalidUnitError(unit);
3470
3471    return normalized;
3472  }
3473
3474  /**
3475   * Check if an object is a Duration. Works across context boundaries
3476   * @param {object} o
3477   * @return {boolean}
3478   */
3479  static isDuration(o) {
3480    return (o && o.isLuxonDuration) || false;
3481  }
3482
3483  /**
3484   * Get  the locale of a Duration, such 'en-GB'
3485   * @type {string}
3486   */
3487  get locale() {
3488    return this.isValid ? this.loc.locale : null;
3489  }
3490
3491  /**
3492   * Get the numbering system of a Duration, such 'beng'. The numbering system is used when formatting the Duration
3493   *
3494   * @type {string}
3495   */
3496  get numberingSystem() {
3497    return this.isValid ? this.loc.numberingSystem : null;
3498  }
3499
3500  /**
3501   * Returns a string representation of this Duration formatted according to the specified format string. You may use these tokens:
3502   * * `S` for milliseconds
3503   * * `s` for seconds
3504   * * `m` for minutes
3505   * * `h` for hours
3506   * * `d` for days
3507   * * `w` for weeks
3508   * * `M` for months
3509   * * `y` for years
3510   * Notes:
3511   * * Add padding by repeating the token, e.g. "yy" pads the years to two digits, "hhhh" pads the hours out to four digits
3512   * * Tokens can be escaped by wrapping with single quotes.
3513   * * The duration will be converted to the set of units in the format string using {@link Duration#shiftTo} and the Durations's conversion accuracy setting.
3514   * @param {string} fmt - the format string
3515   * @param {Object} opts - options
3516   * @param {boolean} [opts.floor=true] - floor numerical values
3517   * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("y d s") //=> "1 6 2"
3518   * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("yy dd sss") //=> "01 06 002"
3519   * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toFormat("M S") //=> "12 518402000"
3520   * @return {string}
3521   */
3522  toFormat(fmt, opts = {}) {
3523    // reverse-compat since 1.2; we always round down now, never up, and we do it by default
3524    const fmtOpts = {
3525      ...opts,
3526      floor: opts.round !== false && opts.floor !== false,
3527    };
3528    return this.isValid
3529      ? Formatter.create(this.loc, fmtOpts).formatDurationFromString(this, fmt)
3530      : INVALID$2;
3531  }
3532
3533  /**
3534   * Returns a string representation of a Duration with all units included.
3535   * To modify its behavior, use `listStyle` and any Intl.NumberFormat option, though `unitDisplay` is especially relevant.
3536   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
3537   * @param {Object} opts - Formatting options. Accepts the same keys as the options parameter of the native `Intl.NumberFormat` constructor, as well as `listStyle`.
3538   * @param {string} [opts.listStyle='narrow'] - How to format the merged list. Corresponds to the `style` property of the options parameter of the native `Intl.ListFormat` constructor.
3539   * @example
3540   * ```js
3541   * var dur = Duration.fromObject({ days: 1, hours: 5, minutes: 6 })
3542   * dur.toHuman() //=> '1 day, 5 hours, 6 minutes'
3543   * dur.toHuman({ listStyle: "long" }) //=> '1 day, 5 hours, and 6 minutes'
3544   * dur.toHuman({ unitDisplay: "short" }) //=> '1 day, 5 hr, 6 min'
3545   * ```
3546   */
3547  toHuman(opts = {}) {
3548    if (!this.isValid) return INVALID$2;
3549
3550    const l = orderedUnits$1
3551      .map((unit) => {
3552        const val = this.values[unit];
3553        if (isUndefined(val)) {
3554          return null;
3555        }
3556        return this.loc
3557          .numberFormatter({ style: "unit", unitDisplay: "long", ...opts, unit: unit.slice(0, -1) })
3558          .format(val);
3559      })
3560      .filter((n) => n);
3561
3562    return this.loc
3563      .listFormatter({ type: "conjunction", style: opts.listStyle || "narrow", ...opts })
3564      .format(l);
3565  }
3566
3567  /**
3568   * Returns a JavaScript object with this Duration's values.
3569   * @example Duration.fromObject({ years: 1, days: 6, seconds: 2 }).toObject() //=> { years: 1, days: 6, seconds: 2 }
3570   * @return {Object}
3571   */
3572  toObject() {
3573    if (!this.isValid) return {};
3574    return { ...this.values };
3575  }
3576
3577  /**
3578   * Returns an ISO 8601-compliant string representation of this Duration.
3579   * @see https://en.wikipedia.org/wiki/ISO_8601#Durations
3580   * @example Duration.fromObject({ years: 3, seconds: 45 }).toISO() //=> 'P3YT45S'
3581   * @example Duration.fromObject({ months: 4, seconds: 45 }).toISO() //=> 'P4MT45S'
3582   * @example Duration.fromObject({ months: 5 }).toISO() //=> 'P5M'
3583   * @example Duration.fromObject({ minutes: 5 }).toISO() //=> 'PT5M'
3584   * @example Duration.fromObject({ milliseconds: 6 }).toISO() //=> 'PT0.006S'
3585   * @return {string}
3586   */
3587  toISO() {
3588    // we could use the formatter, but this is an easier way to get the minimum string
3589    if (!this.isValid) return null;
3590
3591    let s = "P";
3592    if (this.years !== 0) s += this.years + "Y";
3593    if (this.months !== 0 || this.quarters !== 0) s += this.months + this.quarters * 3 + "M";
3594    if (this.weeks !== 0) s += this.weeks + "W";
3595    if (this.days !== 0) s += this.days + "D";
3596    if (this.hours !== 0 || this.minutes !== 0 || this.seconds !== 0 || this.milliseconds !== 0)
3597      s += "T";
3598    if (this.hours !== 0) s += this.hours + "H";
3599    if (this.minutes !== 0) s += this.minutes + "M";
3600    if (this.seconds !== 0 || this.milliseconds !== 0)
3601      // this will handle "floating point madness" by removing extra decimal places
3602      // https://stackoverflow.com/questions/588004/is-floating-point-math-broken
3603      s += roundTo(this.seconds + this.milliseconds / 1000, 3) + "S";
3604    if (s === "P") s += "T0S";
3605    return s;
3606  }
3607
3608  /**
3609   * Returns an ISO 8601-compliant string representation of this Duration, formatted as a time of day.
3610   * Note that this will return null if the duration is invalid, negative, or equal to or greater than 24 hours.
3611   * @see https://en.wikipedia.org/wiki/ISO_8601#Times
3612   * @param {Object} opts - options
3613   * @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0
3614   * @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0
3615   * @param {boolean} [opts.includePrefix=false] - include the `T` prefix
3616   * @param {string} [opts.format='extended'] - choose between the basic and extended format
3617   * @example Duration.fromObject({ hours: 11 }).toISOTime() //=> '11:00:00.000'
3618   * @example Duration.fromObject({ hours: 11 }).toISOTime({ suppressMilliseconds: true }) //=> '11:00:00'
3619   * @example Duration.fromObject({ hours: 11 }).toISOTime({ suppressSeconds: true }) //=> '11:00'
3620   * @example Duration.fromObject({ hours: 11 }).toISOTime({ includePrefix: true }) //=> 'T11:00:00.000'
3621   * @example Duration.fromObject({ hours: 11 }).toISOTime({ format: 'basic' }) //=> '110000.000'
3622   * @return {string}
3623   */
3624  toISOTime(opts = {}) {
3625    if (!this.isValid) return null;
3626
3627    const millis = this.toMillis();
3628    if (millis < 0 || millis >= 86400000) return null;
3629
3630    opts = {
3631      suppressMilliseconds: false,
3632      suppressSeconds: false,
3633      includePrefix: false,
3634      format: "extended",
3635      ...opts,
3636      includeOffset: false,
3637    };
3638
3639    const dateTime = DateTime.fromMillis(millis, { zone: "UTC" });
3640    return dateTime.toISOTime(opts);
3641  }
3642
3643  /**
3644   * Returns an ISO 8601 representation of this Duration appropriate for use in JSON.
3645   * @return {string}
3646   */
3647  toJSON() {
3648    return this.toISO();
3649  }
3650
3651  /**
3652   * Returns an ISO 8601 representation of this Duration appropriate for use in debugging.
3653   * @return {string}
3654   */
3655  toString() {
3656    return this.toISO();
3657  }
3658
3659  /**
3660   * Returns a string representation of this Duration appropriate for the REPL.
3661   * @return {string}
3662   */
3663  [Symbol.for("nodejs.util.inspect.custom")]() {
3664    if (this.isValid) {
3665      return `Duration { values: ${JSON.stringify(this.values)} }`;
3666    } else {
3667      return `Duration { Invalid, reason: ${this.invalidReason} }`;
3668    }
3669  }
3670
3671  /**
3672   * Returns an milliseconds value of this Duration.
3673   * @return {number}
3674   */
3675  toMillis() {
3676    if (!this.isValid) return NaN;
3677
3678    return durationToMillis(this.matrix, this.values);
3679  }
3680
3681  /**
3682   * Returns an milliseconds value of this Duration. Alias of {@link toMillis}
3683   * @return {number}
3684   */
3685  valueOf() {
3686    return this.toMillis();
3687  }
3688
3689  /**
3690   * Make this Duration longer by the specified amount. Return a newly-constructed Duration.
3691   * @param {Duration|Object|number} duration - The amount to add. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
3692   * @return {Duration}
3693   */
3694  plus(duration) {
3695    if (!this.isValid) return this;
3696
3697    const dur = Duration.fromDurationLike(duration),
3698      result = {};
3699
3700    for (const k of orderedUnits$1) {
3701      if (hasOwnProperty(dur.values, k) || hasOwnProperty(this.values, k)) {
3702        result[k] = dur.get(k) + this.get(k);
3703      }
3704    }
3705
3706    return clone$1(this, { values: result }, true);
3707  }
3708
3709  /**
3710   * Make this Duration shorter by the specified amount. Return a newly-constructed Duration.
3711   * @param {Duration|Object|number} duration - The amount to subtract. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
3712   * @return {Duration}
3713   */
3714  minus(duration) {
3715    if (!this.isValid) return this;
3716
3717    const dur = Duration.fromDurationLike(duration);
3718    return this.plus(dur.negate());
3719  }
3720
3721  /**
3722   * Scale this Duration by the specified amount. Return a newly-constructed Duration.
3723   * @param {function} fn - The function to apply to each unit. Arity is 1 or 2: the value of the unit and, optionally, the unit name. Must return a number.
3724   * @example Duration.fromObject({ hours: 1, minutes: 30 }).mapUnits(x => x * 2) //=> { hours: 2, minutes: 60 }
3725   * @example Duration.fromObject({ hours: 1, minutes: 30 }).mapUnits((x, u) => u === "hours" ? x * 2 : x) //=> { hours: 2, minutes: 30 }
3726   * @return {Duration}
3727   */
3728  mapUnits(fn) {
3729    if (!this.isValid) return this;
3730    const result = {};
3731    for (const k of Object.keys(this.values)) {
3732      result[k] = asNumber(fn(this.values[k], k));
3733    }
3734    return clone$1(this, { values: result }, true);
3735  }
3736
3737  /**
3738   * Get the value of unit.
3739   * @param {string} unit - a unit such as 'minute' or 'day'
3740   * @example Duration.fromObject({years: 2, days: 3}).get('years') //=> 2
3741   * @example Duration.fromObject({years: 2, days: 3}).get('months') //=> 0
3742   * @example Duration.fromObject({years: 2, days: 3}).get('days') //=> 3
3743   * @return {number}
3744   */
3745  get(unit) {
3746    return this[Duration.normalizeUnit(unit)];
3747  }
3748
3749  /**
3750   * "Set" the values of specified units. Return a newly-constructed Duration.
3751   * @param {Object} values - a mapping of units to numbers
3752   * @example dur.set({ years: 2017 })
3753   * @example dur.set({ hours: 8, minutes: 30 })
3754   * @return {Duration}
3755   */
3756  set(values) {
3757    if (!this.isValid) return this;
3758
3759    const mixed = { ...this.values, ...normalizeObject(values, Duration.normalizeUnit) };
3760    return clone$1(this, { values: mixed });
3761  }
3762
3763  /**
3764   * "Set" the locale and/or numberingSystem.  Returns a newly-constructed Duration.
3765   * @example dur.reconfigure({ locale: 'en-GB' })
3766   * @return {Duration}
3767   */
3768  reconfigure({ locale, numberingSystem, conversionAccuracy, matrix } = {}) {
3769    const loc = this.loc.clone({ locale, numberingSystem });
3770    const opts = { loc, matrix, conversionAccuracy };
3771    return clone$1(this, opts);
3772  }
3773
3774  /**
3775   * Return the length of the duration in the specified unit.
3776   * @param {string} unit - a unit such as 'minutes' or 'days'
3777   * @example Duration.fromObject({years: 1}).as('days') //=> 365
3778   * @example Duration.fromObject({years: 1}).as('months') //=> 12
3779   * @example Duration.fromObject({hours: 60}).as('days') //=> 2.5
3780   * @return {number}
3781   */
3782  as(unit) {
3783    return this.isValid ? this.shiftTo(unit).get(unit) : NaN;
3784  }
3785
3786  /**
3787   * Reduce this Duration to its canonical representation in its current units.
3788   * Assuming the overall value of the Duration is positive, this means:
3789   * - excessive values for lower-order units are converted to higher-order units (if possible, see first and second example)
3790   * - negative lower-order units are converted to higher order units (there must be such a higher order unit, otherwise
3791   *   the overall value would be negative, see third example)
3792   * - fractional values for higher-order units are converted to lower-order units (if possible, see fourth example)
3793   *
3794   * If the overall value is negative, the result of this method is equivalent to `this.negate().normalize().negate()`.
3795   * @example Duration.fromObject({ years: 2, days: 5000 }).normalize().toObject() //=> { years: 15, days: 255 }
3796   * @example Duration.fromObject({ days: 5000 }).normalize().toObject() //=> { days: 5000 }
3797   * @example Duration.fromObject({ hours: 12, minutes: -45 }).normalize().toObject() //=> { hours: 11, minutes: 15 }
3798   * @example Duration.fromObject({ years: 2.5, days: 0, hours: 0 }).normalize().toObject() //=> { years: 2, days: 182, hours: 12 }
3799   * @return {Duration}
3800   */
3801  normalize() {
3802    if (!this.isValid) return this;
3803    const vals = this.toObject();
3804    normalizeValues(this.matrix, vals);
3805    return clone$1(this, { values: vals }, true);
3806  }
3807
3808  /**
3809   * Rescale units to its largest representation
3810   * @example Duration.fromObject({ milliseconds: 90000 }).rescale().toObject() //=> { minutes: 1, seconds: 30 }
3811   * @return {Duration}
3812   */
3813  rescale() {
3814    if (!this.isValid) return this;
3815    const vals = removeZeroes(this.normalize().shiftToAll().toObject());
3816    return clone$1(this, { values: vals }, true);
3817  }
3818
3819  /**
3820   * Convert this Duration into its representation in a different set of units.
3821   * @example Duration.fromObject({ hours: 1, seconds: 30 }).shiftTo('minutes', 'milliseconds').toObject() //=> { minutes: 60, milliseconds: 30000 }
3822   * @return {Duration}
3823   */
3824  shiftTo(...units) {
3825    if (!this.isValid) return this;
3826
3827    if (units.length === 0) {
3828      return this;
3829    }
3830
3831    units = units.map((u) => Duration.normalizeUnit(u));
3832
3833    const built = {},
3834      accumulated = {},
3835      vals = this.toObject();
3836    let lastUnit;
3837
3838    for (const k of orderedUnits$1) {
3839      if (units.indexOf(k) >= 0) {
3840        lastUnit = k;
3841
3842        let own = 0;
3843
3844        // anything we haven't boiled down yet should get boiled to this unit
3845        for (const ak in accumulated) {
3846          own += this.matrix[ak][k] * accumulated[ak];
3847          accumulated[ak] = 0;
3848        }
3849
3850        // plus anything that's already in this unit
3851        if (isNumber(vals[k])) {
3852          own += vals[k];
3853        }
3854
3855        // only keep the integer part for now in the hopes of putting any decimal part
3856        // into a smaller unit later
3857        const i = Math.trunc(own);
3858        built[k] = i;
3859        accumulated[k] = (own * 1000 - i * 1000) / 1000;
3860
3861        // otherwise, keep it in the wings to boil it later
3862      } else if (isNumber(vals[k])) {
3863        accumulated[k] = vals[k];
3864      }
3865    }
3866
3867    // anything leftover becomes the decimal for the last unit
3868    // lastUnit must be defined since units is not empty
3869    for (const key in accumulated) {
3870      if (accumulated[key] !== 0) {
3871        built[lastUnit] +=
3872          key === lastUnit ? accumulated[key] : accumulated[key] / this.matrix[lastUnit][key];
3873      }
3874    }
3875
3876    normalizeValues(this.matrix, built);
3877    return clone$1(this, { values: built }, true);
3878  }
3879
3880  /**
3881   * Shift this Duration to all available units.
3882   * Same as shiftTo("years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds")
3883   * @return {Duration}
3884   */
3885  shiftToAll() {
3886    if (!this.isValid) return this;
3887    return this.shiftTo(
3888      "years",
3889      "months",
3890      "weeks",
3891      "days",
3892      "hours",
3893      "minutes",
3894      "seconds",
3895      "milliseconds"
3896    );
3897  }
3898
3899  /**
3900   * Return the negative of this Duration.
3901   * @example Duration.fromObject({ hours: 1, seconds: 30 }).negate().toObject() //=> { hours: -1, seconds: -30 }
3902   * @return {Duration}
3903   */
3904  negate() {
3905    if (!this.isValid) return this;
3906    const negated = {};
3907    for (const k of Object.keys(this.values)) {
3908      negated[k] = this.values[k] === 0 ? 0 : -this.values[k];
3909    }
3910    return clone$1(this, { values: negated }, true);
3911  }
3912
3913  /**
3914   * Get the years.
3915   * @type {number}
3916   */
3917  get years() {
3918    return this.isValid ? this.values.years || 0 : NaN;
3919  }
3920
3921  /**
3922   * Get the quarters.
3923   * @type {number}
3924   */
3925  get quarters() {
3926    return this.isValid ? this.values.quarters || 0 : NaN;
3927  }
3928
3929  /**
3930   * Get the months.
3931   * @type {number}
3932   */
3933  get months() {
3934    return this.isValid ? this.values.months || 0 : NaN;
3935  }
3936
3937  /**
3938   * Get the weeks
3939   * @type {number}
3940   */
3941  get weeks() {
3942    return this.isValid ? this.values.weeks || 0 : NaN;
3943  }
3944
3945  /**
3946   * Get the days.
3947   * @type {number}
3948   */
3949  get days() {
3950    return this.isValid ? this.values.days || 0 : NaN;
3951  }
3952
3953  /**
3954   * Get the hours.
3955   * @type {number}
3956   */
3957  get hours() {
3958    return this.isValid ? this.values.hours || 0 : NaN;
3959  }
3960
3961  /**
3962   * Get the minutes.
3963   * @type {number}
3964   */
3965  get minutes() {
3966    return this.isValid ? this.values.minutes || 0 : NaN;
3967  }
3968
3969  /**
3970   * Get the seconds.
3971   * @return {number}
3972   */
3973  get seconds() {
3974    return this.isValid ? this.values.seconds || 0 : NaN;
3975  }
3976
3977  /**
3978   * Get the milliseconds.
3979   * @return {number}
3980   */
3981  get milliseconds() {
3982    return this.isValid ? this.values.milliseconds || 0 : NaN;
3983  }
3984
3985  /**
3986   * Returns whether the Duration is invalid. Invalid durations are returned by diff operations
3987   * on invalid DateTimes or Intervals.
3988   * @return {boolean}
3989   */
3990  get isValid() {
3991    return this.invalid === null;
3992  }
3993
3994  /**
3995   * Returns an error code if this Duration became invalid, or null if the Duration is valid
3996   * @return {string}
3997   */
3998  get invalidReason() {
3999    return this.invalid ? this.invalid.reason : null;
4000  }
4001
4002  /**
4003   * Returns an explanation of why this Duration became invalid, or null if the Duration is valid
4004   * @type {string}
4005   */
4006  get invalidExplanation() {
4007    return this.invalid ? this.invalid.explanation : null;
4008  }
4009
4010  /**
4011   * Equality check
4012   * Two Durations are equal iff they have the same units and the same values for each unit.
4013   * @param {Duration} other
4014   * @return {boolean}
4015   */
4016  equals(other) {
4017    if (!this.isValid || !other.isValid) {
4018      return false;
4019    }
4020
4021    if (!this.loc.equals(other.loc)) {
4022      return false;
4023    }
4024
4025    function eq(v1, v2) {
4026      // Consider 0 and undefined as equal
4027      if (v1 === undefined || v1 === 0) return v2 === undefined || v2 === 0;
4028      return v1 === v2;
4029    }
4030
4031    for (const u of orderedUnits$1) {
4032      if (!eq(this.values[u], other.values[u])) {
4033        return false;
4034      }
4035    }
4036    return true;
4037  }
4038}
4039
4040const INVALID$1 = "Invalid Interval";
4041
4042// checks if the start is equal to or before the end
4043function validateStartEnd(start, end) {
4044  if (!start || !start.isValid) {
4045    return Interval.invalid("missing or invalid start");
4046  } else if (!end || !end.isValid) {
4047    return Interval.invalid("missing or invalid end");
4048  } else if (end < start) {
4049    return Interval.invalid(
4050      "end before start",
4051      `The end of an interval must be after its start, but you had start=${start.toISO()} and end=${end.toISO()}`
4052    );
4053  } else {
4054    return null;
4055  }
4056}
4057
4058/**
4059 * An Interval object represents a half-open interval of time, where each endpoint is a {@link DateTime}. Conceptually, it's a container for those two endpoints, accompanied by methods for creating, parsing, interrogating, comparing, transforming, and formatting them.
4060 *
4061 * Here is a brief overview of the most commonly used methods and getters in Interval:
4062 *
4063 * * **Creation** To create an Interval, use {@link Interval.fromDateTimes}, {@link Interval.after}, {@link Interval.before}, or {@link Interval.fromISO}.
4064 * * **Accessors** Use {@link Interval#start} and {@link Interval#end} to get the start and end.
4065 * * **Interrogation** To analyze the Interval, use {@link Interval#count}, {@link Interval#length}, {@link Interval#hasSame}, {@link Interval#contains}, {@link Interval#isAfter}, or {@link Interval#isBefore}.
4066 * * **Transformation** To create other Intervals out of this one, use {@link Interval#set}, {@link Interval#splitAt}, {@link Interval#splitBy}, {@link Interval#divideEqually}, {@link Interval.merge}, {@link Interval.xor}, {@link Interval#union}, {@link Interval#intersection}, or {@link Interval#difference}.
4067 * * **Comparison** To compare this Interval to another one, use {@link Interval#equals}, {@link Interval#overlaps}, {@link Interval#abutsStart}, {@link Interval#abutsEnd}, {@link Interval#engulfs}
4068 * * **Output** To convert the Interval into other representations, see {@link Interval#toString}, {@link Interval#toLocaleString}, {@link Interval#toISO}, {@link Interval#toISODate}, {@link Interval#toISOTime}, {@link Interval#toFormat}, and {@link Interval#toDuration}.
4069 */
4070class Interval {
4071  /**
4072   * @private
4073   */
4074  constructor(config) {
4075    /**
4076     * @access private
4077     */
4078    this.s = config.start;
4079    /**
4080     * @access private
4081     */
4082    this.e = config.end;
4083    /**
4084     * @access private
4085     */
4086    this.invalid = config.invalid || null;
4087    /**
4088     * @access private
4089     */
4090    this.isLuxonInterval = true;
4091  }
4092
4093  /**
4094   * Create an invalid Interval.
4095   * @param {string} reason - simple string of why this Interval is invalid. Should not contain parameters or anything else data-dependent
4096   * @param {string} [explanation=null] - longer explanation, may include parameters and other useful debugging information
4097   * @return {Interval}
4098   */
4099  static invalid(reason, explanation = null) {
4100    if (!reason) {
4101      throw new InvalidArgumentError("need to specify a reason the Interval is invalid");
4102    }
4103
4104    const invalid = reason instanceof Invalid ? reason : new Invalid(reason, explanation);
4105
4106    if (Settings.throwOnInvalid) {
4107      throw new InvalidIntervalError(invalid);
4108    } else {
4109      return new Interval({ invalid });
4110    }
4111  }
4112
4113  /**
4114   * Create an Interval from a start DateTime and an end DateTime. Inclusive of the start but not the end.
4115   * @param {DateTime|Date|Object} start
4116   * @param {DateTime|Date|Object} end
4117   * @return {Interval}
4118   */
4119  static fromDateTimes(start, end) {
4120    const builtStart = friendlyDateTime(start),
4121      builtEnd = friendlyDateTime(end);
4122
4123    const validateError = validateStartEnd(builtStart, builtEnd);
4124
4125    if (validateError == null) {
4126      return new Interval({
4127        start: builtStart,
4128        end: builtEnd,
4129      });
4130    } else {
4131      return validateError;
4132    }
4133  }
4134
4135  /**
4136   * Create an Interval from a start DateTime and a Duration to extend to.
4137   * @param {DateTime|Date|Object} start
4138   * @param {Duration|Object|number} duration - the length of the Interval.
4139   * @return {Interval}
4140   */
4141  static after(start, duration) {
4142    const dur = Duration.fromDurationLike(duration),
4143      dt = friendlyDateTime(start);
4144    return Interval.fromDateTimes(dt, dt.plus(dur));
4145  }
4146
4147  /**
4148   * Create an Interval from an end DateTime and a Duration to extend backwards to.
4149   * @param {DateTime|Date|Object} end
4150   * @param {Duration|Object|number} duration - the length of the Interval.
4151   * @return {Interval}
4152   */
4153  static before(end, duration) {
4154    const dur = Duration.fromDurationLike(duration),
4155      dt = friendlyDateTime(end);
4156    return Interval.fromDateTimes(dt.minus(dur), dt);
4157  }
4158
4159  /**
4160   * Create an Interval from an ISO 8601 string.
4161   * Accepts `<start>/<end>`, `<start>/<duration>`, and `<duration>/<end>` formats.
4162   * @param {string} text - the ISO string to parse
4163   * @param {Object} [opts] - options to pass {@link DateTime#fromISO} and optionally {@link Duration#fromISO}
4164   * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
4165   * @return {Interval}
4166   */
4167  static fromISO(text, opts) {
4168    const [s, e] = (text || "").split("/", 2);
4169    if (s && e) {
4170      let start, startIsValid;
4171      try {
4172        start = DateTime.fromISO(s, opts);
4173        startIsValid = start.isValid;
4174      } catch (e) {
4175        startIsValid = false;
4176      }
4177
4178      let end, endIsValid;
4179      try {
4180        end = DateTime.fromISO(e, opts);
4181        endIsValid = end.isValid;
4182      } catch (e) {
4183        endIsValid = false;
4184      }
4185
4186      if (startIsValid && endIsValid) {
4187        return Interval.fromDateTimes(start, end);
4188      }
4189
4190      if (startIsValid) {
4191        const dur = Duration.fromISO(e, opts);
4192        if (dur.isValid) {
4193          return Interval.after(start, dur);
4194        }
4195      } else if (endIsValid) {
4196        const dur = Duration.fromISO(s, opts);
4197        if (dur.isValid) {
4198          return Interval.before(end, dur);
4199        }
4200      }
4201    }
4202    return Interval.invalid("unparsable", `the input "${text}" can't be parsed as ISO 8601`);
4203  }
4204
4205  /**
4206   * Check if an object is an Interval. Works across context boundaries
4207   * @param {object} o
4208   * @return {boolean}
4209   */
4210  static isInterval(o) {
4211    return (o && o.isLuxonInterval) || false;
4212  }
4213
4214  /**
4215   * Returns the start of the Interval
4216   * @type {DateTime}
4217   */
4218  get start() {
4219    return this.isValid ? this.s : null;
4220  }
4221
4222  /**
4223   * Returns the end of the Interval
4224   * @type {DateTime}
4225   */
4226  get end() {
4227    return this.isValid ? this.e : null;
4228  }
4229
4230  /**
4231   * Returns whether this Interval's end is at least its start, meaning that the Interval isn't 'backwards'.
4232   * @type {boolean}
4233   */
4234  get isValid() {
4235    return this.invalidReason === null;
4236  }
4237
4238  /**
4239   * Returns an error code if this Interval is invalid, or null if the Interval is valid
4240   * @type {string}
4241   */
4242  get invalidReason() {
4243    return this.invalid ? this.invalid.reason : null;
4244  }
4245
4246  /**
4247   * Returns an explanation of why this Interval became invalid, or null if the Interval is valid
4248   * @type {string}
4249   */
4250  get invalidExplanation() {
4251    return this.invalid ? this.invalid.explanation : null;
4252  }
4253
4254  /**
4255   * Returns the length of the Interval in the specified unit.
4256   * @param {string} unit - the unit (such as 'hours' or 'days') to return the length in.
4257   * @return {number}
4258   */
4259  length(unit = "milliseconds") {
4260    return this.isValid ? this.toDuration(...[unit]).get(unit) : NaN;
4261  }
4262
4263  /**
4264   * Returns the count of minutes, hours, days, months, or years included in the Interval, even in part.
4265   * Unlike {@link Interval#length} this counts sections of the calendar, not periods of time, e.g. specifying 'day'
4266   * asks 'what dates are included in this interval?', not 'how many days long is this interval?'
4267   * @param {string} [unit='milliseconds'] - the unit of time to count.
4268   * @param {Object} opts - options
4269   * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week; this operation will always use the locale of the start DateTime
4270   * @return {number}
4271   */
4272  count(unit = "milliseconds", opts) {
4273    if (!this.isValid) return NaN;
4274    const start = this.start.startOf(unit, opts);
4275    let end;
4276    if (opts?.useLocaleWeeks) {
4277      end = this.end.reconfigure({ locale: start.locale });
4278    } else {
4279      end = this.end;
4280    }
4281    end = end.startOf(unit, opts);
4282    return Math.floor(end.diff(start, unit).get(unit)) + (end.valueOf() !== this.end.valueOf());
4283  }
4284
4285  /**
4286   * Returns whether this Interval's start and end are both in the same unit of time
4287   * @param {string} unit - the unit of time to check sameness on
4288   * @return {boolean}
4289   */
4290  hasSame(unit) {
4291    return this.isValid ? this.isEmpty() || this.e.minus(1).hasSame(this.s, unit) : false;
4292  }
4293
4294  /**
4295   * Return whether this Interval has the same start and end DateTimes.
4296   * @return {boolean}
4297   */
4298  isEmpty() {
4299    return this.s.valueOf() === this.e.valueOf();
4300  }
4301
4302  /**
4303   * Return whether this Interval's start is after the specified DateTime.
4304   * @param {DateTime} dateTime
4305   * @return {boolean}
4306   */
4307  isAfter(dateTime) {
4308    if (!this.isValid) return false;
4309    return this.s > dateTime;
4310  }
4311
4312  /**
4313   * Return whether this Interval's end is before the specified DateTime.
4314   * @param {DateTime} dateTime
4315   * @return {boolean}
4316   */
4317  isBefore(dateTime) {
4318    if (!this.isValid) return false;
4319    return this.e <= dateTime;
4320  }
4321
4322  /**
4323   * Return whether this Interval contains the specified DateTime.
4324   * @param {DateTime} dateTime
4325   * @return {boolean}
4326   */
4327  contains(dateTime) {
4328    if (!this.isValid) return false;
4329    return this.s <= dateTime && this.e > dateTime;
4330  }
4331
4332  /**
4333   * "Sets" the start and/or end dates. Returns a newly-constructed Interval.
4334   * @param {Object} values - the values to set
4335   * @param {DateTime} values.start - the starting DateTime
4336   * @param {DateTime} values.end - the ending DateTime
4337   * @return {Interval}
4338   */
4339  set({ start, end } = {}) {
4340    if (!this.isValid) return this;
4341    return Interval.fromDateTimes(start || this.s, end || this.e);
4342  }
4343
4344  /**
4345   * Split this Interval at each of the specified DateTimes
4346   * @param {...DateTime} dateTimes - the unit of time to count.
4347   * @return {Array}
4348   */
4349  splitAt(...dateTimes) {
4350    if (!this.isValid) return [];
4351    const sorted = dateTimes
4352        .map(friendlyDateTime)
4353        .filter((d) => this.contains(d))
4354        .sort((a, b) => a.toMillis() - b.toMillis()),
4355      results = [];
4356    let { s } = this,
4357      i = 0;
4358
4359    while (s < this.e) {
4360      const added = sorted[i] || this.e,
4361        next = +added > +this.e ? this.e : added;
4362      results.push(Interval.fromDateTimes(s, next));
4363      s = next;
4364      i += 1;
4365    }
4366
4367    return results;
4368  }
4369
4370  /**
4371   * Split this Interval into smaller Intervals, each of the specified length.
4372   * Left over time is grouped into a smaller interval
4373   * @param {Duration|Object|number} duration - The length of each resulting interval.
4374   * @return {Array}
4375   */
4376  splitBy(duration) {
4377    const dur = Duration.fromDurationLike(duration);
4378
4379    if (!this.isValid || !dur.isValid || dur.as("milliseconds") === 0) {
4380      return [];
4381    }
4382
4383    let { s } = this,
4384      idx = 1,
4385      next;
4386
4387    const results = [];
4388    while (s < this.e) {
4389      const added = this.start.plus(dur.mapUnits((x) => x * idx));
4390      next = +added > +this.e ? this.e : added;
4391      results.push(Interval.fromDateTimes(s, next));
4392      s = next;
4393      idx += 1;
4394    }
4395
4396    return results;
4397  }
4398
4399  /**
4400   * Split this Interval into the specified number of smaller intervals.
4401   * @param {number} numberOfParts - The number of Intervals to divide the Interval into.
4402   * @return {Array}
4403   */
4404  divideEqually(numberOfParts) {
4405    if (!this.isValid) return [];
4406    return this.splitBy(this.length() / numberOfParts).slice(0, numberOfParts);
4407  }
4408
4409  /**
4410   * Return whether this Interval overlaps with the specified Interval
4411   * @param {Interval} other
4412   * @return {boolean}
4413   */
4414  overlaps(other) {
4415    return this.e > other.s && this.s < other.e;
4416  }
4417
4418  /**
4419   * Return whether this Interval's end is adjacent to the specified Interval's start.
4420   * @param {Interval} other
4421   * @return {boolean}
4422   */
4423  abutsStart(other) {
4424    if (!this.isValid) return false;
4425    return +this.e === +other.s;
4426  }
4427
4428  /**
4429   * Return whether this Interval's start is adjacent to the specified Interval's end.
4430   * @param {Interval} other
4431   * @return {boolean}
4432   */
4433  abutsEnd(other) {
4434    if (!this.isValid) return false;
4435    return +other.e === +this.s;
4436  }
4437
4438  /**
4439   * Return
4439s true if this Interval fully contains the specified Interval, specifically if the intersect (of this Interval and the other Interval) is equal to the other Interval; false otherwise
vendor: 18,333 bytes, lines 4439-4888
4439.
4440   * @param {Interval} other
4441   * @return {boolean}
4442   */
4443  engulfs(other) {
4444    if (!this.isValid) return false;
4445    return this.s <= other.s && this.e >= other.e;
4446  }
4447
4448  /**
4449   * Return whether this Interval has the same start and end as the specified Interval.
4450   * @param {Interval} other
4451   * @return {boolean}
4452   */
4453  equals(other) {
4454    if (!this.isValid || !other.isValid) {
4455      return false;
4456    }
4457
4458    return this.s.equals(other.s) && this.e.equals(other.e);
4459  }
4460
4461  /**
4462   * Return an Interval representing the intersection of this Interval and the specified Interval.
4463   * Specifically, the resulting Interval has the maximum start time and the minimum end time of the two Intervals.
4464   * Returns null if the intersection is empty, meaning, the intervals don't intersect.
4465   * @param {Interval} other
4466   * @return {Interval}
4467   */
4468  intersection(other) {
4469    if (!this.isValid) return this;
4470    const s = this.s > other.s ? this.s : other.s,
4471      e = this.e < other.e ? this.e : other.e;
4472
4473    if (s >= e) {
4474      return null;
4475    } else {
4476      return Interval.fromDateTimes(s, e);
4477    }
4478  }
4479
4480  /**
4481   * Return an Interval representing the union of this Interval and the specified Interval.
4482   * Specifically, the resulting Interval has the minimum start time and the maximum end time of the two Intervals.
4483   * @param {Interval} other
4484   * @return {Interval}
4485   */
4486  union(other) {
4487    if (!this.isValid) return this;
4488    const s = this.s < other.s ? this.s : other.s,
4489      e = this.e > other.e ? this.e : other.e;
4490    return Interval.fromDateTimes(s, e);
4491  }
4492
4493  /**
4494   * Merge an array of Intervals into a equivalent minimal set of Intervals.
4495   * Combines overlapping and adjacent Intervals.
4496   * @param {Array} intervals
4497   * @return {Array}
4498   */
4499  static merge(intervals) {
4500    const [found, final] = intervals
4501      .sort((a, b) => a.s - b.s)
4502      .reduce(
4503        ([sofar, current], item) => {
4504          if (!current) {
4505            return [sofar, item];
4506          } else if (current.overlaps(item) || current.abutsStart(item)) {
4507            return [sofar, current.union(item)];
4508          } else {
4509            return [sofar.concat([current]), item];
4510          }
4511        },
4512        [[], null]
4513      );
4514    if (final) {
4515      found.push(final);
4516    }
4517    return found;
4518  }
4519
4520  /**
4521   * Return an array of Intervals representing the spans of time that only appear in one of the specified Intervals.
4522   * @param {Array} intervals
4523   * @return {Array}
4524   */
4525  static xor(intervals) {
4526    let start = null,
4527      currentCount = 0;
4528    const results = [],
4529      ends = intervals.map((i) => [
4530        { time: i.s, type: "s" },
4531        { time: i.e, type: "e" },
4532      ]),
4533      flattened = Array.prototype.concat(...ends),
4534      arr = flattened.sort((a, b) => a.time - b.time);
4535
4536    for (const i of arr) {
4537      currentCount += i.type === "s" ? 1 : -1;
4538
4539      if (currentCount === 1) {
4540        start = i.time;
4541      } else {
4542        if (start && +start !== +i.time) {
4543          results.push(Interval.fromDateTimes(start, i.time));
4544        }
4545
4546        start = null;
4547      }
4548    }
4549
4550    return Interval.merge(results);
4551  }
4552
4553  /**
4554   * Return an Interval representing the span of time in this Interval that doesn't overlap with any of the specified Intervals.
4555   * @param {...Interval} intervals
4556   * @return {Array}
4557   */
4558  difference(...intervals) {
4559    return Interval.xor([this].concat(intervals))
4560      .map((i) => this.intersection(i))
4561      .filter((i) => i && !i.isEmpty());
4562  }
4563
4564  /**
4565   * Returns a string representation of this Interval appropriate for debugging.
4566   * @return {string}
4567   */
4568  toString() {
4569    if (!this.isValid) return INVALID$1;
4570    return `[${this.s.toISO()} – ${this.e.toISO()})`;
4571  }
4572
4573  /**
4574   * Returns a string representation of this Interval appropriate for the REPL.
4575   * @return {string}
4576   */
4577  [Symbol.for("nodejs.util.inspect.custom")]() {
4578    if (this.isValid) {
4579      return `Interval { start: ${this.s.toISO()}, end: ${this.e.toISO()} }`;
4580    } else {
4581      return `Interval { Invalid, reason: ${this.invalidReason} }`;
4582    }
4583  }
4584
4585  /**
4586   * Returns a localized string representing this Interval. Accepts the same options as the
4587   * Intl.DateTimeFormat constructor and any presets defined by Luxon, such as
4588   * {@link DateTime.DATE_FULL} or {@link DateTime.TIME_SIMPLE}. The exact behavior of this method
4589   * is browser-specific, but in general it will return an appropriate representation of the
4590   * Interval in the assigned locale. Defaults to the system's locale if no locale has been
4591   * specified.
4592   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
4593   * @param {Object} [formatOpts=DateTime.DATE_SHORT] - Either a DateTime preset or
4594   * Intl.DateTimeFormat constructor options.
4595   * @param {Object} opts - Options to override the configuration of the start DateTime.
4596   * @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(); //=> 11/7/2022 – 11/8/2022
4597   * @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(DateTime.DATE_FULL); //=> November 7 – 8, 2022
4598   * @example Interval.fromISO('2022-11-07T09:00Z/2022-11-08T09:00Z').toLocaleString(DateTime.DATE_FULL, { locale: 'fr-FR' }); //=> 7–8 novembre 2022
4599   * @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString(DateTime.TIME_SIMPLE); //=> 6:00 – 8:00 PM
4600   * @example Interval.fromISO('2022-11-07T17:00Z/2022-11-07T19:00Z').toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }); //=> Mon, Nov 07, 6:00 – 8:00 p
4601   * @return {string}
4602   */
4603  toLocaleString(formatOpts = DATE_SHORT, opts = {}) {
4604    return this.isValid
4605      ? Formatter.create(this.s.loc.clone(opts), formatOpts).formatInterval(this)
4606      : INVALID$1;
4607  }
4608
4609  /**
4610   * Returns an ISO 8601-compliant string representation of this Interval.
4611   * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
4612   * @param {Object} opts - The same options as {@link DateTime#toISO}
4613   * @return {string}
4614   */
4615  toISO(opts) {
4616    if (!this.isValid) return INVALID$1;
4617    return `${this.s.toISO(opts)}/${this.e.toISO(opts)}`;
4618  }
4619
4620  /**
4621   * Returns an ISO 8601-compliant string representation of date of this Interval.
4622   * The time components are ignored.
4623   * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
4624   * @return {string}
4625   */
4626  toISODate() {
4627    if (!this.isValid) return INVALID$1;
4628    return `${this.s.toISODate()}/${this.e.toISODate()}`;
4629  }
4630
4631  /**
4632   * Returns an ISO 8601-compliant string representation of time of this Interval.
4633   * The date components are ignored.
4634   * @see https://en.wikipedia.org/wiki/ISO_8601#Time_intervals
4635   * @param {Object} opts - The same options as {@link DateTime#toISO}
4636   * @return {string}
4637   */
4638  toISOTime(opts) {
4639    if (!this.isValid) return INVALID$1;
4640    return `${this.s.toISOTime(opts)}/${this.e.toISOTime(opts)}`;
4641  }
4642
4643  /**
4644   * Returns a string representation of this Interval formatted according to the specified format
4645   * string. **You may not want this.** See {@link Interval#toLocaleString} for a more flexible
4646   * formatting tool.
4647   * @param {string} dateFormat - The format string. This string formats the start and end time.
4648   * See {@link DateTime#toFormat} for details.
4649   * @param {Object} opts - Options.
4650   * @param {string} [opts.separator =  ' – '] - A separator to place between the start and end
4651   * representations.
4652   * @return {string}
4653   */
4654  toFormat(dateFormat, { separator = " – " } = {}) {
4655    if (!this.isValid) return INVALID$1;
4656    return `${this.s.toFormat(dateFormat)}${separator}${this.e.toFormat(dateFormat)}`;
4657  }
4658
4659  /**
4660   * Return a Duration representing the time spanned by this interval.
4661   * @param {string|string[]} [unit=['milliseconds']] - the unit or units (such as 'hours' or 'days') to include in the duration.
4662   * @param {Object} opts - options that affect the creation of the Duration
4663   * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use
4664   * @example Interval.fromDateTimes(dt1, dt2).toDuration().toObject() //=> { milliseconds: 88489257 }
4665   * @example Interval.fromDateTimes(dt1, dt2).toDuration('days').toObject() //=> { days: 1.0241812152777778 }
4666   * @example Interval.fromDateTimes(dt1, dt2).toDuration(['hours', 'minutes']).toObject() //=> { hours: 24, minutes: 34.82095 }
4667   * @example Interval.fromDateTimes(dt1, dt2).toDuration(['hours', 'minutes', 'seconds']).toObject() //=> { hours: 24, minutes: 34, seconds: 49.257 }
4668   * @example Interval.fromDateTimes(dt1, dt2).toDuration('seconds').toObject() //=> { seconds: 88489.257 }
4669   * @return {Duration}
4670   */
4671  toDuration(unit, opts) {
4672    if (!this.isValid) {
4673      return Duration.invalid(this.invalidReason);
4674    }
4675    return this.e.diff(this.s, unit, opts);
4676  }
4677
4678  /**
4679   * Run mapFn on the interval start and end, returning a new Interval from the resulting DateTimes
4680   * @param {function} mapFn
4681   * @return {Interval}
4682   * @example Interval.fromDateTimes(dt1, dt2).mapEndpoints(endpoint => endpoint.toUTC())
4683   * @example Interval.fromDateTimes(dt1, dt2).mapEndpoints(endpoint => endpoint.plus({ hours: 2 }))
4684   */
4685  mapEndpoints(mapFn) {
4686    return Interval.fromDateTimes(mapFn(this.s), mapFn(this.e));
4687  }
4688}
4689
4690/**
4691 * The Info class contains static methods for retrieving general time and date related data. For example, it has methods for finding out if a time zone has a DST, for listing the months in any supported locale, and for discovering which of Luxon features are available in the current environment.
4692 */
4693class Info {
4694  /**
4695   * Return whether the specified zone contains a DST.
4696   * @param {string|Zone} [zone='local'] - Zone to check. Defaults to the environment's local zone.
4697   * @return {boolean}
4698   */
4699  static hasDST(zone = Settings.defaultZone) {
4700    const proto = DateTime.now().setZone(zone).set({ month: 12 });
4701
4702    return !zone.isUniversal && proto.offset !== proto.set({ month: 6 }).offset;
4703  }
4704
4705  /**
4706   * Return whether the specified zone is a valid IANA specifier.
4707   * @param {string} zone - Zone to check
4708   * @return {boolean}
4709   */
4710  static isValidIANAZone(zone) {
4711    return IANAZone.isValidZone(zone);
4712  }
4713
4714  /**
4715   * Converts the input into a {@link Zone} instance.
4716   *
4717   * * If `input` is already a Zone instance, it is returned unchanged.
4718   * * If `input` is a string containing a valid time zone name, a Zone instance
4719   *   with that name is returned.
4720   * * If `input` is a string that doesn't refer to a known time zone, a Zone
4721   *   instance with {@link Zone#isValid} == false is returned.
4722   * * If `input is a number, a Zone instance with the specified fixed offset
4723   *   in minutes is returned.
4724   * * If `input` is `null` or `undefined`, the default zone is returned.
4725   * @param {string|Zone|number} [input] - the value to be converted
4726   * @return {Zone}
4727   */
4728  static normalizeZone(input) {
4729    return normalizeZone(input, Settings.defaultZone);
4730  }
4731
4732  /**
4733   * Get the weekday on which the week starts according to the given locale.
4734   * @param {Object} opts - options
4735   * @param {string} [opts.locale] - the locale code
4736   * @param {string} [opts.locObj=null] - an existing locale object to use
4737   * @returns {number} the start of the week, 1 for Monday through 7 for Sunday
4738   */
4739  static getStartOfWeek({ locale = null, locObj = null } = {}) {
4740    return (locObj || Locale.create(locale)).getStartOfWeek();
4741  }
4742
4743  /**
4744   * Get the minimum number of days necessary in a week before it is considered part of the next year according
4745   * to the given locale.
4746   * @param {Object} opts - options
4747   * @param {string} [opts.locale] - the locale code
4748   * @param {string} [opts.locObj=null] - an existing locale object to use
4749   * @returns {number}
4750   */
4751  static getMinimumDaysInFirstWeek({ locale = null, locObj = null } = {}) {
4752    return (locObj || Locale.create(locale)).getMinDaysInFirstWeek();
4753  }
4754
4755  /**
4756   * Get the weekdays, which are considered the weekend according to the given locale
4757   * @param {Object} opts - options
4758   * @param {string} [opts.locale] - the locale code
4759   * @param {string} [opts.locObj=null] - an existing locale object to use
4760   * @returns {number[]} an array of weekdays, 1 for Monday through 7 for Sunday
4761   */
4762  static getWeekendWeekdays({ locale = null, locObj = null } = {}) {
4763    // copy the array, because we cache it internally
4764    return (locObj || Locale.create(locale)).getWeekendDays().slice();
4765  }
4766
4767  /**
4768   * Return an array of standalone month names.
4769   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
4770   * @param {string} [length='long'] - the length of the month representation, such as "numeric", "2-digit", "narrow", "short", "long"
4771   * @param {Object} opts - options
4772   * @param {string} [opts.locale] - the locale code
4773   * @param {string} [opts.numberingSystem=null] - the numbering system
4774   * @param {string} [opts.locObj=null] - an existing locale object to use
4775   * @param {string} [opts.outputCalendar='gregory'] - the calendar
4776   * @example Info.months()[0] //=> 'January'
4777   * @example Info.months('short')[0] //=> 'Jan'
4778   * @example Info.months('numeric')[0] //=> '1'
4779   * @example Info.months('short', { locale: 'fr-CA' } )[0] //=> 'janv.'
4780   * @example Info.months('numeric', { locale: 'ar' })[0] //=> 'Ù¡'
4781   * @example Info.months('long', { outputCalendar: 'islamic' })[0] //=> 'RabiÊ» I'
4782   * @return {Array}
4783   */
4784  static months(
4785    length = "long",
4786    { locale = null, numberingSystem = null, locObj = null, outputCalendar = "gregory" } = {}
4787  ) {
4788    return (locObj || Locale.create(locale, numberingSystem, outputCalendar)).months(length);
4789  }
4790
4791  /**
4792   * Return an array of format month names.
4793   * Format months differ from standalone months in that they're meant to appear next to the day of the month. In some languages, that
4794   * changes the string.
4795   * See {@link Info#months}
4796   * @param {string} [length='long'] - the length of the month representation, such as "numeric", "2-digit", "narrow", "short", "long"
4797   * @param {Object} opts - options
4798   * @param {string} [opts.locale] - the locale code
4799   * @param {string} [opts.numberingSystem=null] - the numbering system
4800   * @param {string} [opts.locObj=null] - an existing locale object to use
4801   * @param {string} [opts.outputCalendar='gregory'] - the calendar
4802   * @return {Array}
4803   */
4804  static monthsFormat(
4805    length = "long",
4806    { locale = null, numberingSystem = null, locObj = null, outputCalendar = "gregory" } = {}
4807  ) {
4808    return (locObj || Locale.create(locale, numberingSystem, outputCalendar)).months(length, true);
4809  }
4810
4811  /**
4812   * Return an array of standalone week names.
4813   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
4814   * @param {string} [length='long'] - the length of the weekday representation, such as "narrow", "short", "long".
4815   * @param {Object} opts - options
4816   * @param {string} [opts.locale] - the locale code
4817   * @param {string} [opts.numberingSystem=null] - the numbering system
4818   * @param {string} [opts.locObj=null] - an existing locale object to use
4819   * @example Info.weekdays()[0] //=> 'Monday'
4820   * @example Info.weekdays('short')[0] //=> 'Mon'
4821   * @example Info.weekdays('short', { locale: 'fr-CA' })[0] //=> 'lun.'
4822   * @example Info.weekdays('short', { locale: 'ar' })[0] //=> 'الاثنين'
4823   * @return {Array}
4824   */
4825  static weekdays(length = "long", { locale = null, numberingSystem = null, locObj = null } = {}) {
4826    return (locObj || Locale.create(locale, numberingSystem, null)).weekdays(length);
4827  }
4828
4829  /**
4830   * Return an array of format week names.
4831   * Format weekdays differ from standalone weekdays in that they're meant to appear next to more date information. In some languages, that
4832   * changes the string.
4833   * See {@link Info#weekdays}
4834   * @param {string} [length='long'] - the length of the month representation, such as "narrow", "short", "long".
4835   * @param {Object} opts - options
4836   * @param {string} [opts.locale=null] - the locale code
4837   * @param {string} [opts.numberingSystem=null] - the numbering system
4838   * @param {string} [opts.locObj=null] - an existing locale object to use
4839   * @return {Array}
4840   */
4841  static weekdaysFormat(
4842    length = "long",
4843    { locale = null, numberingSystem = null, locObj = null } = {}
4844  ) {
4845    return (locObj || Locale.create(locale, numberingSystem, null)).weekdays(length, true);
4846  }
4847
4848  /**
4849   * Return an array of meridiems.
4850   * @param {Object} opts - options
4851   * @param {string} [opts.locale] - the locale code
4852   * @example Info.meridiems() //=> [ 'AM', 'PM' ]
4853   * @example Info.meridiems({ locale: 'my' }) //=> [ 'နံနက်', 'ညနေ' ]
4854   * @return {Array}
4855   */
4856  static meridiems({ locale = null } = {}) {
4857    return Locale.create(locale).meridiems();
4858  }
4859
4860  /**
4861   * Return an array of eras, such as ['BC', 'AD']. The locale can be specified, but the calendar system is always Gregorian.
4862   * @param {string} [length='short'] - the length of the era representation, such as "short" or "long".
4863   * @param {Object} opts - options
4864   * @param {string} [opts.locale] - the locale code
4865   * @example Info.eras() //=> [ 'BC', 'AD' ]
4866   * @example Info.eras('long') //=> [ 'Before Christ', 'Anno Domini' ]
4867   * @example Info.eras('long', { locale: 'fr' }) //=> [ 'avant Jésus-Christ', 'après Jésus-Christ' ]
4868   * @return {Array}
4869   */
4870  static eras(length = "short", { locale = null } = {}) {
4871    return Locale.create(locale, null, "gregory").eras(length);
4872  }
4873
4874  /**
4875   * Return the set of available features in this environment.
4876   * Some features of Luxon are not available in all environments. For example, on older browsers, relative time formatting support is not available. Use this function to figure out if that's the case.
4877   * Keys:
4878   * * `relative`: whether this environment supports relative time formatting
4879   * * `localeWeek`: whether this environment supports different weekdays for the start of the week based on the locale
4880   * @example Info.features() //=> { relative: false, localeWeek: true }
4881   * @return {Object}
4882   */
4883  static features() {
4884    return { relative: hasRelative(), localeWeek: hasLocaleWeekInfo() };
4885  }
4886}
4887
4888function dayDiff(earlier, later) {
vendor: 16,499 bytes, lines 4889-5520
4889  const utcDayStart = (dt) => dt.toUTC(0, { keepLocalTime: true }).startOf("day").valueOf(),
4890    ms = utcDayStart(later) - utcDayStart(earlier);
4891  return Math.floor(Duration.fromMillis(ms).as("days"));
4892}
4893
4894function highOrderDiffs(cursor, later, units) {
4895  const differs = [
4896    ["years", (a, b) => b.year - a.year],
4897    ["quarters", (a, b) => b.quarter - a.quarter + (b.year - a.year) * 4],
4898    ["months", (a, b) => b.month - a.month + (b.year - a.year) * 12],
4899    [
4900      "weeks",
4901      (a, b) => {
4902        const days = dayDiff(a, b);
4903        return (days - (days % 7)) / 7;
4904      },
4905    ],
4906    ["days", dayDiff],
4907  ];
4908
4909  const results = {};
4910  const earlier = cursor;
4911  let lowestOrder, highWater;
4912
4913  /* This loop tries to diff using larger units first.
4914     If we overshoot, we backtrack and try the next smaller unit.
4915     "cursor" starts out at the earlier timestamp and moves closer and closer to "later"
4916     as we use smaller and smaller units.
4917     highWater keeps track of where we would be if we added one more of the smallest unit,
4918     this is used later to potentially convert any difference smaller than the smallest higher order unit
4919     into a fraction of that smallest higher order unit
4920  */
4921  for (const [unit, differ] of differs) {
4922    if (units.indexOf(unit) >= 0) {
4923      lowestOrder = unit;
4924
4925      results[unit] = differ(cursor, later);
4926      highWater = earlier.plus(results);
4927
4928      if (highWater > later) {
4929        // we overshot the end point, backtrack cursor by 1
4930        results[unit]--;
4931        cursor = earlier.plus(results);
4932
4933        // if we are still overshooting now, we need to backtrack again
4934        // this happens in certain situations when diffing times in different zones,
4935        // because this calculation ignores time zones
4936        if (cursor > later) {
4937          // keep the "overshot by 1" around as highWater
4938          highWater = cursor;
4939          // backtrack cursor by 1
4940          results[unit]--;
4941          cursor = earlier.plus(results);
4942        }
4943      } else {
4944        cursor = highWater;
4945      }
4946    }
4947  }
4948
4949  return [cursor, results, highWater, lowestOrder];
4950}
4951
4952function diff (earlier, later, units, opts) {
4953  let [cursor, results, highWater, lowestOrder] = highOrderDiffs(earlier, later, units);
4954
4955  const remainingMillis = later - cursor;
4956
4957  const lowerOrderUnits = units.filter(
4958    (u) => ["hours", "minutes", "seconds", "milliseconds"].indexOf(u) >= 0
4959  );
4960
4961  if (lowerOrderUnits.length === 0) {
4962    if (highWater < later) {
4963      highWater = cursor.plus({ [lowestOrder]: 1 });
4964    }
4965
4966    if (highWater !== cursor) {
4967      results[lowestOrder] = (results[lowestOrder] || 0) + remainingMillis / (highWater - cursor);
4968    }
4969  }
4970
4971  const duration = Duration.fromObject(results, opts);
4972
4973  if (lowerOrderUnits.length > 0) {
4974    return Duration.fromMillis(remainingMillis, opts)
4975      .shiftTo(...lowerOrderUnits)
4976      .plus(duration);
4977  } else {
4978    return duration;
4979  }
4980}
4981
4982const MISSING_FTP = "missing Intl.DateTimeFormat.formatToParts support";
4983
4984function intUnit(regex, post = (i) => i) {
4985  return { regex, deser: ([s]) => post(parseDigits(s)) };
4986}
4987
4988const NBSP = String.fromCharCode(160);
4989const spaceOrNBSP = `[ ${NBSP}]`;
4990const spaceOrNBSPRegExp = new RegExp(spaceOrNBSP, "g");
4991
4992function fixListRegex(s) {
4993  // make dots optional and also make them literal
4994  // make space and non breakable space characters interchangeable
4995  return s.replace(/\./g, "\\.?").replace(spaceOrNBSPRegExp, spaceOrNBSP);
4996}
4997
4998function stripInsensitivities(s) {
4999  return s
5000    .replace(/\./g, "") // ignore dots that were made optional
5001    .replace(spaceOrNBSPRegExp, " ") // interchange space and nbsp
5002    .toLowerCase();
5003}
5004
5005function oneOf(strings, startIndex) {
5006  if (strings === null) {
5007    return null;
5008  } else {
5009    return {
5010      regex: RegExp(strings.map(fixListRegex).join("|")),
5011      deser: ([s]) =>
5012        strings.findIndex((i) => stripInsensitivities(s) === stripInsensitivities(i)) + startIndex,
5013    };
5014  }
5015}
5016
5017function offset(regex, groups) {
5018  return { regex, deser: ([, h, m]) => signedOffset(h, m), groups };
5019}
5020
5021function simple(regex) {
5022  return { regex, deser: ([s]) => s };
5023}
5024
5025function escapeToken(value) {
5026  return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
5027}
5028
5029/**
5030 * @param token
5031 * @param {Locale} loc
5032 */
5033function unitForToken(token, loc) {
5034  const one = digitRegex(loc),
5035    two = digitRegex(loc, "{2}"),
5036    three = digitRegex(loc, "{3}"),
5037    four = digitRegex(loc, "{4}"),
5038    six = digitRegex(loc, "{6}"),
5039    oneOrTwo = digitRegex(loc, "{1,2}"),
5040    oneToThree = digitRegex(loc, "{1,3}"),
5041    oneToSix = digitRegex(loc, "{1,6}"),
5042    oneToNine = digitRegex(loc, "{1,9}"),
5043    twoToFour = digitRegex(loc, "{2,4}"),
5044    fourToSix = digitRegex(loc, "{4,6}"),
5045    literal = (t) => ({ regex: RegExp(escapeToken(t.val)), deser: ([s]) => s, literal: true }),
5046    unitate = (t) => {
5047      if (token.literal) {
5048        return literal(t);
5049      }
5050      switch (t.val) {
5051        // era
5052        case "G":
5053          return oneOf(loc.eras("short"), 0);
5054        case "GG":
5055          return oneOf(loc.eras("long"), 0);
5056        // years
5057        case "y":
5058          return intUnit(oneToSix);
5059        case "yy":
5060          return intUnit(twoToFour, untruncateYear);
5061        case "yyyy":
5062          return intUnit(four);
5063        case "yyyyy":
5064          return intUnit(fourToSix);
5065        case "yyyyyy":
5066          return intUnit(six);
5067        // months
5068        case "M":
5069          return intUnit(oneOrTwo);
5070        case "MM":
5071          return intUnit(two);
5072        case "MMM":
5073          return oneOf(loc.months("short", true), 1);
5074        case "MMMM":
5075          return oneOf(loc.months("long", true), 1);
5076        case "L":
5077          return intUnit(oneOrTwo);
5078        case "LL":
5079          return intUnit(two);
5080        case "LLL":
5081          return oneOf(loc.months("short", false), 1);
5082        case "LLLL":
5083          return oneOf(loc.months("long", false), 1);
5084        // dates
5085        case "d":
5086          return intUnit(oneOrTwo);
5087        case "dd":
5088          return intUnit(two);
5089        // ordinals
5090        case "o":
5091          return intUnit(oneToThree);
5092        case "ooo":
5093          return intUnit(three);
5094        // time
5095        case "HH":
5096          return intUnit(two);
5097        case "H":
5098          return intUnit(oneOrTwo);
5099        case "hh":
5100          return intUnit(two);
5101        case "h":
5102          return intUnit(oneOrTwo);
5103        case "mm":
5104          return intUnit(two);
5105        case "m":
5106          return intUnit(oneOrTwo);
5107        case "q":
5108          return intUnit(oneOrTwo);
5109        case "qq":
5110          return intUnit(two);
5111        case "s":
5112          return intUnit(oneOrTwo);
5113        case "ss":
5114          return intUnit(two);
5115        case "S":
5116          return intUnit(oneToThree);
5117        case "SSS":
5118          return intUnit(three);
5119        case "u":
5120          return simple(oneToNine);
5121        case "uu":
5122          return simple(oneOrTwo);
5123        case "uuu":
5124          return intUnit(one);
5125        // meridiem
5126        case "a":
5127          return oneOf(loc.meridiems(), 0);
5128        // weekYear (k)
5129        case "kkkk":
5130          return intUnit(four);
5131        case "kk":
5132          return intUnit(twoToFour, untruncateYear);
5133        // weekNumber (W)
5134        case "W":
5135          return intUnit(oneOrTwo);
5136        case "WW":
5137          return intUnit(two);
5138        // weekdays
5139        case "E":
5140        case "c":
5141          return intUnit(one);
5142        case "EEE":
5143          return oneOf(loc.weekdays("short", false), 1);
5144        case "EEEE":
5145          return oneOf(loc.weekdays("long", false), 1);
5146        case "ccc":
5147          return oneOf(loc.weekdays("short", true), 1);
5148        case "cccc":
5149          return oneOf(loc.weekdays("long", true), 1);
5150        // offset/zone
5151        case "Z":
5152        case "ZZ":
5153          return offset(new RegExp(`([+-]${oneOrTwo.source})(?::(${two.source}))?`), 2);
5154        case "ZZZ":
5155          return offset(new RegExp(`([+-]${oneOrTwo.source})(${two.source})?`), 2);
5156        // we don't support ZZZZ (PST) or ZZZZZ (Pacific Standard Time) in parsing
5157        // because we don't have any way to figure out what they are
5158        case "z":
5159          return simple(/[a-z_+-/]{1,256}?/i);
5160        // this special-case "token" represents a place where a macro-token expanded into a white-space literal
5161        // in this case we accept any non-newline white-space
5162        case " ":
5163          return simple(/[^\S\n\r]/);
5164        default:
5165          return literal(t);
5166      }
5167    };
5168
5169  const unit = unitate(token) || {
5170    invalidReason: MISSING_FTP,
5171  };
5172
5173  unit.token = token;
5174
5175  return unit;
5176}
5177
5178const partTypeStyleToTokenVal = {
5179  year: {
5180    "2-digit": "yy",
5181    numeric: "yyyyy",
5182  },
5183  month: {
5184    numeric: "M",
5185    "2-digit": "MM",
5186    short: "MMM",
5187    long: "MMMM",
5188  },
5189  day: {
5190    numeric: "d",
5191    "2-digit": "dd",
5192  },
5193  weekday: {
5194    short: "EEE",
5195    long: "EEEE",
5196  },
5197  dayperiod: "a",
5198  dayPeriod: "a",
5199  hour12: {
5200    numeric: "h",
5201    "2-digit": "hh",
5202  },
5203  hour24: {
5204    numeric: "H",
5205    "2-digit": "HH",
5206  },
5207  minute: {
5208    numeric: "m",
5209    "2-digit": "mm",
5210  },
5211  second: {
5212    numeric: "s",
5213    "2-digit": "ss",
5214  },
5215  timeZoneName: {
5216    long: "ZZZZZ",
5217    short: "ZZZ",
5218  },
5219};
5220
5221function tokenForPart(part, formatOpts, resolvedOpts) {
5222  const { type, value } = part;
5223
5224  if (type === "literal") {
5225    const isSpace = /^\s+$/.test(value);
5226    return {
5227      literal: !isSpace,
5228      val: isSpace ? " " : value,
5229    };
5230  }
5231
5232  const style = formatOpts[type];
5233
5234  // The user might have explicitly specified hour12 or hourCycle
5235  // if so, respect their decision
5236  // if not, refer back to the resolvedOpts, which are based on the locale
5237  let actualType = type;
5238  if (type === "hour") {
5239    if (formatOpts.hour12 != null) {
5240      actualType = formatOpts.hour12 ? "hour12" : "hour24";
5241    } else if (formatOpts.hourCycle != null) {
5242      if (formatOpts.hourCycle === "h11" || formatOpts.hourCycle === "h12") {
5243        actualType = "hour12";
5244      } else {
5245        actualType = "hour24";
5246      }
5247    } else {
5248      // tokens only differentiate between 24 hours or not,
5249      // so we do not need to check hourCycle here, which is less supported anyways
5250      actualType = resolvedOpts.hour12 ? "hour12" : "hour24";
5251    }
5252  }
5253  let val = partTypeStyleToTokenVal[actualType];
5254  if (typeof val === "object") {
5255    val = val[style];
5256  }
5257
5258  if (val) {
5259    return {
5260      literal: false,
5261      val,
5262    };
5263  }
5264
5265  return undefined;
5266}
5267
5268function buildRegex(units) {
5269  const re = units.map((u) => u.regex).reduce((f, r) => `${f}(${r.source})`, "");
5270  return [`^${re}$`, units];
5271}
5272
5273function match(input, regex, handlers) {
5274  const matches = input.match(regex);
5275
5276  if (matches) {
5277    const all = {};
5278    let matchIndex = 1;
5279    for (const i in handlers) {
5280      if (hasOwnProperty(handlers, i)) {
5281        const h = handlers[i],
5282          groups = h.groups ? h.groups + 1 : 1;
5283        if (!h.literal && h.token) {
5284          all[h.token.val[0]] = h.deser(matches.slice(matchIndex, matchIndex + groups));
5285        }
5286        matchIndex += groups;
5287      }
5288    }
5289    return [matches, all];
5290  } else {
5291    return [matches, {}];
5292  }
5293}
5294
5295function dateTimeFromMatches(matches) {
5296  const toField = (token) => {
5297    switch (token) {
5298      case "S":
5299        return "millisecond";
5300      case "s":
5301        return "second";
5302      case "m":
5303        return "minute";
5304      case "h":
5305      case "H":
5306        return "hour";
5307      case "d":
5308        return "day";
5309      case "o":
5310        return "ordinal";
5311      case "L":
5312      case "M":
5313        return "month";
5314      case "y":
5315        return "year";
5316      case "E":
5317      case "c":
5318        return "weekday";
5319      case "W":
5320        return "weekNumber";
5321      case "k":
5322        return "weekYear";
5323      case "q":
5324        return "quarter";
5325      default:
5326        return null;
5327    }
5328  };
5329
5330  let zone = null;
5331  let specificOffset;
5332  if (!isUndefined(matches.z)) {
5333    zone = IANAZone.create(matches.z);
5334  }
5335
5336  if (!isUndefined(matches.Z)) {
5337    if (!zone) {
5338      zone = new FixedOffsetZone(matches.Z);
5339    }
5340    specificOffset = matches.Z;
5341  }
5342
5343  if (!isUndefined(matches.q)) {
5344    matches.M = (matches.q - 1) * 3 + 1;
5345  }
5346
5347  if (!isUndefined(matches.h)) {
5348    if (matches.h < 12 && matches.a === 1) {
5349      matches.h += 12;
5350    } else if (matches.h === 12 && matches.a === 0) {
5351      matches.h = 0;
5352    }
5353  }
5354
5355  if (matches.G === 0 && matches.y) {
5356    matches.y = -matches.y;
5357  }
5358
5359  if (!isUndefined(matches.u)) {
5360    matches.S = parseMillis(matches.u);
5361  }
5362
5363  const vals = Object.keys(matches).reduce((r, k) => {
5364    const f = toField(k);
5365    if (f) {
5366      r[f] = matches[k];
5367    }
5368
5369    return r;
5370  }, {});
5371
5372  return [vals, zone, specificOffset];
5373}
5374
5375let dummyDateTimeCache = null;
5376
5377function getDummyDateTime() {
5378  if (!dummyDateTimeCache) {
5379    dummyDateTimeCache = DateTime.fromMillis(1555555555555);
5380  }
5381
5382  return dummyDateTimeCache;
5383}
5384
5385function maybeExpandMacroToken(token, locale) {
5386  if (token.literal) {
5387    return token;
5388  }
5389
5390  const formatOpts = Formatter.macroTokenToFormatOpts(token.val);
5391  const tokens = formatOptsToTokens(formatOpts, locale);
5392
5393  if (tokens == null || tokens.includes(undefined)) {
5394    return token;
5395  }
5396
5397  return tokens;
5398}
5399
5400function expandMacroTokens(tokens, locale) {
5401  return Array.prototype.concat(...tokens.map((t) => maybeExpandMacroToken(t, locale)));
5402}
5403
5404/**
5405 * @private
5406 */
5407
5408class TokenParser {
5409  constructor(locale, format) {
5410    this.locale = locale;
5411    this.format = format;
5412    this.tokens = expandMacroTokens(Formatter.parseFormat(format), locale);
5413    this.units = this.tokens.map((t) => unitForToken(t, locale));
5414    this.disqualifyingUnit = this.units.find((t) => t.invalidReason);
5415
5416    if (!this.disqualifyingUnit) {
5417      const [regexString, handlers] = buildRegex(this.units);
5418      this.regex = RegExp(regexString, "i");
5419      this.handlers = handlers;
5420    }
5421  }
5422
5423  explainFromTokens(input) {
5424    if (!this.isValid) {
5425      return { input, tokens: this.tokens, invalidReason: this.invalidReason };
5426    } else {
5427      const [rawMatches, matches] = match(input, this.regex, this.handlers),
5428        [result, zone, specificOffset] = matches
5429          ? dateTimeFromMatches(matches)
5430          : [null, null, undefined];
5431      if (hasOwnProperty(matches, "a") && hasOwnProperty(matches, "H")) {
5432        throw new ConflictingSpecificationError(
5433          "Can't include meridiem when specifying 24-hour format"
5434        );
5435      }
5436      return {
5437        input,
5438        tokens: this.tokens,
5439        regex: this.regex,
5440        rawMatches,
5441        matches,
5442        result,
5443        zone,
5444        specificOffset,
5445      };
5446    }
5447  }
5448
5449  get isValid() {
5450    return !this.disqualifyingUnit;
5451  }
5452
5453  get invalidReason() {
5454    return this.disqualifyingUnit ? this.disqualifyingUnit.invalidReason : null;
5455  }
5456}
5457
5458function explainFromTokens(locale, input, format) {
5459  const parser = new TokenParser(locale, format);
5460  return parser.explainFromTokens(input);
5461}
5462
5463function parseFromTokens(locale, input, format) {
5464  const { result, zone, specificOffset, invalidReason } = explainFromTokens(locale, input, format);
5465  return [result, zone, specificOffset, invalidReason];
5466}
5467
5468function formatOptsToTokens(formatOpts, locale) {
5469  if (!formatOpts) {
5470    return null;
5471  }
5472
5473  const formatter = Formatter.create(locale, formatOpts);
5474  const df = formatter.dtFormatter(getDummyDateTime());
5475  const parts = df.formatToParts();
5476  const resolvedOpts = df.resolvedOptions();
5477  return parts.map((p) => tokenForPart(p, formatOpts, resolvedOpts));
5478}
5479
5480const INVALID = "Invalid DateTime";
5481const MAX_DATE = 8.64e15;
5482
5483function unsupportedZone(zone) {
5484  return new Invalid("unsupported zone", `the zone "${zone.name}" is not supported`);
5485}
5486
5487// we cache week data on the DT object and this intermediates the cache
5488/**
5489 * @param {DateTime} dt
5490 */
5491function possiblyCachedWeekData(dt) {
5492  if (dt.weekData === null) {
5493    dt.weekData = gregorianToWeek(dt.c);
5494  }
5495  return dt.weekData;
5496}
5497
5498/**
5499 * @param {DateTime} dt
5500 */
5501function possiblyCachedLocalWeekData(dt) {
5502  if (dt.localWeekData === null) {
5503    dt.localWeekData = gregorianToWeek(
5504      dt.c,
5505      dt.loc.getMinDaysInFirstWeek(),
5506      dt.loc.getStartOfWeek()
5507    );
5508  }
5509  return dt.localWeekData;
5510}
5511
5512// clone really means, "make a new object with these modifications". all "setters" really use this
5513// to create a new object while only changing some of the properties
5514function clone(inst, alts) {
5515  const current = {
5516    ts: inst.ts,
5517    zone: inst.zone,
5518    c: inst.c,
5519    o: inst.o,
5520    loc: inst.loc,
vendor: 7,114 bytes, lines 5521-5799
5521    invalid: inst.invalid,
5522  };
5523  return new DateTime({ ...current, ...alts, old: current });
5524}
5525
5526// find the right offset a given local time. The o input is our guess, which determines which
5527// offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
5528function fixOffset(localTS, o, tz) {
5529  // Our UTC time is just a guess because our offset is just a guess
5530  let utcGuess = localTS - o * 60 * 1000;
5531
5532  // Test whether the zone matches the offset for this ts
5533  const o2 = tz.offset(utcGuess);
5534
5535  // If so, offset didn't change and we're done
5536  if (o === o2) {
5537    return [utcGuess, o];
5538  }
5539
5540  // If not, change the ts by the difference in the offset
5541  utcGuess -= (o2 - o) * 60 * 1000;
5542
5543  // If that gives us the local time we want, we're done
5544  const o3 = tz.offset(utcGuess);
5545  if (o2 === o3) {
5546    return [utcGuess, o2];
5547  }
5548
5549  // If it's different, we're in a hole time. The offset has changed, but the we don't adjust the time
5550  return [localTS - Math.min(o2, o3) * 60 * 1000, Math.max(o2, o3)];
5551}
5552
5553// convert an epoch timestamp into a calendar object with the given offset
5554function tsToObj(ts, offset) {
5555  ts += offset * 60 * 1000;
5556
5557  const d = new Date(ts);
5558
5559  return {
5560    year: d.getUTCFullYear(),
5561    month: d.getUTCMonth() + 1,
5562    day: d.getUTCDate(),
5563    hour: d.getUTCHours(),
5564    minute: d.getUTCMinutes(),
5565    second: d.getUTCSeconds(),
5566    millisecond: d.getUTCMilliseconds(),
5567  };
5568}
5569
5570// convert a calendar object to a epoch timestamp
5571function objToTS(obj, offset, zone) {
5572  return fixOffset(objToLocalTS(obj), offset, zone);
5573}
5574
5575// create a new DT instance by adding a duration, adjusting for DSTs
5576function adjustTime(inst, dur) {
5577  const oPre = inst.o,
5578    year = inst.c.year + Math.trunc(dur.years),
5579    month = inst.c.month + Math.trunc(dur.months) + Math.trunc(dur.quarters) * 3,
5580    c = {
5581      ...inst.c,
5582      year,
5583      month,
5584      day:
5585        Math.min(inst.c.day, daysInMonth(year, month)) +
5586        Math.trunc(dur.days) +
5587        Math.trunc(dur.weeks) * 7,
5588    },
5589    millisToAdd = Duration.fromObject({
5590      years: dur.years - Math.trunc(dur.years),
5591      quarters: dur.quarters - Math.trunc(dur.quarters),
5592      months: dur.months - Math.trunc(dur.months),
5593      weeks: dur.weeks - Math.trunc(dur.weeks),
5594      days: dur.days - Math.trunc(dur.days),
5595      hours: dur.hours,
5596      minutes: dur.minutes,
5597      seconds: dur.seconds,
5598      milliseconds: dur.milliseconds,
5599    }).as("milliseconds"),
5600    localTS = objToLocalTS(c);
5601
5602  let [ts, o] = fixOffset(localTS, oPre, inst.zone);
5603
5604  if (millisToAdd !== 0) {
5605    ts += millisToAdd;
5606    // that could have changed the offset by going over a DST, but we want to keep the ts the same
5607    o = inst.zone.offset(ts);
5608  }
5609
5610  return { ts, o };
5611}
5612
5613// helper useful in turning the results of parsing into real dates
5614// by handling the zone options
5615function parseDataToDateTime(parsed, parsedZone, opts, format, text, specificOffset) {
5616  const { setZone, zone } = opts;
5617  if ((parsed && Object.keys(parsed).length !== 0) || parsedZone) {
5618    const interpretationZone = parsedZone || zone,
5619      inst = DateTime.fromObject(parsed, {
5620        ...opts,
5621        zone: interpretationZone,
5622        specificOffset,
5623      });
5624    return setZone ? inst : inst.setZone(zone);
5625  } else {
5626    return DateTime.invalid(
5627      new Invalid("unparsable", `the input "${text}" can't be parsed as ${format}`)
5628    );
5629  }
5630}
5631
5632// if you want to output a technical format (e.g. RFC 2822), this helper
5633// helps handle the details
5634function toTechFormat(dt, format, allowZ = true) {
5635  return dt.isValid
5636    ? Formatter.create(Locale.create("en-US"), {
5637        allowZ,
5638        forceSimple: true,
5639      }).formatDateTimeFromString(dt, format)
5640    : null;
5641}
5642
5643function toISODate(o, extended) {
5644  const longFormat = o.c.year > 9999 || o.c.year < 0;
5645  let c = "";
5646  if (longFormat && o.c.year >= 0) c += "+";
5647  c += padStart(o.c.year, longFormat ? 6 : 4);
5648
5649  if (extended) {
5650    c += "-";
5651    c += padStart(o.c.month);
5652    c += "-";
5653    c += padStart(o.c.day);
5654  } else {
5655    c += padStart(o.c.month);
5656    c += padStart(o.c.day);
5657  }
5658  return c;
5659}
5660
5661function toISOTime(
5662  o,
5663  extended,
5664  suppressSeconds,
5665  suppressMilliseconds,
5666  includeOffset,
5667  extendedZone
5668) {
5669  let c = padStart(o.c.hour);
5670  if (extended) {
5671    c += ":";
5672    c += padStart(o.c.minute);
5673    if (o.c.millisecond !== 0 || o.c.second !== 0 || !suppressSeconds) {
5674      c += ":";
5675    }
5676  } else {
5677    c += padStart(o.c.minute);
5678  }
5679
5680  if (o.c.millisecond !== 0 || o.c.second !== 0 || !suppressSeconds) {
5681    c += padStart(o.c.second);
5682
5683    if (o.c.millisecond !== 0 || !suppressMilliseconds) {
5684      c += ".";
5685      c += padStart(o.c.millisecond, 3);
5686    }
5687  }
5688
5689  if (includeOffset) {
5690    if (o.isOffsetFixed && o.offset === 0 && !extendedZone) {
5691      c += "Z";
5692    } else if (o.o < 0) {
5693      c += "-";
5694      c += padStart(Math.trunc(-o.o / 60));
5695      c += ":";
5696      c += padStart(Math.trunc(-o.o % 60));
5697    } else {
5698      c += "+";
5699      c += padStart(Math.trunc(o.o / 60));
5700      c += ":";
5701      c += padStart(Math.trunc(o.o % 60));
5702    }
5703  }
5704
5705  if (extendedZone) {
5706    c += "[" + o.zone.ianaName + "]";
5707  }
5708  return c;
5709}
5710
5711// defaults for unspecified units in the supported calendars
5712const defaultUnitValues = {
5713    month: 1,
5714    day: 1,
5715    hour: 0,
5716    minute: 0,
5717    second: 0,
5718    millisecond: 0,
5719  },
5720  defaultWeekUnitValues = {
5721    weekNumber: 1,
5722    weekday: 1,
5723    hour: 0,
5724    minute: 0,
5725    second: 0,
5726    millisecond: 0,
5727  },
5728  defaultOrdinalUnitValues = {
5729    ordinal: 1,
5730    hour: 0,
5731    minute: 0,
5732    second: 0,
5733    millisecond: 0,
5734  };
5735
5736// Units in the supported calendars, sorted by bigness
5737const orderedUnits = ["year", "month", "day", "hour", "minute", "second", "millisecond"],
5738  orderedWeekUnits = [
5739    "weekYear",
5740    "weekNumber",
5741    "weekday",
5742    "hour",
5743    "minute",
5744    "second",
5745    "millisecond",
5746  ],
5747  orderedOrdinalUnits = ["year", "ordinal", "hour", "minute", "second", "millisecond"];
5748
5749// standardize case and plurality in units
5750function normalizeUnit(unit) {
5751  const normalized = {
5752    year: "year",
5753    years: "year",
5754    month: "month",
5755    months: "month",
5756    day: "day",
5757    days: "day",
5758    hour: "hour",
5759    hours: "hour",
5760    minute: "minute",
5761    minutes: "minute",
5762    quarter: "quarter",
5763    quarters: "quarter",
5764    second: "second",
5765    seconds: "second",
5766    millisecond: "millisecond",
5767    milliseconds: "millisecond",
5768    weekday: "weekday",
5769    weekdays: "weekday",
5770    weeknumber: "weekNumber",
5771    weeksnumber: "weekNumber",
5772    weeknumbers: "weekNumber",
5773    weekyear: "weekYear",
5774    weekyears: "weekYear",
5775    ordinal: "ordinal",
5776  }[unit.toLowerCase()];
5777
5778  if (!normalized) throw new InvalidUnitError(unit);
5779
5780  return normalized;
5781}
5782
5783function normalizeUnitWithLocalWeeks(unit) {
5784  switch (unit.toLowerCase()) {
5785    case "localweekday":
5786    case "localweekdays":
5787      return "localWeekday";
5788    case "localweeknumber":
5789    case "localweeknumbers":
5790      return "localWeekNumber";
5791    case "localweekyear":
5792    case "localweekyears":
5793      return "localWeekYear";
5794    default:
5795      return normalizeUnit(unit);
5796  }
5797}
5798
5799// 
5799cache offsets for zones based on the current timestamp when this function is
5800// first called. When we are handling a datetime from components like (year,
5801// month, day, hour) in a time zone, we need a guess about what the timezone
5802// offset is so that we can convert into a UTC timestamp. One way is to find the
5803// offset of now in the zone. The actual date may have a different offset (for
5804// example, if we handle a date in June while we're in December in a zone that
5805// observes DST), but we can check and adjust that.
5806//
5807// When handling many dates, calculating the offset for now every time is
5808// expensive. It's just a guess, so we can cache the offset to use even if we
5809// are right on a time change boundary (we'll just correct in the other
5810// direction). Using a timestamp from first read is a slight optimization for
5811// handling dates close to the current date, since those dates will usually be
5812// in the same offset (we could set the timestamp statically, instead). We use a
5813// single timestamp for all zones to make things a bit more predictable.
5814//
5815// This is safe for quickDT (used by local() and utc()) because we don't fill in
5816// higher-order units from tsNow (as we do in fromObject, this requires that
5817// offset is calculated from tsNow).
5818function guessOffsetForZone(zone) {
5819  if (!zoneOffsetGuessCache[zone]) {
5820    if (zoneOffsetTs === undefined) {
5821      zoneOffsetTs = Settings.now();
5822    }
5823
5824    zoneOffsetGuessCache[zone] = zone.offset(zoneOffsetTs);
5825  }
5826  return zoneOffsetGuessCache[zone];
5827}
5828
5829// this is a dumbed down version of fromObject() that runs about 60% faster
5830// but doesn't do any validation, makes a bunch of assumptions about what units
5831// are present, and so on.
5832function quickDT(obj, opts) {
5833  const zone = normalizeZone(opts.zone, Settings.defaultZone);
5834  if (!zone.isValid) {
5835    return DateTime.invalid(unsupportedZone(zone));
5836  }
5837
5838  const loc = Locale.fromObject(opts);
5839
5840  let ts, o;
5841
5842  // assume we have the higher-order units
5843  if (!isUndefined(obj.year)) {
5844    for (const u of orderedUnits) {
5845      if (isUndefined(obj[u])) {
vendor: 1,849 bytes, lines 5846-5916
5846        obj[u] = defaultUnitValues[u];
5847      }
5848    }
5849
5850    const invalid = hasInvalidGregorianData(obj) || hasInvalidTimeData(obj);
5851    if (invalid) {
5852      return DateTime.invalid(invalid);
5853    }
5854
5855    const offsetProvis = guessOffsetForZone(zone);
5856    [ts, o] = objToTS(obj, offsetProvis, zone);
5857  } else {
5858    ts = Settings.now();
5859  }
5860
5861  return new DateTime({ ts, zone, loc, o });
5862}
5863
5864function diffRelative(start, end, opts) {
5865  const round = isUndefined(opts.round) ? true : opts.round,
5866    format = (c, unit) => {
5867      c = roundTo(c, round || opts.calendary ? 0 : 2, true);
5868      const formatter = end.loc.clone(opts).relFormatter(opts);
5869      return formatter.format(c, unit);
5870    },
5871    differ = (unit) => {
5872      if (opts.calendary) {
5873        if (!end.hasSame(start, unit)) {
5874          return end.startOf(unit).diff(start.startOf(unit), unit).get(unit);
5875        } else return 0;
5876      } else {
5877        return end.diff(start, unit).get(unit);
5878      }
5879    };
5880
5881  if (opts.unit) {
5882    return format(differ(opts.unit), opts.unit);
5883  }
5884
5885  for (const unit of opts.units) {
5886    const count = differ(unit);
5887    if (Math.abs(count) >= 1) {
5888      return format(count, unit);
5889    }
5890  }
5891  return format(start > end ? -0 : 0, opts.units[opts.units.length - 1]);
5892}
5893
5894function lastOpts(argList) {
5895  let opts = {},
5896    args;
5897  if (argList.length > 0 && typeof argList[argList.length - 1] === "object") {
5898    opts = argList[argList.length - 1];
5899    args = Array.from(argList).slice(0, argList.length - 1);
5900  } else {
5901    args = Array.from(argList);
5902  }
5903  return [opts, args];
5904}
5905
5906/**
5907 * Timestamp to use for cached zone offset guesses (exposed for test)
5908 */
5909let zoneOffsetTs;
5910/**
5911 * Cache for zone offset guesses (exposed for test).
5912 *
5913 * This optimizes quickDT via guessOffsetForZone to avoid repeated calls of
5914 * zone.offset().
5915 */
5916let zoneOffsetGuessCache = {}
vendor: 28,762 bytes, lines 5916-6481
5916;
5917
5918/**
5919 * A DateTime is an immutable data structure representing a specific date and time and accompanying methods. It contains class and instance methods for creating, parsing, interrogating, transforming, and formatting them.
5920 *
5921 * A DateTime comprises of:
5922 * * A timestamp. Each DateTime instance refers to a specific millisecond of the Unix epoch.
5923 * * A time zone. Each instance is considered in the context of a specific zone (by default the local system's zone).
5924 * * Configuration properties that effect how output strings are formatted, such as `locale`, `numberingSystem`, and `outputCalendar`.
5925 *
5926 * Here is a brief overview of the most commonly used functionality it provides:
5927 *
5928 * * **Creation**: To create a DateTime from its components, use one of its factory class methods: {@link DateTime.local}, {@link DateTime.utc}, and (most flexibly) {@link DateTime.fromObject}. To create one from a standard string format, use {@link DateTime.fromISO}, {@link DateTime.fromHTTP}, and {@link DateTime.fromRFC2822}. To create one from a custom string format, use {@link DateTime.fromFormat}. To create one from a native JS date, use {@link DateTime.fromJSDate}.
5929 * * **Gregorian calendar and time**: To examine the Gregorian properties of a DateTime individually (i.e as opposed to collectively through {@link DateTime#toObject}), use the {@link DateTime#year}, {@link DateTime#month},
5930 * {@link DateTime#day}, {@link DateTime#hour}, {@link DateTime#minute}, {@link DateTime#second}, {@link DateTime#millisecond} accessors.
5931 * * **Week calendar**: For ISO week calendar attributes, see the {@link DateTime#weekYear}, {@link DateTime#weekNumber}, and {@link DateTime#weekday} accessors.
5932 * * **Configuration** See the {@link DateTime#locale} and {@link DateTime#numberingSystem} accessors.
5933 * * **Transformation**: To transform the DateTime into other DateTimes, use {@link DateTime#set}, {@link DateTime#reconfigure}, {@link DateTime#setZone}, {@link DateTime#setLocale}, {@link DateTime.plus}, {@link DateTime#minus}, {@link DateTime#endOf}, {@link DateTime#startOf}, {@link DateTime#toUTC}, and {@link DateTime#toLocal}.
5934 * * **Output**: To convert the DateTime to other representations, use the {@link DateTime#toRelative}, {@link DateTime#toRelativeCalendar}, {@link DateTime#toJSON}, {@link DateTime#toISO}, {@link DateTime#toHTTP}, {@link DateTime#toObject}, {@link DateTime#toRFC2822}, {@link DateTime#toString}, {@link DateTime#toLocaleString}, {@link DateTime#toFormat}, {@link DateTime#toMillis} and {@link DateTime#toJSDate}.
5935 *
5936 * There's plenty others documented below. In addition, for more information on subtler topics like internationalization, time zones, alternative calendars, validity, and so on, see the external documentation.
5937 */
5938class DateTime {
5939  /**
5940   * @access private
5941   */
5942  constructor(config) {
5943    const zone = config.zone || Settings.defaultZone;
5944
5945    let invalid =
5946      config.invalid ||
5947      (Number.isNaN(config.ts) ? new Invalid("invalid input") : null) ||
5948      (!zone.isValid ? unsupportedZone(zone) : null);
5949    /**
5950     * @access private
5951     */
5952    this.ts = isUndefined(config.ts) ? Settings.now() : config.ts;
5953
5954    let c = null,
5955      o = null;
5956    if (!invalid) {
5957      const unchanged = config.old && config.old.ts === this.ts && config.old.zone.equals(zone);
5958
5959      if (unchanged) {
5960        [c, o] = [config.old.c, config.old.o];
5961      } else {
5962        // If an offset has been passed and we have not been called from
5963        // clone(), we can trust it and avoid the offset calculation.
5964        const ot = isNumber(config.o) && !config.old ? config.o : zone.offset(this.ts);
5965        c = tsToObj(this.ts, ot);
5966        invalid = Number.isNaN(c.year) ? new Invalid("invalid input") : null;
5967        c = invalid ? null : c;
5968        o = invalid ? null : ot;
5969      }
5970    }
5971
5972    /**
5973     * @access private
5974     */
5975    this._zone = zone;
5976    /**
5977     * @access private
5978     */
5979    this.loc = config.loc || Locale.create();
5980    /**
5981     * @access private
5982     */
5983    this.invalid = invalid;
5984    /**
5985     * @access private
5986     */
5987    this.weekData = null;
5988    /**
5989     * @access private
5990     */
5991    this.localWeekData = null;
5992    /**
5993     * @access private
5994     */
5995    this.c = c;
5996    /**
5997     * @access private
5998     */
5999    this.o = o;
6000    /**
6001     * @access private
6002     */
6003    this.isLuxonDateTime = true;
6004  }
6005
6006  // CONSTRUCT
6007
6008  /**
6009   * Create a DateTime for the current instant, in the system's time zone.
6010   *
6011   * Use Settings to override these default values if needed.
6012   * @example DateTime.now().toISO() //~> now in the ISO format
6013   * @return {DateTime}
6014   */
6015  static now() {
6016    return new DateTime({});
6017  }
6018
6019  /**
6020   * Create a local DateTime
6021   * @param {number} [year] - The calendar year. If omitted (as in, call `local()` with no arguments), the current time will be used
6022   * @param {number} [month=1] - The month, 1-indexed
6023   * @param {number} [day=1] - The day of the month, 1-indexed
6024   * @param {number} [hour=0] - The hour of the day, in 24-hour time
6025   * @param {number} [minute=0] - The minute of the hour, meaning a number between 0 and 59
6026   * @param {number} [second=0] - The second of the minute, meaning a number between 0 and 59
6027   * @param {number} [millisecond=0] - The millisecond of the second, meaning a number between 0 and 999
6028   * @example DateTime.local()                                  //~> now
6029   * @example DateTime.local({ zone: "America/New_York" })      //~> now, in US east coast time
6030   * @example DateTime.local(2017)                              //~> 2017-01-01T00:00:00
6031   * @example DateTime.local(2017, 3)                           //~> 2017-03-01T00:00:00
6032   * @example DateTime.local(2017, 3, 12, { locale: "fr" })     //~> 2017-03-12T00:00:00, with a French locale
6033   * @example DateTime.local(2017, 3, 12, 5)                    //~> 2017-03-12T05:00:00
6034   * @example DateTime.local(2017, 3, 12, 5, { zone: "utc" })   //~> 2017-03-12T05:00:00, in UTC
6035   * @example DateTime.local(2017, 3, 12, 5, 45)                //~> 2017-03-12T05:45:00
6036   * @example DateTime.local(2017, 3, 12, 5, 45, 10)            //~> 2017-03-12T05:45:10
6037   * @example DateTime.local(2017, 3, 12, 5, 45, 10, 765)       //~> 2017-03-12T05:45:10.765
6038   * @return {DateTime}
6039   */
6040  static local() {
6041    const [opts, args] = lastOpts(arguments),
6042      [year, month, day, hour, minute, second, millisecond] = args;
6043    return quickDT({ year, month, day, hour, minute, second, millisecond }, opts);
6044  }
6045
6046  /**
6047   * Create a DateTime in UTC
6048   * @param {number} [year] - The calendar year. If omitted (as in, call `utc()` with no arguments), the current time will be used
6049   * @param {number} [month=1] - The month, 1-indexed
6050   * @param {number} [day=1] - The day of the month
6051   * @param {number} [hour=0] - The hour of the day, in 24-hour time
6052   * @param {number} [minute=0] - The minute of the hour, meaning a number between 0 and 59
6053   * @param {number} [second=0] - The second of the minute, meaning a number between 0 and 59
6054   * @param {number} [millisecond=0] - The millisecond of the second, meaning a number between 0 and 999
6055   * @param {Object} options - configuration options for the DateTime
6056   * @param {string} [options.locale] - a locale to set on the resulting DateTime instance
6057   * @param {string} [options.outputCalendar] - the output calendar to set on the resulting DateTime instance
6058   * @param {string} [options.numberingSystem] - the numbering system to set on the resulting DateTime instance
6059   * @param {string} [options.weekSettings] - the week settings to set on the resulting DateTime instance
6060   * @example DateTime.utc()                                              //~> now
6061   * @example DateTime.utc(2017)                                          //~> 2017-01-01T00:00:00Z
6062   * @example DateTime.utc(2017, 3)                                       //~> 2017-03-01T00:00:00Z
6063   * @example DateTime.utc(2017, 3, 12)                                   //~> 2017-03-12T00:00:00Z
6064   * @example DateTime.utc(2017, 3, 12, 5)                                //~> 2017-03-12T05:00:00Z
6065   * @example DateTime.utc(2017, 3, 12, 5, 45)                            //~> 2017-03-12T05:45:00Z
6066   * @example DateTime.utc(2017, 3, 12, 5, 45, { locale: "fr" })          //~> 2017-03-12T05:45:00Z with a French locale
6067   * @example DateTime.utc(2017, 3, 12, 5, 45, 10)                        //~> 2017-03-12T05:45:10Z
6068   * @example DateTime.utc(2017, 3, 12, 5, 45, 10, 765, { locale: "fr" }) //~> 2017-03-12T05:45:10.765Z with a French locale
6069   * @return {DateTime}
6070   */
6071  static utc() {
6072    const [opts, args] = lastOpts(arguments),
6073      [year, month, day, hour, minute, second, millisecond] = args;
6074
6075    opts.zone = FixedOffsetZone.utcInstance;
6076    return quickDT({ year, month, day, hour, minute, second, millisecond }, opts);
6077  }
6078
6079  /**
6080   * Create a DateTime from a JavaScript Date object. Uses the default zone.
6081   * @param {Date} date - a JavaScript Date object
6082   * @param {Object} options - configuration options for the DateTime
6083   * @param {string|Zone} [options.zone='local'] - the zone to place the DateTime into
6084   * @return {DateTime}
6085   */
6086  static fromJSDate(date, options = {}) {
6087    const ts = isDate(date) ? date.valueOf() : NaN;
6088    if (Number.isNaN(ts)) {
6089      return DateTime.invalid("invalid input");
6090    }
6091
6092    const zoneToUse = normalizeZone(options.zone, Settings.defaultZone);
6093    if (!zoneToUse.isValid) {
6094      return DateTime.invalid(unsupportedZone(zoneToUse));
6095    }
6096
6097    return new DateTime({
6098      ts: ts,
6099      zone: zoneToUse,
6100      loc: Locale.fromObject(options),
6101    });
6102  }
6103
6104  /**
6105   * Create a DateTime from a number of milliseconds since the epoch (meaning since 1 January 1970 00:00:00 UTC). Uses the default zone.
6106   * @param {number} milliseconds - a number of milliseconds since 1970 UTC
6107   * @param {Object} options - configuration options for the DateTime
6108   * @param {string|Zone} [options.zone='local'] - the zone to place the DateTime into
6109   * @param {string} [options.locale] - a locale to set on the resulting DateTime instance
6110   * @param {string} options.outputCalendar - the output calendar to set on the resulting DateTime instance
6111   * @param {string} options.numberingSystem - the numbering system to set on the resulting DateTime instance
6112   * @param {string} options.weekSettings - the week settings to set on the resulting DateTime instance
6113   * @return {DateTime}
6114   */
6115  static fromMillis(milliseconds, options = {}) {
6116    if (!isNumber(milliseconds)) {
6117      throw new InvalidArgumentError(
6118        `fromMillis requires a numerical input, but received a ${typeof milliseconds} with value ${milliseconds}`
6119      );
6120    } else if (milliseconds < -MAX_DATE || milliseconds > MAX_DATE) {
6121      // this isn't perfect because we can still end up out of range because of additional shifting, but it's a start
6122      return DateTime.invalid("Timestamp out of range");
6123    } else {
6124      return new DateTime({
6125        ts: milliseconds,
6126        zone: normalizeZone(options.zone, Settings.defaultZone),
6127        loc: Locale.fromObject(options),
6128      });
6129    }
6130  }
6131
6132  /**
6133   * Create a DateTime from a number of seconds since the epoch (meaning since 1 January 1970 00:00:00 UTC). Uses the default zone.
6134   * @param {number} seconds - a number of seconds since 1970 UTC
6135   * @param {Object} options - configuration options for the DateTime
6136   * @param {string|Zone} [options.zone='local'] - the zone to place the DateTime into
6137   * @param {string} [options.locale] - a locale to set on the resulting DateTime instance
6138   * @param {string} options.outputCalendar - the output calendar to set on the resulting DateTime instance
6139   * @param {string} options.numberingSystem - the numbering system to set on the resulting DateTime instance
6140   * @param {string} options.weekSettings - the week settings to set on the resulting DateTime instance
6141   * @return {DateTime}
6142   */
6143  static fromSeconds(seconds, options = {}) {
6144    if (!isNumber(seconds)) {
6145      throw new InvalidArgumentError("fromSeconds requires a numerical input");
6146    } else {
6147      return new DateTime({
6148        ts: seconds * 1000,
6149        zone: normalizeZone(options.zone, Settings.defaultZone),
6150        loc: Locale.fromObject(options),
6151      });
6152    }
6153  }
6154
6155  /**
6156   * Create a DateTime from a JavaScript object with keys like 'year' and 'hour' with reasonable defaults.
6157   * @param {Object} obj - the object to create the DateTime from
6158   * @param {number} obj.year - a year, such as 1987
6159   * @param {number} obj.month - a month, 1-12
6160   * @param {number} obj.day - a day of the month, 1-31, depending on the month
6161   * @param {number} obj.ordinal - day of the year, 1-365 or 366
6162   * @param {number} obj.weekYear - an ISO week year
6163   * @param {number} obj.weekNumber - an ISO week number, between 1 and 52 or 53, depending on the year
6164   * @param {number} obj.weekday - an ISO weekday, 1-7, where 1 is Monday and 7 is Sunday
6165   * @param {number} obj.localWeekYear - a week year, according to the locale
6166   * @param {number} obj.localWeekNumber - a week number, between 1 and 52 or 53, depending on the year, according to the locale
6167   * @param {number} obj.localWeekday - a weekday, 1-7, where 1 is the first and 7 is the last day of the week, according to the locale
6168   * @param {number} obj.hour - hour of the day, 0-23
6169   * @param {number} obj.minute - minute of the hour, 0-59
6170   * @param {number} obj.second - second of the minute, 0-59
6171   * @param {number} obj.millisecond - millisecond of the second, 0-999
6172   * @param {Object} opts - options for creating this DateTime
6173   * @param {string|Zone} [opts.zone='local'] - interpret the numbers in the context of a particular zone. Can take any value taken as the first argument to setZone()
6174   * @param {string} [opts.locale='system\'s locale'] - a locale to set on the resulting DateTime instance
6175   * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance
6176   * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance
6177   * @param {string} opts.weekSettings - the week settings to set on the resulting DateTime instance
6178   * @example DateTime.fromObject({ year: 1982, month: 5, day: 25}).toISODate() //=> '1982-05-25'
6179   * @example DateTime.fromObject({ year: 1982 }).toISODate() //=> '1982-01-01'
6180   * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }) //~> today at 10:26:06
6181   * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'utc' }),
6182   * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'local' })
6183   * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'America/New_York' })
6184   * @example DateTime.fromObject({ weekYear: 2016, weekNumber: 2, weekday: 3 }).toISODate() //=> '2016-01-13'
6185   * @example DateTime.fromObject({ localWeekYear: 2022, localWeekNumber: 1, localWeekday: 1 }, { locale: "en-US" }).toISODate() //=> '2021-12-26'
6186   * @return {DateTime}
6187   */
6188  static fromObject(obj, opts = {}) {
6189    obj = obj || {};
6190    const zoneToUse = normalizeZone(opts.zone, Settings.defaultZone);
6191    if (!zoneToUse.isValid) {
6192      return DateTime.invalid(unsupportedZone(zoneToUse));
6193    }
6194
6195    const loc = Locale.fromObject(opts);
6196    const normalized = normalizeObject(obj, normalizeUnitWithLocalWeeks);
6197    const { minDaysInFirstWeek, startOfWeek } = usesLocalWeekValues(normalized, loc);
6198
6199    const tsNow = Settings.now(),
6200      offsetProvis = !isUndefined(opts.specificOffset)
6201        ? opts.specificOffset
6202        : zoneToUse.offset(tsNow),
6203      containsOrdinal = !isUndefined(normalized.ordinal),
6204      containsGregorYear = !isUndefined(normalized.year),
6205      containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day),
6206      containsGregor = containsGregorYear || containsGregorMD,
6207      definiteWeekDef = normalized.weekYear || normalized.weekNumber;
6208
6209    // cases:
6210    // just a weekday -> this week's instance of that weekday, no worries
6211    // (gregorian data or ordinal) + (weekYear or weekNumber) -> error
6212    // (gregorian month or day) + ordinal -> error
6213    // otherwise just use weeks or ordinals or gregorian, depending on what's specified
6214
6215    if ((containsGregor || containsOrdinal) && definiteWeekDef) {
6216      throw new ConflictingSpecificationError(
6217        "Can't mix weekYear/weekNumber units with year/month/day or ordinals"
6218      );
6219    }
6220
6221    if (containsGregorMD && containsOrdinal) {
6222      throw new ConflictingSpecificationError("Can't mix ordinal dates with month/day");
6223    }
6224
6225    const useWeekData = definiteWeekDef || (normalized.weekday && !containsGregor);
6226
6227    // configure ourselves to deal with gregorian dates or week stuff
6228    let units,
6229      defaultValues,
6230      objNow = tsToObj(tsNow, offsetProvis);
6231    if (useWeekData) {
6232      units = orderedWeekUnits;
6233      defaultValues = defaultWeekUnitValues;
6234      objNow = gregorianToWeek(objNow, minDaysInFirstWeek, startOfWeek);
6235    } else if (containsOrdinal) {
6236      units = orderedOrdinalUnits;
6237      defaultValues = defaultOrdinalUnitValues;
6238      objNow = gregorianToOrdinal(objNow);
6239    } else {
6240      units = orderedUnits;
6241      defaultValues = defaultUnitValues;
6242    }
6243
6244    // set default values for missing stuff
6245    let foundFirst = false;
6246    for (const u of units) {
6247      const v = normalized[u];
6248      if (!isUndefined(v)) {
6249        foundFirst = true;
6250      } else if (foundFirst) {
6251        normalized[u] = defaultValues[u];
6252      } else {
6253        normalized[u] = objNow[u];
6254      }
6255    }
6256
6257    // make sure the values we have are in range
6258    const higherOrderInvalid = useWeekData
6259        ? hasInvalidWeekData(normalized, minDaysInFirstWeek, startOfWeek)
6260        : containsOrdinal
6261        ? hasInvalidOrdinalData(normalized)
6262        : hasInvalidGregorianData(normalized),
6263      invalid = higherOrderInvalid || hasInvalidTimeData(normalized);
6264
6265    if (invalid) {
6266      return DateTime.invalid(invalid);
6267    }
6268
6269    // compute the actual time
6270    const gregorian = useWeekData
6271        ? weekToGregorian(normalized, minDaysInFirstWeek, startOfWeek)
6272        : containsOrdinal
6273        ? ordinalToGregorian(normalized)
6274        : normalized,
6275      [tsFinal, offsetFinal] = objToTS(gregorian, offsetProvis, zoneToUse),
6276      inst = new DateTime({
6277        ts: tsFinal,
6278        zone: zoneToUse,
6279        o: offsetFinal,
6280        loc,
6281      });
6282
6283    // gregorian data + weekday serves only to validate
6284    if (normalized.weekday && containsGregor && obj.weekday !== inst.weekday) {
6285      return DateTime.invalid(
6286        "mismatched weekday",
6287        `you can't specify both a weekday of ${normalized.weekday} and a date of ${inst.toISO()}`
6288      );
6289    }
6290
6291    if (!inst.isValid) {
6292      return DateTime.invalid(inst.invalid);
6293    }
6294
6295    return inst;
6296  }
6297
6298  /**
6299   * Create a DateTime from an ISO 8601 string
6300   * @param {string} text - the ISO string
6301   * @param {Object} opts - options to affect the creation
6302   * @param {string|Zone} [opts.zone='local'] - use this zone if no offset is specified in the input string itself. Will also convert the time to this zone
6303   * @param {boolean} [opts.setZone=false] - override the zone with a fixed-offset zone specified in the string itself, if it specifies one
6304   * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance
6305   * @param {string} [opts.outputCalendar] - the output calendar to set on the resulting DateTime instance
6306   * @param {string} [opts.numberingSystem] - the numbering system to set on the resulting DateTime instance
6307   * @param {string} [opts.weekSettings] - the week settings to set on the resulting DateTime instance
6308   * @example DateTime.fromISO('2016-05-25T09:08:34.123')
6309   * @example DateTime.fromISO('2016-05-25T09:08:34.123+06:00')
6310   * @example DateTime.fromISO('2016-05-25T09:08:34.123+06:00', {setZone: true})
6311   * @example DateTime.fromISO('2016-05-25T09:08:34.123', {zone: 'utc'})
6312   * @example DateTime.fromISO('2016-W05-4')
6313   * @return {DateTime}
6314   */
6315  static fromISO(text, opts = {}) {
6316    const [vals, parsedZone] = parseISODate(text);
6317    return parseDataToDateTime(vals, parsedZone, opts, "ISO 8601", text);
6318  }
6319
6320  /**
6321   * Create a DateTime from an RFC 2822 string
6322   * @param {string} text - the RFC 2822 string
6323   * @param {Object} opts - options to affect the creation
6324   * @param {string|Zone} [opts.zone='local'] - convert the time to this zone. Since the offset is always specified in the string itself, this has no effect on the interpretation of string, merely the zone the resulting DateTime is expressed in.
6325   * @param {boolean} [opts.setZone=false] - override the zone with a fixed-offset zone specified in the string itself, if it specifies one
6326   * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance
6327   * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance
6328   * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance
6329   * @param {string} opts.weekSettings - the week settings to set on the resulting DateTime instance
6330   * @example DateTime.fromRFC2822('25 Nov 2016 13:23:12 GMT')
6331   * @example DateTime.fromRFC2822('Fri, 25 Nov 2016 13:23:12 +0600')
6332   * @example DateTime.fromRFC2822('25 Nov 2016 13:23 Z')
6333   * @return {DateTime}
6334   */
6335  static fromRFC2822(text, opts = {}) {
6336    const [vals, parsedZone] = parseRFC2822Date(text);
6337    return parseDataToDateTime(vals, parsedZone, opts, "RFC 2822", text);
6338  }
6339
6340  /**
6341   * Create a DateTime from an HTTP header date
6342   * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
6343   * @param {string} text - the HTTP header date
6344   * @param {Object} opts - options to affect the creation
6345   * @param {string|Zone} [opts.zone='local'] - convert the time to this zone. Since HTTP dates are always in UTC, this has no effect on the interpretation of string, merely the zone the resulting DateTime is expressed in.
6346   * @param {boolean} [opts.setZone=false] - override the zone with the fixed-offset zone specified in the string. For HTTP dates, this is always UTC, so this option is equivalent to setting the `zone` option to 'utc', but this option is included for consistency with similar methods.
6347   * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance
6348   * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance
6349   * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance
6350   * @param {string} opts.weekSettings - the week settings to set on the resulting DateTime instance
6351   * @example DateTime.fromHTTP('Sun, 06 Nov 1994 08:49:37 GMT')
6352   * @example DateTime.fromHTTP('Sunday, 06-Nov-94 08:49:37 GMT')
6353   * @example DateTime.fromHTTP('Sun Nov  6 08:49:37 1994')
6354   * @return {DateTime}
6355   */
6356  static fromHTTP(text, opts = {}) {
6357    const [vals, parsedZone] = parseHTTPDate(text);
6358    return parseDataToDateTime(vals, parsedZone, opts, "HTTP", opts);
6359  }
6360
6361  /**
6362   * Create a DateTime from an input string and format string.
6363   * Defaults to en-US if no locale has been specified, regardless of the system's locale. For a table of tokens and their interpretations, see [here](https://moment.github.io/luxon/#/parsing?id=table-of-tokens).
6364   * @param {string} text - the string to parse
6365   * @param {string} fmt - the format the string is expected to be in (see the link below for the formats)
6366   * @param {Object} opts - options to affect the creation
6367   * @param {string|Zone} [opts.zone='local'] - use this zone if no offset is specified in the input string itself. Will also convert the DateTime to this zone
6368   * @param {boolean} [opts.setZone=false] - override the zone with a zone specified in the string itself, if it specifies one
6369   * @param {string} [opts.locale='en-US'] - a locale string to use when parsing. Will also set the DateTime to this locale
6370   * @param {string} opts.numberingSystem - the numbering system to use when parsing. Will also set the resulting DateTime to this numbering system
6371   * @param {string} opts.weekSettings - the week settings to set on the resulting DateTime instance
6372   * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance
6373   * @return {DateTime}
6374   */
6375  static fromFormat(text, fmt, opts = {}) {
6376    if (isUndefined(text) || isUndefined(fmt)) {
6377      throw new InvalidArgumentError("fromFormat requires an input string and a format");
6378    }
6379
6380    const { locale = null, numberingSystem = null } = opts,
6381      localeToUse = Locale.fromOpts({
6382        locale,
6383        numberingSystem,
6384        defaultToEN: true,
6385      }),
6386      [vals, parsedZone, specificOffset, invalid] = parseFromTokens(localeToUse, text, fmt);
6387    if (invalid) {
6388      return DateTime.invalid(invalid);
6389    } else {
6390      return parseDataToDateTime(vals, parsedZone, opts, `format ${fmt}`, text, specificOffset);
6391    }
6392  }
6393
6394  /**
6395   * @deprecated use fromFormat instead
6396   */
6397  static fromString(text, fmt, opts = {}) {
6398    return DateTime.fromFormat(text, fmt, opts);
6399  }
6400
6401  /**
6402   * Create a DateTime from a SQL date, time, or datetime
6403   * Defaults to en-US if no locale has been specified, regardless of the system's locale
6404   * @param {string} text - the string to parse
6405   * @param {Object} opts - options to affect the creation
6406   * @param {string|Zone} [opts.zone='local'] - use this zone if no offset is specified in the input string itself. Will also convert the DateTime to this zone
6407   * @param {boolean} [opts.setZone=false] - override the zone with a zone specified in the string itself, if it specifies one
6408   * @param {string} [opts.locale='en-US'] - a locale string to use when parsing. Will also set the DateTime to this locale
6409   * @param {string} opts.numberingSystem - the numbering system to use when parsing. Will also set the resulting DateTime to this numbering system
6410   * @param {string} opts.weekSettings - the week settings to set on the resulting DateTime instance
6411   * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance
6412   * @example DateTime.fromSQL('2017-05-15')
6413   * @example DateTime.fromSQL('2017-05-15 09:12:34')
6414   * @example DateTime.fromSQL('2017-05-15 09:12:34.342')
6415   * @example DateTime.fromSQL('2017-05-15 09:12:34.342+06:00')
6416   * @example DateTime.fromSQL('2017-05-15 09:12:34.342 America/Los_Angeles')
6417   * @example DateTime.fromSQL('2017-05-15 09:12:34.342 America/Los_Angeles', { setZone: true })
6418   * @example DateTime.fromSQL('2017-05-15 09:12:34.342', { zone: 'America/Los_Angeles' })
6419   * @example DateTime.fromSQL('09:12:34.342')
6420   * @return {DateTime}
6421   */
6422  static fromSQL(text, opts = {}) {
6423    const [vals, parsedZone] = parseSQL(text);
6424    return parseDataToDateTime(vals, parsedZone, opts, "SQL", text);
6425  }
6426
6427  /**
6428   * Create an invalid DateTime.
6429   * @param {string} reason - simple string of why this DateTime is invalid. Should not contain parameters or anything else data-dependent.
6430   * @param {string} [explanation=null] - longer explanation, may include parameters and other useful debugging information
6431   * @return {DateTime}
6432   */
6433  static invalid(reason, explanation = null) {
6434    if (!reason) {
6435      throw new InvalidArgumentError("need to specify a reason the DateTime is invalid");
6436    }
6437
6438    const invalid = reason instanceof Invalid ? reason : new Invalid(reason, explanation);
6439
6440    if (Settings.throwOnInvalid) {
6441      throw new InvalidDateTimeError(invalid);
6442    } else {
6443      return new DateTime({ invalid });
6444    }
6445  }
6446
6447  /**
6448   * Check if an object is an instance of DateTime. Works across context boundaries
6449   * @param {object} o
6450   * @return {boolean}
6451   */
6452  static isDateTime(o) {
6453    return (o && o.isLuxonDateTime) || false;
6454  }
6455
6456  /**
6457   * Produce the format string for a set of options
6458   * @param formatOpts
6459   * @param localeOpts
6460   * @returns {string}
6461   */
6462  static parseFormatForOpts(formatOpts, localeOpts = {}) {
6463    const tokenList = formatOptsToTokens(formatOpts, Locale.fromObject(localeOpts));
6464    return !tokenList ? null : tokenList.map((t) => (t ? t.val : null)).join("");
6465  }
6466
6467  /**
6468   * Produce the the fully expanded format token for the locale
6469   * Does NOT quote characters, so quoted tokens will not round trip correctly
6470   * @param fmt
6471   * @param localeOpts
6472   * @returns {string}
6473   */
6474  static expandFormat(fmt, localeOpts = {}) {
6475    const expanded = expandMacroTokens(Formatter.parseFormat(fmt), Locale.fromObject(localeOpts));
6476    return expanded.map((t) => t.val).join("");
6477  }
6478
6479  static resetCache() {
6480    zoneOffsetTs = undefined;
6481    zoneOffsetGuessCache
6481 = {}
vendor: 41,868 bytes, lines 6481-7617
6481;
6482  }
6483
6484  // INFO
6485
6486  /**
6487   * Get the value of unit.
6488   * @param {string} unit - a unit such as 'minute' or 'day'
6489   * @example DateTime.local(2017, 7, 4).get('month'); //=> 7
6490   * @example DateTime.local(2017, 7, 4).get('day'); //=> 4
6491   * @return {number}
6492   */
6493  get(unit) {
6494    return this[unit];
6495  }
6496
6497  /**
6498   * Returns whether the DateTime is valid. Invalid DateTimes occur when:
6499   * * The DateTime was created from invalid calendar information, such as the 13th month or February 30
6500   * * The DateTime was created by an operation on another invalid date
6501   * @type {boolean}
6502   */
6503  get isValid() {
6504    return this.invalid === null;
6505  }
6506
6507  /**
6508   * Returns an error code if this DateTime is invalid, or null if the DateTime is valid
6509   * @type {string}
6510   */
6511  get invalidReason() {
6512    return this.invalid ? this.invalid.reason : null;
6513  }
6514
6515  /**
6516   * Returns an explanation of why this DateTime became invalid, or null if the DateTime is valid
6517   * @type {string}
6518   */
6519  get invalidExplanation() {
6520    return this.invalid ? this.invalid.explanation : null;
6521  }
6522
6523  /**
6524   * Get the locale of a DateTime, such 'en-GB'. The locale is used when formatting the DateTime
6525   *
6526   * @type {string}
6527   */
6528  get locale() {
6529    return this.isValid ? this.loc.locale : null;
6530  }
6531
6532  /**
6533   * Get the numbering system of a DateTime, such 'beng'. The numbering system is used when formatting the DateTime
6534   *
6535   * @type {string}
6536   */
6537  get numberingSystem() {
6538    return this.isValid ? this.loc.numberingSystem : null;
6539  }
6540
6541  /**
6542   * Get the output calendar of a DateTime, such 'islamic'. The output calendar is used when formatting the DateTime
6543   *
6544   * @type {string}
6545   */
6546  get outputCalendar() {
6547    return this.isValid ? this.loc.outputCalendar : null;
6548  }
6549
6550  /**
6551   * Get the time zone associated with this DateTime.
6552   * @type {Zone}
6553   */
6554  get zone() {
6555    return this._zone;
6556  }
6557
6558  /**
6559   * Get the name of the time zone.
6560   * @type {string}
6561   */
6562  get zoneName() {
6563    return this.isValid ? this.zone.name : null;
6564  }
6565
6566  /**
6567   * Get the year
6568   * @example DateTime.local(2017, 5, 25).year //=> 2017
6569   * @type {number}
6570   */
6571  get year() {
6572    return this.isValid ? this.c.year : NaN;
6573  }
6574
6575  /**
6576   * Get the quarter
6577   * @example DateTime.local(2017, 5, 25).quarter //=> 2
6578   * @type {number}
6579   */
6580  get quarter() {
6581    return this.isValid ? Math.ceil(this.c.month / 3) : NaN;
6582  }
6583
6584  /**
6585   * Get the month (1-12).
6586   * @example DateTime.local(2017, 5, 25).month //=> 5
6587   * @type {number}
6588   */
6589  get month() {
6590    return this.isValid ? this.c.month : NaN;
6591  }
6592
6593  /**
6594   * Get the day of the month (1-30ish).
6595   * @example DateTime.local(2017, 5, 25).day //=> 25
6596   * @type {number}
6597   */
6598  get day() {
6599    return this.isValid ? this.c.day : NaN;
6600  }
6601
6602  /**
6603   * Get the hour of the day (0-23).
6604   * @example DateTime.local(2017, 5, 25, 9).hour //=> 9
6605   * @type {number}
6606   */
6607  get hour() {
6608    return this.isValid ? this.c.hour : NaN;
6609  }
6610
6611  /**
6612   * Get the minute of the hour (0-59).
6613   * @example DateTime.local(2017, 5, 25, 9, 30).minute //=> 30
6614   * @type {number}
6615   */
6616  get minute() {
6617    return this.isValid ? this.c.minute : NaN;
6618  }
6619
6620  /**
6621   * Get the second of the minute (0-59).
6622   * @example DateTime.local(2017, 5, 25, 9, 30, 52).second //=> 52
6623   * @type {number}
6624   */
6625  get second() {
6626    return this.isValid ? this.c.second : NaN;
6627  }
6628
6629  /**
6630   * Get the millisecond of the second (0-999).
6631   * @example DateTime.local(2017, 5, 25, 9, 30, 52, 654).millisecond //=> 654
6632   * @type {number}
6633   */
6634  get millisecond() {
6635    return this.isValid ? this.c.millisecond : NaN;
6636  }
6637
6638  /**
6639   * Get the week year
6640   * @see https://en.wikipedia.org/wiki/ISO_week_date
6641   * @example DateTime.local(2014, 12, 31).weekYear //=> 2015
6642   * @type {number}
6643   */
6644  get weekYear() {
6645    return this.isValid ? possiblyCachedWeekData(this).weekYear : NaN;
6646  }
6647
6648  /**
6649   * Get the week number of the week year (1-52ish).
6650   * @see https://en.wikipedia.org/wiki/ISO_week_date
6651   * @example DateTime.local(2017, 5, 25).weekNumber //=> 21
6652   * @type {number}
6653   */
6654  get weekNumber() {
6655    return this.isValid ? possiblyCachedWeekData(this).weekNumber : NaN;
6656  }
6657
6658  /**
6659   * Get the day of the week.
6660   * 1 is Monday and 7 is Sunday
6661   * @see https://en.wikipedia.org/wiki/ISO_week_date
6662   * @example DateTime.local(2014, 11, 31).weekday //=> 4
6663   * @type {number}
6664   */
6665  get weekday() {
6666    return this.isValid ? possiblyCachedWeekData(this).weekday : NaN;
6667  }
6668
6669  /**
6670   * Returns true if this date is on a weekend according to the locale, false otherwise
6671   * @returns {boolean}
6672   */
6673  get isWeekend() {
6674    return this.isValid && this.loc.getWeekendDays().includes(this.weekday);
6675  }
6676
6677  /**
6678   * Get the day of the week according to the locale.
6679   * 1 is the first day of the week and 7 is the last day of the week.
6680   * If the locale assigns Sunday as the first day of the week, then a date which is a Sunday will return 1,
6681   * @returns {number}
6682   */
6683  get localWeekday() {
6684    return this.isValid ? possiblyCachedLocalWeekData(this).weekday : NaN;
6685  }
6686
6687  /**
6688   * Get the week number of the week year according to the locale. Different locales assign week numbers differently,
6689   * because the week can start on different days of the week (see localWeekday) and because a different number of days
6690   * is required for a week to count as the first week of a year.
6691   * @returns {number}
6692   */
6693  get localWeekNumber() {
6694    return this.isValid ? possiblyCachedLocalWeekData(this).weekNumber : NaN;
6695  }
6696
6697  /**
6698   * Get the week year according to the locale. Different locales assign week numbers (and therefor week years)
6699   * differently, see localWeekNumber.
6700   * @returns {number}
6701   */
6702  get localWeekYear() {
6703    return this.isValid ? possiblyCachedLocalWeekData(this).weekYear : NaN;
6704  }
6705
6706  /**
6707   * Get the ordinal (meaning the day of the year)
6708   * @example DateTime.local(2017, 5, 25).ordinal //=> 145
6709   * @type {number|DateTime}
6710   */
6711  get ordinal() {
6712    return this.isValid ? gregorianToOrdinal(this.c).ordinal : NaN;
6713  }
6714
6715  /**
6716   * Get the human readable short month name, such as 'Oct'.
6717   * Defaults to the system's locale if no locale has been specified
6718   * @example DateTime.local(2017, 10, 30).monthShort //=> Oct
6719   * @type {string}
6720   */
6721  get monthShort() {
6722    return this.isValid ? Info.months("short", { locObj: this.loc })[this.month - 1] : null;
6723  }
6724
6725  /**
6726   * Get the human readable long month name, such as 'October'.
6727   * Defaults to the system's locale if no locale has been specified
6728   * @example DateTime.local(2017, 10, 30).monthLong //=> October
6729   * @type {string}
6730   */
6731  get monthLong() {
6732    return this.isValid ? Info.months("long", { locObj: this.loc })[this.month - 1] : null;
6733  }
6734
6735  /**
6736   * Get the human readable short weekday, such as 'Mon'.
6737   * Defaults to the system's locale if no locale has been specified
6738   * @example DateTime.local(2017, 10, 30).weekdayShort //=> Mon
6739   * @type {string}
6740   */
6741  get weekdayShort() {
6742    return this.isValid ? Info.weekdays("short", { locObj: this.loc })[this.weekday - 1] : null;
6743  }
6744
6745  /**
6746   * Get the human readable long weekday, such as 'Monday'.
6747   * Defaults to the system's locale if no locale has been specified
6748   * @example DateTime.local(2017, 10, 30).weekdayLong //=> Monday
6749   * @type {string}
6750   */
6751  get weekdayLong() {
6752    return this.isValid ? Info.weekdays("long", { locObj: this.loc })[this.weekday - 1] : null;
6753  }
6754
6755  /**
6756   * Get the UTC offset of this DateTime in minutes
6757   * @example DateTime.now().offset //=> -240
6758   * @example DateTime.utc().offset //=> 0
6759   * @type {number}
6760   */
6761  get offset() {
6762    return this.isValid ? +this.o : NaN;
6763  }
6764
6765  /**
6766   * Get the short human name for the zone's current offset, for example "EST" or "EDT".
6767   * Defaults to the system's locale if no locale has been specified
6768   * @type {string}
6769   */
6770  get offsetNameShort() {
6771    if (this.isValid) {
6772      return this.zone.offsetName(this.ts, {
6773        format: "short",
6774        locale: this.locale,
6775      });
6776    } else {
6777      return null;
6778    }
6779  }
6780
6781  /**
6782   * Get the long human name for the zone's current offset, for example "Eastern Standard Time" or "Eastern Daylight Time".
6783   * Defaults to the system's locale if no locale has been specified
6784   * @type {string}
6785   */
6786  get offsetNameLong() {
6787    if (this.isValid) {
6788      return this.zone.offsetName(this.ts, {
6789        format: "long",
6790        locale: this.locale,
6791      });
6792    } else {
6793      return null;
6794    }
6795  }
6796
6797  /**
6798   * Get whether this zone's offset ever changes, as in a DST.
6799   * @type {boolean}
6800   */
6801  get isOffsetFixed() {
6802    return this.isValid ? this.zone.isUniversal : null;
6803  }
6804
6805  /**
6806   * Get whether the DateTime is in a DST.
6807   * @type {boolean}
6808   */
6809  get isInDST() {
6810    if (this.isOffsetFixed) {
6811      return false;
6812    } else {
6813      return (
6814        this.offset > this.set({ month: 1, day: 1 }).offset ||
6815        this.offset > this.set({ month: 5 }).offset
6816      );
6817    }
6818  }
6819
6820  /**
6821   * Get those DateTimes which have the same local time as this DateTime, but a different offset from UTC
6822   * in this DateTime's zone. During DST changes local time can be ambiguous, for example
6823   * `2023-10-29T02:30:00` in `Europe/Berlin` can have offset `+01:00` or `+02:00`.
6824   * This method will return both possible DateTimes if this DateTime's local time is ambiguous.
6825   * @returns {DateTime[]}
6826   */
6827  getPossibleOffsets() {
6828    if (!this.isValid || this.isOffsetFixed) {
6829      return [this];
6830    }
6831    const dayMs = 86400000;
6832    const minuteMs = 60000;
6833    const localTS = objToLocalTS(this.c);
6834    const oEarlier = this.zone.offset(localTS - dayMs);
6835    const oLater = this.zone.offset(localTS + dayMs);
6836
6837    const o1 = this.zone.offset(localTS - oEarlier * minuteMs);
6838    const o2 = this.zone.offset(localTS - oLater * minuteMs);
6839    if (o1 === o2) {
6840      return [this];
6841    }
6842    const ts1 = localTS - o1 * minuteMs;
6843    const ts2 = localTS - o2 * minuteMs;
6844    const c1 = tsToObj(ts1, o1);
6845    const c2 = tsToObj(ts2, o2);
6846    if (
6847      c1.hour === c2.hour &&
6848      c1.minute === c2.minute &&
6849      c1.second === c2.second &&
6850      c1.millisecond === c2.millisecond
6851    ) {
6852      return [clone(this, { ts: ts1 }), clone(this, { ts: ts2 })];
6853    }
6854    return [this];
6855  }
6856
6857  /**
6858   * Returns true if this DateTime is in a leap year, false otherwise
6859   * @example DateTime.local(2016).isInLeapYear //=> true
6860   * @example DateTime.local(2013).isInLeapYear //=> false
6861   * @type {boolean}
6862   */
6863  get isInLeapYear() {
6864    return isLeapYear(this.year);
6865  }
6866
6867  /**
6868   * Returns the number of days in this DateTime's month
6869   * @example DateTime.local(2016, 2).daysInMonth //=> 29
6870   * @example DateTime.local(2016, 3).daysInMonth //=> 31
6871   * @type {number}
6872   */
6873  get daysInMonth() {
6874    return daysInMonth(this.year, this.month);
6875  }
6876
6877  /**
6878   * Returns the number of days in this DateTime's year
6879   * @example DateTime.local(2016).daysInYear //=> 366
6880   * @example DateTime.local(2013).daysInYear //=> 365
6881   * @type {number}
6882   */
6883  get daysInYear() {
6884    return this.isValid ? daysInYear(this.year) : NaN;
6885  }
6886
6887  /**
6888   * Returns the number of weeks in this DateTime's year
6889   * @see https://en.wikipedia.org/wiki/ISO_week_date
6890   * @example DateTime.local(2004).weeksInWeekYear //=> 53
6891   * @example DateTime.local(2013).weeksInWeekYear //=> 52
6892   * @type {number}
6893   */
6894  get weeksInWeekYear() {
6895    return this.isValid ? weeksInWeekYear(this.weekYear) : NaN;
6896  }
6897
6898  /**
6899   * Returns the number of weeks in this DateTime's local week year
6900   * @example DateTime.local(2020, 6, {locale: 'en-US'}).weeksInLocalWeekYear //=> 52
6901   * @example DateTime.local(2020, 6, {locale: 'de-DE'}).weeksInLocalWeekYear //=> 53
6902   * @type {number}
6903   */
6904  get weeksInLocalWeekYear() {
6905    return this.isValid
6906      ? weeksInWeekYear(
6907          this.localWeekYear,
6908          this.loc.getMinDaysInFirstWeek(),
6909          this.loc.getStartOfWeek()
6910        )
6911      : NaN;
6912  }
6913
6914  /**
6915   * Returns the resolved Intl options for this DateTime.
6916   * This is useful in understanding the behavior of formatting methods
6917   * @param {Object} opts - the same options as toLocaleString
6918   * @return {Object}
6919   */
6920  resolvedLocaleOptions(opts = {}) {
6921    const { locale, numberingSystem, calendar } = Formatter.create(
6922      this.loc.clone(opts),
6923      opts
6924    ).resolvedOptions(this);
6925    return { locale, numberingSystem, outputCalendar: calendar };
6926  }
6927
6928  // TRANSFORM
6929
6930  /**
6931   * "Set" the DateTime's zone to UTC. Returns a newly-constructed DateTime.
6932   *
6933   * Equivalent to {@link DateTime#setZone}('utc')
6934   * @param {number} [offset=0] - optionally, an offset from UTC in minutes
6935   * @param {Object} [opts={}] - options to pass to `setZone()`
6936   * @return {DateTime}
6937   */
6938  toUTC(offset = 0, opts = {}) {
6939    return this.setZone(FixedOffsetZone.instance(offset), opts);
6940  }
6941
6942  /**
6943   * "Set" the DateTime's zone to the host's local zone. Returns a newly-constructed DateTime.
6944   *
6945   * Equivalent to `setZone('local')`
6946   * @return {DateTime}
6947   */
6948  toLocal() {
6949    return this.setZone(Settings.defaultZone);
6950  }
6951
6952  /**
6953   * "Set" the DateTime's zone to specified zone. Returns a newly-constructed DateTime.
6954   *
6955   * By default, the setter keeps the underlying time the same (as in, the same timestamp), but the new instance will report different local times and consider DSTs when making computations, as with {@link DateTime#plus}. You may wish to use {@link DateTime#toLocal} and {@link DateTime#toUTC} which provide simple convenience wrappers for commonly used zones.
6956   * @param {string|Zone} [zone='local'] - a zone identifier. As a string, that can be any IANA zone supported by the host environment, or a fixed-offset name of the form 'UTC+3', or the strings 'local' or 'utc'. You may also supply an instance of a {@link DateTime#Zone} class.
6957   * @param {Object} opts - options
6958   * @param {boolean} [opts.keepLocalTime=false] - If true, adjust the underlying time so that the local time stays the same, but in the target zone. You should rarely need this.
6959   * @return {DateTime}
6960   */
6961  setZone(zone, { keepLocalTime = false, keepCalendarTime = false } = {}) {
6962    zone = normalizeZone(zone, Settings.defaultZone);
6963    if (zone.equals(this.zone)) {
6964      return this;
6965    } else if (!zone.isValid) {
6966      return DateTime.invalid(unsupportedZone(zone));
6967    } else {
6968      let newTS = this.ts;
6969      if (keepLocalTime || keepCalendarTime) {
6970        const offsetGuess = zone.offset(this.ts);
6971        const asObj = this.toObject();
6972        [newTS] = objToTS(asObj, offsetGuess, zone);
6973      }
6974      return clone(this, { ts: newTS, zone });
6975    }
6976  }
6977
6978  /**
6979   * "Set" the locale, numberingSystem, or outputCalendar. Returns a newly-constructed DateTime.
6980   * @param {Object} properties - the properties to set
6981   * @example DateTime.local(2017, 5, 25).reconfigure({ locale: 'en-GB' })
6982   * @return {DateTime}
6983   */
6984  reconfigure({ locale, numberingSystem, outputCalendar } = {}) {
6985    const loc = this.loc.clone({ locale, numberingSystem, outputCalendar });
6986    return clone(this, { loc });
6987  }
6988
6989  /**
6990   * "Set" the locale. Returns a newly-constructed DateTime.
6991   * Just a convenient alias for reconfigure({ locale })
6992   * @example DateTime.local(2017, 5, 25).setLocale('en-GB')
6993   * @return {DateTime}
6994   */
6995  setLocale(locale) {
6996    return this.reconfigure({ locale });
6997  }
6998
6999  /**
7000   * "Set" the values of specified units. Returns a newly-constructed DateTime.
7001   * You can only set units with this method; for "setting" metadata, see {@link DateTime#reconfigure} and {@link DateTime#setZone}.
7002   *
7003   * This method also supports setting locale-based week units, i.e. `localWeekday`, `localWeekNumber` and `localWeekYear`.
7004   * They cannot be mixed with ISO-week units like `weekday`.
7005   * @param {Object} values - a mapping of units to numbers
7006   * @example dt.set({ year: 2017 })
7007   * @example dt.set({ hour: 8, minute: 30 })
7008   * @example dt.set({ weekday: 5 })
7009   * @example dt.set({ year: 2005, ordinal: 234 })
7010   * @return {DateTime}
7011   */
7012  set(values) {
7013    if (!this.isValid) return this;
7014
7015    const normalized = normalizeObject(values, normalizeUnitWithLocalWeeks);
7016    const { minDaysInFirstWeek, startOfWeek } = usesLocalWeekValues(normalized, this.loc);
7017
7018    const settingWeekStuff =
7019        !isUndefined(normalized.weekYear) ||
7020        !isUndefined(normalized.weekNumber) ||
7021        !isUndefined(normalized.weekday),
7022      containsOrdinal = !isUndefined(normalized.ordinal),
7023      containsGregorYear = !isUndefined(normalized.year),
7024      containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day),
7025      containsGregor = containsGregorYear || containsGregorMD,
7026      definiteWeekDef = normalized.weekYear || normalized.weekNumber;
7027
7028    if ((containsGregor || containsOrdinal) && definiteWeekDef) {
7029      throw new ConflictingSpecificationError(
7030        "Can't mix weekYear/weekNumber units with year/month/day or ordinals"
7031      );
7032    }
7033
7034    if (containsGregorMD && containsOrdinal) {
7035      throw new ConflictingSpecificationError("Can't mix ordinal dates with month/day");
7036    }
7037
7038    let mixed;
7039    if (settingWeekStuff) {
7040      mixed = weekToGregorian(
7041        { ...gregorianToWeek(this.c, minDaysInFirstWeek, startOfWeek), ...normalized },
7042        minDaysInFirstWeek,
7043        startOfWeek
7044      );
7045    } else if (!isUndefined(normalized.ordinal)) {
7046      mixed = ordinalToGregorian({ ...gregorianToOrdinal(this.c), ...normalized });
7047    } else {
7048      mixed = { ...this.toObject(), ...normalized };
7049
7050      // if we didn't set the day but we ended up on an overflow date,
7051      // use the last day of the right month
7052      if (isUndefined(normalized.day)) {
7053        mixed.day = Math.min(daysInMonth(mixed.year, mixed.month), mixed.day);
7054      }
7055    }
7056
7057    const [ts, o] = objToTS(mixed, this.o, this.zone);
7058    return clone(this, { ts, o });
7059  }
7060
7061  /**
7062   * Add a period of time to this DateTime and return the resulting DateTime
7063   *
7064   * Adding hours, minutes, seconds, or milliseconds increases the timestamp by the right number of milliseconds. Adding days, months, or years shifts the calendar, accounting for DSTs and leap years along the way. Thus, `dt.plus({ hours: 24 })` may result in a different time than `dt.plus({ days: 1 })` if there's a DST shift in between.
7065   * @param {Duration|Object|number} duration - The amount to add. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
7066   * @example DateTime.now().plus(123) //~> in 123 milliseconds
7067   * @example DateTime.now().plus({ minutes: 15 }) //~> in 15 minutes
7068   * @example DateTime.now().plus({ days: 1 }) //~> this time tomorrow
7069   * @example DateTime.now().plus({ days: -1 }) //~> this time yesterday
7070   * @example DateTime.now().plus({ hours: 3, minutes: 13 }) //~> in 3 hr, 13 min
7071   * @example DateTime.now().plus(Duration.fromObject({ hours: 3, minutes: 13 })) //~> in 3 hr, 13 min
7072   * @return {DateTime}
7073   */
7074  plus(duration) {
7075    if (!this.isValid) return this;
7076    const dur = Duration.fromDurationLike(duration);
7077    return clone(this, adjustTime(this, dur));
7078  }
7079
7080  /**
7081   * Subtract a period of time to this DateTime and return the resulting DateTime
7082   * See {@link DateTime#plus}
7083   * @param {Duration|Object|number} duration - The amount to subtract. Either a Luxon Duration, a number of milliseconds, the object argument to Duration.fromObject()
7084   @return {DateTime}
7085   */
7086  minus(duration) {
7087    if (!this.isValid) return this;
7088    const dur = Duration.fromDurationLike(duration).negate();
7089    return clone(this, adjustTime(this, dur));
7090  }
7091
7092  /**
7093   * "Set" this DateTime to the beginning of a unit of time.
7094   * @param {string} unit - The unit to go to the beginning of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'.
7095   * @param {Object} opts - options
7096   * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week
7097   * @example DateTime.local(2014, 3, 3).startOf('month').toISODate(); //=> '2014-03-01'
7098   * @example DateTime.local(2014, 3, 3).startOf('year').toISODate(); //=> '2014-01-01'
7099   * @example DateTime.local(2014, 3, 3).startOf('week').toISODate(); //=> '2014-03-03', weeks always start on Mondays
7100   * @example DateTime.local(2014, 3, 3, 5, 30).startOf('day').toISOTime(); //=> '00:00.000-05:00'
7101   * @example DateTime.local(2014, 3, 3, 5, 30).startOf('hour').toISOTime(); //=> '05:00:00.000-05:00'
7102   * @return {DateTime}
7103   */
7104  startOf(unit, { useLocaleWeeks = false } = {}) {
7105    if (!this.isValid) return this;
7106
7107    const o = {},
7108      normalizedUnit = Duration.normalizeUnit(unit);
7109    switch (normalizedUnit) {
7110      case "years":
7111        o.month = 1;
7112      // falls through
7113      case "quarters":
7114      case "months":
7115        o.day = 1;
7116      // falls through
7117      case "weeks":
7118      case "days":
7119        o.hour = 0;
7120      // falls through
7121      case "hours":
7122        o.minute = 0;
7123      // falls through
7124      case "minutes":
7125        o.second = 0;
7126      // falls through
7127      case "seconds":
7128        o.millisecond = 0;
7129        break;
7130      // no default, invalid units throw in normalizeUnit()
7131    }
7132
7133    if (normalizedUnit === "weeks") {
7134      if (useLocaleWeeks) {
7135        const startOfWeek = this.loc.getStartOfWeek();
7136        const { weekday } = this;
7137        if (weekday < startOfWeek) {
7138          o.weekNumber = this.weekNumber - 1;
7139        }
7140        o.weekday = startOfWeek;
7141      } else {
7142        o.weekday = 1;
7143      }
7144    }
7145
7146    if (normalizedUnit === "quarters") {
7147      const q = Math.ceil(this.month / 3);
7148      o.month = (q - 1) * 3 + 1;
7149    }
7150
7151    return this.set(o);
7152  }
7153
7154  /**
7155   * "Set" this DateTime to the end (meaning the last millisecond) of a unit of time
7156   * @param {string} unit - The unit to go to the end of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'.
7157   * @param {Object} opts - options
7158   * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week
7159   * @example DateTime.local(2014, 3, 3).endOf('month').toISO(); //=> '2014-03-31T23:59:59.999-05:00'
7160   * @example DateTime.local(2014, 3, 3).endOf('year').toISO(); //=> '2014-12-31T23:59:59.999-05:00'
7161   * @example DateTime.local(2014, 3, 3).endOf('week').toISO(); // => '2014-03-09T23:59:59.999-05:00', weeks start on Mondays
7162   * @example DateTime.local(2014, 3, 3, 5, 30).endOf('day').toISO(); //=> '2014-03-03T23:59:59.999-05:00'
7163   * @example DateTime.local(2014, 3, 3, 5, 30).endOf('hour').toISO(); //=> '2014-03-03T05:59:59.999-05:00'
7164   * @return {DateTime}
7165   */
7166  endOf(unit, opts) {
7167    return this.isValid
7168      ? this.plus({ [unit]: 1 })
7169          .startOf(unit, opts)
7170          .minus(1)
7171      : this;
7172  }
7173
7174  // OUTPUT
7175
7176  /**
7177   * Returns a string representation of this DateTime formatted according to the specified format string.
7178   * **You may not want this.** See {@link DateTime#toLocaleString} for a more flexible formatting tool. For a table of tokens and their interpretations, see [here](https://moment.github.io/luxon/#/formatting?id=table-of-tokens).
7179   * Defaults to en-US if no locale has been specified, regardless of the system's locale.
7180   * @param {string} fmt - the format string
7181   * @param {Object} opts - opts to override the configuration options on this DateTime
7182   * @example DateTime.now().toFormat('yyyy LLL dd') //=> '2017 Apr 22'
7183   * @example DateTime.now().setLocale('fr').toFormat('yyyy LLL dd') //=> '2017 avr. 22'
7184   * @example DateTime.now().toFormat('yyyy LLL dd', { locale: "fr" }) //=> '2017 avr. 22'
7185   * @example DateTime.now().toFormat("HH 'hours and' mm 'minutes'") //=> '20 hours and 55 minutes'
7186   * @return {string}
7187   */
7188  toFormat(fmt, opts = {}) {
7189    return this.isValid
7190      ? Formatter.create(this.loc.redefaultToEN(opts)).formatDateTimeFromString(this, fmt)
7191      : INVALID;
7192  }
7193
7194  /**
7195   * Returns a localized string representing this date. Accepts the same options as the Intl.DateTimeFormat constructor and any presets defined by Luxon, such as `DateTime.DATE_FULL` or `DateTime.TIME_SIMPLE`.
7196   * The exact behavior of this method is browser-specific, but in general it will return an appropriate representation
7197   * of the DateTime in the assigned locale.
7198   * Defaults to the system's locale if no locale has been specified
7199   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
7200   * @param formatOpts {Object} - Intl.DateTimeFormat constructor options and configuration options
7201   * @param {Object} opts - opts to override the configuration options on this DateTime
7202   * @example DateTime.now().toLocaleString(); //=> 4/20/2017
7203   * @example DateTime.now().setLocale('en-gb').toLocaleString(); //=> '20/04/2017'
7204   * @example DateTime.now().toLocaleString(DateTime.DATE_FULL); //=> 'April 20, 2017'
7205   * @example DateTime.now().toLocaleString(DateTime.DATE_FULL, { locale: 'fr' }); //=> '28 août 2022'
7206   * @example DateTime.now().toLocaleString(DateTime.TIME_SIMPLE); //=> '11:32 AM'
7207   * @example DateTime.now().toLocaleString(DateTime.DATETIME_SHORT); //=> '4/20/2017, 11:32 AM'
7208   * @example DateTime.now().toLocaleString({ weekday: 'long', month: 'long', day: '2-digit' }); //=> 'Thursday, April 20'
7209   * @example DateTime.now().toLocaleString({ weekday: 'short', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }); //=> 'Thu, Apr 20, 11:27 AM'
7210   * @example DateTime.now().toLocaleString({ hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }); //=> '11:32'
7211   * @return {string}
7212   */
7213  toLocaleString(formatOpts = DATE_SHORT, opts = {}) {
7214    return this.isValid
7215      ? Formatter.create(this.loc.clone(opts), formatOpts).formatDateTime(this)
7216      : INVALID;
7217  }
7218
7219  /**
7220   * Returns an array of format "parts", meaning individual tokens along with metadata. This is allows callers to post-process individual sections of the formatted output.
7221   * Defaults to the system's locale if no locale has been specified
7222   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/formatToParts
7223   * @param opts {Object} - Intl.DateTimeFormat constructor options, same as `toLocaleString`.
7224   * @example DateTime.now().toLocaleParts(); //=> [
7225   *                                   //=>   { type: 'day', value: '25' },
7226   *                                   //=>   { type: 'literal', value: '/' },
7227   *                                   //=>   { type: 'month', value: '05' },
7228   *                                   //=>   { type: 'literal', value: '/' },
7229   *                                   //=>   { type: 'year', value: '1982' }
7230   *                                   //=> ]
7231   */
7232  toLocaleParts(opts = {}) {
7233    return this.isValid
7234      ? Formatter.create(this.loc.clone(opts), opts).formatDateTimeParts(this)
7235      : [];
7236  }
7237
7238  /**
7239   * Returns an ISO 8601-compliant string representation of this DateTime
7240   * @param {Object} opts - options
7241   * @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0
7242   * @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0
7243   * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00'
7244   * @param {boolean} [opts.extendedZone=false] - add the time zone format extension
7245   * @param {string} [opts.format='extended'] - choose between the basic and extended format
7246   * @example DateTime.utc(1983, 5, 25).toISO() //=> '1982-05-25T00:00:00.000Z'
7247   * @example DateTime.now().toISO() //=> '2017-04-22T20:47:05.335-04:00'
7248   * @example DateTime.now().toISO({ includeOffset: false }) //=> '2017-04-22T20:47:05.335'
7249   * @example DateTime.now().toISO({ format: 'basic' }) //=> '20170422T204705.335-0400'
7250   * @return {string}
7251   */
7252  toISO({
7253    format = "extended",
7254    suppressSeconds = false,
7255    suppressMilliseconds = false,
7256    includeOffset = true,
7257    extendedZone = false,
7258  } = {}) {
7259    if (!this.isValid) {
7260      return null;
7261    }
7262
7263    const ext = format === "extended";
7264
7265    let c = toISODate(this, ext);
7266    c += "T";
7267    c += toISOTime(this, ext, suppressSeconds, suppressMilliseconds, includeOffset, extendedZone);
7268    return c;
7269  }
7270
7271  /**
7272   * Returns an ISO 8601-compliant string representation of this DateTime's date component
7273   * @param {Object} opts - options
7274   * @param {string} [opts.format='extended'] - choose between the basic and extended format
7275   * @example DateTime.utc(1982, 5, 25).toISODate() //=> '1982-05-25'
7276   * @example DateTime.utc(1982, 5, 25).toISODate({ format: 'basic' }) //=> '19820525'
7277   * @return {string}
7278   */
7279  toISODate({ format = "extended" } = {}) {
7280    if (!this.isValid) {
7281      return null;
7282    }
7283
7284    return toISODate(this, format === "extended");
7285  }
7286
7287  /**
7288   * Returns an ISO 8601-compliant string representation of this DateTime's week date
7289   * @example DateTime.utc(1982, 5, 25).toISOWeekDate() //=> '1982-W21-2'
7290   * @return {string}
7291   */
7292  toISOWeekDate() {
7293    return toTechFormat(this, "kkkk-'W'WW-c");
7294  }
7295
7296  /**
7297   * Returns an ISO 8601-compliant string representation of this DateTime's time component
7298   * @param {Object} opts - options
7299   * @param {boolean} [opts.suppressMilliseconds=false] - exclude milliseconds from the format if they're 0
7300   * @param {boolean} [opts.suppressSeconds=false] - exclude seconds from the format if they're 0
7301   * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00'
7302   * @param {boolean} [opts.extendedZone=true] - add the time zone format extension
7303   * @param {boolean} [opts.includePrefix=false] - include the `T` prefix
7304   * @param {string} [opts.format='extended'] - choose between the basic and extended format
7305   * @example DateTime.utc().set({ hour: 7, minute: 34 }).toISOTime() //=> '07:34:19.361Z'
7306   * @example DateTime.utc().set({ hour: 7, minute: 34, seconds: 0, milliseconds: 0 }).toISOTime({ suppressSeconds: true }) //=> '07:34Z'
7307   * @example DateTime.utc().set({ hour: 7, minute: 34 }).toISOTime({ format: 'basic' }) //=> '073419.361Z'
7308   * @example DateTime.utc().set({ hour: 7, minute: 34 }).toISOTime({ includePrefix: true }) //=> 'T07:34:19.361Z'
7309   * @return {string}
7310   */
7311  toISOTime({
7312    suppressMilliseconds = false,
7313    suppressSeconds = false,
7314    includeOffset = true,
7315    includePrefix = false,
7316    extendedZone = false,
7317    format = "extended",
7318  } = {}) {
7319    if (!this.isValid) {
7320      return null;
7321    }
7322
7323    let c = includePrefix ? "T" : "";
7324    return (
7325      c +
7326      toISOTime(
7327        this,
7328        format === "extended",
7329        suppressSeconds,
7330        suppressMilliseconds,
7331        includeOffset,
7332        extendedZone
7333      )
7334    );
7335  }
7336
7337  /**
7338   * Returns an RFC 2822-compatible string representation of this DateTime
7339   * @example DateTime.utc(2014, 7, 13).toRFC2822() //=> 'Sun, 13 Jul 2014 00:00:00 +0000'
7340   * @example DateTime.local(2014, 7, 13).toRFC2822() //=> 'Sun, 13 Jul 2014 00:00:00 -0400'
7341   * @return {string}
7342   */
7343  toRFC2822() {
7344    return toTechFormat(this, "EEE, dd LLL yyyy HH:mm:ss ZZZ", false);
7345  }
7346
7347  /**
7348   * Returns a string representation of this DateTime appropriate for use in HTTP headers. The output is always expressed in GMT.
7349   * Specifically, the string conforms to RFC 1123.
7350   * @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
7351   * @example DateTime.utc(2014, 7, 13).toHTTP() //=> 'Sun, 13 Jul 2014 00:00:00 GMT'
7352   * @example DateTime.utc(2014, 7, 13, 19).toHTTP() //=> 'Sun, 13 Jul 2014 19:00:00 GMT'
7353   * @return {string}
7354   */
7355  toHTTP() {
7356    return toTechFormat(this.toUTC(), "EEE, dd LLL yyyy HH:mm:ss 'GMT'");
7357  }
7358
7359  /**
7360   * Returns a string representation of this DateTime appropriate for use in SQL Date
7361   * @example DateTime.utc(2014, 7, 13).toSQLDate() //=> '2014-07-13'
7362   * @return {string}
7363   */
7364  toSQLDate() {
7365    if (!this.isValid) {
7366      return null;
7367    }
7368    return toISODate(this, true);
7369  }
7370
7371  /**
7372   * Returns a string representation of this DateTime appropriate for use in SQL Time
7373   * @param {Object} opts - options
7374   * @param {boolean} [opts.includeZone=false] - include the zone, such as 'America/New_York'. Overrides includeOffset.
7375   * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00'
7376   * @param {boolean} [opts.includeOffsetSpace=true] - include the space between the time and the offset, such as '05:15:16.345 -04:00'
7377   * @example DateTime.utc().toSQL() //=> '05:15:16.345'
7378   * @example DateTime.now().toSQL() //=> '05:15:16.345 -04:00'
7379   * @example DateTime.now().toSQL({ includeOffset: false }) //=> '05:15:16.345'
7380   * @example DateTime.now().toSQL({ includeZone: false }) //=> '05:15:16.345 America/New_York'
7381   * @return {string}
7382   */
7383  toSQLTime({ includeOffset = true, includeZone = false, includeOffsetSpace = true } = {}) {
7384    let fmt = "HH:mm:ss.SSS";
7385
7386    if (includeZone || includeOffset) {
7387      if (includeOffsetSpace) {
7388        fmt += " ";
7389      }
7390      if (includeZone) {
7391        fmt += "z";
7392      } else if (includeOffset) {
7393        fmt += "ZZ";
7394      }
7395    }
7396
7397    return toTechFormat(this, fmt, true);
7398  }
7399
7400  /**
7401   * Returns a string representation of this DateTime appropriate for use in SQL DateTime
7402   * @param {Object} opts - options
7403   * @param {boolean} [opts.includeZone=false] - include the zone, such as 'America/New_York'. Overrides includeOffset.
7404   * @param {boolean} [opts.includeOffset=true] - include the offset, such as 'Z' or '-04:00'
7405   * @param {boolean} [opts.includeOffsetSpace=true] - include the space between the time and the offset, such as '05:15:16.345 -04:00'
7406   * @example DateTime.utc(2014, 7, 13).toSQL() //=> '2014-07-13 00:00:00.000 Z'
7407   * @example DateTime.local(2014, 7, 13).toSQL() //=> '2014-07-13 00:00:00.000 -04:00'
7408   * @example DateTime.local(2014, 7, 13).toSQL({ includeOffset: false }) //=> '2014-07-13 00:00:00.000'
7409   * @example DateTime.local(2014, 7, 13).toSQL({ includeZone: true }) //=> '2014-07-13 00:00:00.000 America/New_York'
7410   * @return {string}
7411   */
7412  toSQL(opts = {}) {
7413    if (!this.isValid) {
7414      return null;
7415    }
7416
7417    return `${this.toSQLDate()} ${this.toSQLTime(opts)}`;
7418  }
7419
7420  /**
7421   * Returns a string representation of this DateTime appropriate for debugging
7422   * @return {string}
7423   */
7424  toString() {
7425    return this.isValid ? this.toISO() : INVALID;
7426  }
7427
7428  /**
7429   * Returns a string representation of this DateTime appropriate for the REPL.
7430   * @return {string}
7431   */
7432  [Symbol.for("nodejs.util.inspect.custom")]() {
7433    if (this.isValid) {
7434      return `DateTime { ts: ${this.toISO()}, zone: ${this.zone.name}, locale: ${this.locale} }`;
7435    } else {
7436      return `DateTime { Invalid, reason: ${this.invalidReason} }`;
7437    }
7438  }
7439
7440  /**
7441   * Returns the epoch milliseconds of this DateTime. Alias of {@link DateTime#toMillis}
7442   * @return {number}
7443   */
7444  valueOf() {
7445    return this.toMillis();
7446  }
7447
7448  /**
7449   * Returns the epoch milliseconds of this DateTime.
7450   * @return {number}
7451   */
7452  toMillis() {
7453    return this.isValid ? this.ts : NaN;
7454  }
7455
7456  /**
7457   * Returns the epoch seconds of this DateTime.
7458   * @return {number}
7459   */
7460  toSeconds() {
7461    return this.isValid ? this.ts / 1000 : NaN;
7462  }
7463
7464  /**
7465   * Returns the epoch seconds (as a whole number) of this DateTime.
7466   * @return {number}
7467   */
7468  toUnixInteger() {
7469    return this.isValid ? Math.floor(this.ts / 1000) : NaN;
7470  }
7471
7472  /**
7473   * Returns an ISO 8601 representation of this DateTime appropriate for use in JSON.
7474   * @return {string}
7475   */
7476  toJSON() {
7477    return this.toISO();
7478  }
7479
7480  /**
7481   * Returns a BSON serializable equivalent to this DateTime.
7482   * @return {Date}
7483   */
7484  toBSON() {
7485    return this.toJSDate();
7486  }
7487
7488  /**
7489   * Returns a JavaScript object with this DateTime's year, month, day, and so on.
7490   * @param opts - options for generating the object
7491   * @param {boolean} [opts.includeConfig=false] - include configuration attributes in the output
7492   * @example DateTime.now().toObject() //=> { year: 2017, month: 4, day: 22, hour: 20, minute: 49, second: 42, millisecond: 268 }
7493   * @return {Object}
7494   */
7495  toObject(opts = {}) {
7496    if (!this.isValid) return {};
7497
7498    const base = { ...this.c };
7499
7500    if (opts.includeConfig) {
7501      base.outputCalendar = this.outputCalendar;
7502      base.numberingSystem = this.loc.numberingSystem;
7503      base.locale = this.loc.locale;
7504    }
7505    return base;
7506  }
7507
7508  /**
7509   * Returns a JavaScript Date equivalent to this DateTime.
7510   * @return {Date}
7511   */
7512  toJSDate() {
7513    return new Date(this.isValid ? this.ts : NaN);
7514  }
7515
7516  // COMPARE
7517
7518  /**
7519   * Return the difference between two DateTimes as a Duration.
7520   * @param {DateTime} otherDateTime - the DateTime to compare this one to
7521   * @param {string|string[]} [unit=['milliseconds']] - the unit or array of units (such as 'hours' or 'days') to include in the duration.
7522   * @param {Object} opts - options that affect the creation of the Duration
7523   * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use
7524   * @example
7525   * var i1 = DateTime.fromISO('1982-05-25T09:45'),
7526   *     i2 = DateTime.fromISO('1983-10-14T10:30');
7527   * i2.diff(i1).toObject() //=> { milliseconds: 43807500000 }
7528   * i2.diff(i1, 'hours').toObject() //=> { hours: 12168.75 }
7529   * i2.diff(i1, ['months', 'days']).toObject() //=> { months: 16, days: 19.03125 }
7530   * i2.diff(i1, ['months', 'days', 'hours']).toObject() //=> { months: 16, days: 19, hours: 0.75 }
7531   * @return {Duration}
7532   */
7533  diff(otherDateTime, unit = "milliseconds", opts = {}) {
7534    if (!this.isValid || !otherDateTime.isValid) {
7535      return Duration.invalid("created by diffing an invalid DateTime");
7536    }
7537
7538    const durOpts = { locale: this.locale, numberingSystem: this.numberingSystem, ...opts };
7539
7540    const units = maybeArray(unit).map(Duration.normalizeUnit),
7541      otherIsLater = otherDateTime.valueOf() > this.valueOf(),
7542      earlier = otherIsLater ? this : otherDateTime,
7543      later = otherIsLater ? otherDateTime : this,
7544      diffed = diff(earlier, later, units, durOpts);
7545
7546    return otherIsLater ? diffed.negate() : diffed;
7547  }
7548
7549  /**
7550   * Return the difference between this DateTime and right now.
7551   * See {@link DateTime#diff}
7552   * @param {string|string[]} [unit=['milliseconds']] - the unit or units units (such as 'hours' or 'days') to include in the duration
7553   * @param {Object} opts - options that affect the creation of the Duration
7554   * @param {string} [opts.conversionAccuracy='casual'] - the conversion system to use
7555   * @return {Duration}
7556   */
7557  diffNow(unit = "milliseconds", opts = {}) {
7558    return this.diff(DateTime.now(), unit, opts);
7559  }
7560
7561  /**
7562   * Return an Interval spanning between this DateTime and another DateTime
7563   * @param {DateTime} otherDateTime - the other end point of the Interval
7564   * @return {Interval}
7565   */
7566  until(otherDateTime) {
7567    return this.isValid ? Interval.fromDateTimes(this, otherDateTime) : this;
7568  }
7569
7570  /**
7571   * Return whether this DateTime is in the same unit of time as another DateTime.
7572   * Higher-order units must also be identical for this function to return `true`.
7573   * Note that time zones are **ignored** in this comparison, which compares the **local** calendar time. Use {@link DateTime#setZone} to convert one of the dates if needed.
7574   * @param {DateTime} otherDateTime - the other DateTime
7575   * @param {string} unit - the unit of time to check sameness on
7576   * @param {Object} opts - options
7577   * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week; only the locale of this DateTime is used
7578   * @example DateTime.now().hasSame(otherDT, 'day'); //~> true if otherDT is in the same current calendar day
7579   * @return {boolean}
7580   */
7581  hasSame(otherDateTime, unit, opts) {
7582    if (!this.isValid) return false;
7583
7584    const inputMs = otherDateTime.valueOf();
7585    const adjustedToZone = this.setZone(otherDateTime.zone, { keepLocalTime: true });
7586    return (
7587      adjustedToZone.startOf(unit, opts) <= inputMs && inputMs <= adjustedToZone.endOf(unit, opts)
7588    );
7589  }
7590
7591  /**
7592   * Equality check
7593   * Two DateTimes are equal if and only if they represent the same millisecond, have the same zone and location, and are both valid.
7594   * To compare just the millisecond values, use `+dt1 === +dt2`.
7595   * @param {DateTime} other - the other DateTime
7596   * @return {boolean}
7597   */
7598  equals(other) {
7599    return (
7600      this.isValid &&
7601      other.isValid &&
7602      this.valueOf() === other.valueOf() &&
7603      this.zone.equals(other.zone) &&
7604      this.loc.equals(other.loc)
7605    );
7606  }
7607
7608  /**
7609   * Returns a string representation of a this time relative to now, such as "in two days". Can only internationalize if your
7610   * platform supports Intl.RelativeTimeFormat. Rounds down by default.
7611   * @param {Object} options - options that affect the output
7612   * @param {DateTime} [options.base=DateTime.now()] - the DateTime to use as the basis to which this time is compared. Defaults to now.
7613   * @param {string} [options.style="long"] - the style of units, must be "long", "short", or "narrow"
7614   * @param {string|string[]} options.unit - use a specific unit or array of units; if omitted, or an array, the method will pick the best unit. Use an array or one of "years", "quarters", "months", "weeks", "days", "hours", "minutes", or "seconds"
7615   * @param {boolean} [options.round=true] - whether to round the numbers in the output.
7616   * @param {number} [options.padding=0] - padding in milliseconds. This allows you to round up the result if it fits inside the threshold. Don't use in combination with {round: false} because the decimal output will include the padding.
7617   * @param {string} options.locale - override the locale of this DateTime
vendor: 11,479 bytes, lines 7618-7981
7618   * @param {string} options.numberingSystem - override the numberingSystem of this DateTime. The Intl system may choose not to honor this
7619   * @example DateTime.now().plus({ days: 1 }).toRelative() //=> "in 1 day"
7620   * @example DateTime.now().setLocale("es").toRelative({ days: 1 }) //=> "dentro de 1 día"
7621   * @example DateTime.now().plus({ days: 1 }).toRelative({ locale: "fr" }) //=> "dans 23 heures"
7622   * @example DateTime.now().minus({ days: 2 }).toRelative() //=> "2 days ago"
7623   * @example DateTime.now().minus({ days: 2 }).toRelative({ unit: "hours" }) //=> "48 hours ago"
7624   * @example DateTime.now().minus({ hours: 36 }).toRelative({ round: false }) //=> "1.5 days ago"
7625   */
7626  toRelative(options = {}) {
7627    if (!this.isValid) return null;
7628    const base = options.base || DateTime.fromObject({}, { zone: this.zone }),
7629      padding = options.padding ? (this < base ? -options.padding : options.padding) : 0;
7630    let units = ["years", "months", "days", "hours", "minutes", "seconds"];
7631    let unit = options.unit;
7632    if (Array.isArray(options.unit)) {
7633      units = options.unit;
7634      unit = undefined;
7635    }
7636    return diffRelative(base, this.plus(padding), {
7637      ...options,
7638      numeric: "always",
7639      units,
7640      unit,
7641    });
7642  }
7643
7644  /**
7645   * Returns a string representation of this date relative to today, such as "yesterday" or "next month".
7646   * Only internationalizes on platforms that supports Intl.RelativeTimeFormat.
7647   * @param {Object} options - options that affect the output
7648   * @param {DateTime} [options.base=DateTime.now()] - the DateTime to use as the basis to which this time is compared. Defaults to now.
7649   * @param {string} options.locale - override the locale of this DateTime
7650   * @param {string} options.unit - use a specific unit; if omitted, the method will pick the unit. Use one of "years", "quarters", "months", "weeks", or "days"
7651   * @param {string} options.numberingSystem - override the numberingSystem of this DateTime. The Intl system may choose not to honor this
7652   * @example DateTime.now().plus({ days: 1 }).toRelativeCalendar() //=> "tomorrow"
7653   * @example DateTime.now().setLocale("es").plus({ days: 1 }).toRelative() //=> ""mañana"
7654   * @example DateTime.now().plus({ days: 1 }).toRelativeCalendar({ locale: "fr" }) //=> "demain"
7655   * @example DateTime.now().minus({ days: 2 }).toRelativeCalendar() //=> "2 days ago"
7656   */
7657  toRelativeCalendar(options = {}) {
7658    if (!this.isValid) return null;
7659
7660    return diffRelative(options.base || DateTime.fromObject({}, { zone: this.zone }), this, {
7661      ...options,
7662      numeric: "auto",
7663      units: ["years", "months", "days"],
7664      calendary: true,
7665    });
7666  }
7667
7668  /**
7669   * Return the min of several date times
7670   * @param {...DateTime} dateTimes - the DateTimes from which to choose the minimum
7671   * @return {DateTime} the min DateTime, or undefined if called with no argument
7672   */
7673  static min(...dateTimes) {
7674    if (!dateTimes.every(DateTime.isDateTime)) {
7675      throw new InvalidArgumentError("min requires all arguments be DateTimes");
7676    }
7677    return bestBy(dateTimes, (i) => i.valueOf(), Math.min);
7678  }
7679
7680  /**
7681   * Return the max of several date times
7682   * @param {...DateTime} dateTimes - the DateTimes from which to choose the maximum
7683   * @return {DateTime} the max DateTime, or undefined if called with no argument
7684   */
7685  static max(...dateTimes) {
7686    if (!dateTimes.every(DateTime.isDateTime)) {
7687      throw new InvalidArgumentError("max requires all arguments be DateTimes");
7688    }
7689    return bestBy(dateTimes, (i) => i.valueOf(), Math.max);
7690  }
7691
7692  // MISC
7693
7694  /**
7695   * Explain how a string would be parsed by fromFormat()
7696   * @param {string} text - the string to parse
7697   * @param {string} fmt - the format the string is expected to be in (see description)
7698   * @param {Object} options - options taken by fromFormat()
7699   * @return {Object}
7700   */
7701  static fromFormatExplain(text, fmt, options = {}) {
7702    const { locale = null, numberingSystem = null } = options,
7703      localeToUse = Locale.fromOpts({
7704        locale,
7705        numberingSystem,
7706        defaultToEN: true,
7707      });
7708    return explainFromTokens(localeToUse, text, fmt);
7709  }
7710
7711  /**
7712   * @deprecated use fromFormatExplain instead
7713   */
7714  static fromStringExplain(text, fmt, options = {}) {
7715    return DateTime.fromFormatExplain(text, fmt, options);
7716  }
7717
7718  /**
7719   * Build a parser for `fmt` using the given locale. This parser can be passed
7720   * to {@link DateTime.fromFormatParser} to a parse a date in this format. This
7721   * can be used to optimize cases where many dates need to be parsed in a
7722   * specific format.
7723   *
7724   * @param {String} fmt - the format the string is expected to be in (see
7725   * description)
7726   * @param {Object} options - options used to set locale and numberingSystem
7727   * for parser
7728   * @returns {TokenParser} - opaque object to be used
7729   */
7730  static buildFormatParser(fmt, options = {}) {
7731    const { locale = null, numberingSystem = null } = options,
7732      localeToUse = Locale.fromOpts({
7733        locale,
7734        numberingSystem,
7735        defaultToEN: true,
7736      });
7737    return new TokenParser(localeToUse, fmt);
7738  }
7739
7740  /**
7741   * Create a DateTime from an input string and format parser.
7742   *
7743   * The format parser must have been created with the same locale as this call.
7744   *
7745   * @param {String} text - the string to parse
7746   * @param {TokenParser} formatParser - parser from {@link DateTime.buildFormatParser}
7747   * @param {Object} opts - options taken by fromFormat()
7748   * @returns {DateTime}
7749   */
7750  static fromFormatParser(text, formatParser, opts = {}) {
7751    if (isUndefined(text) || isUndefined(formatParser)) {
7752      throw new InvalidArgumentError(
7753        "fromFormatParser requires an input string and a format parser"
7754      );
7755    }
7756    const { locale = null, numberingSystem = null } = opts,
7757      localeToUse = Locale.fromOpts({
7758        locale,
7759        numberingSystem,
7760        defaultToEN: true,
7761      });
7762
7763    if (!localeToUse.equals(formatParser.locale)) {
7764      throw new InvalidArgumentError(
7765        `fromFormatParser called with a locale of ${localeToUse}, ` +
7766          `but the format parser was created for ${formatParser.locale}`
7767      );
7768    }
7769
7770    const { result, zone, specificOffset, invalidReason } = formatParser.explainFromTokens(text);
7771
7772    if (invalidReason) {
7773      return DateTime.invalid(invalidReason);
7774    } else {
7775      return parseDataToDateTime(
7776        result,
7777        zone,
7778        opts,
7779        `format ${formatParser.format}`,
7780        text,
7781        specificOffset
7782      );
7783    }
7784  }
7785
7786  // FORMAT PRESETS
7787
7788  /**
7789   * {@link DateTime#toLocaleString} format like 10/14/1983
7790   * @type {Object}
7791   */
7792  static get DATE_SHORT() {
7793    return DATE_SHORT;
7794  }
7795
7796  /**
7797   * {@link DateTime#toLocaleString} format like 'Oct 14, 1983'
7798   * @type {Object}
7799   */
7800  static get DATE_MED() {
7801    return DATE_MED;
7802  }
7803
7804  /**
7805   * {@link DateTime#toLocaleString} format like 'Fri, Oct 14, 1983'
7806   * @type {Object}
7807   */
7808  static get DATE_MED_WITH_WEEKDAY() {
7809    return DATE_MED_WITH_WEEKDAY;
7810  }
7811
7812  /**
7813   * {@link DateTime#toLocaleString} format like 'October 14, 1983'
7814   * @type {Object}
7815   */
7816  static get DATE_FULL() {
7817    return DATE_FULL;
7818  }
7819
7820  /**
7821   * {@link DateTime#toLocaleString} format like 'Tuesday, October 14, 1983'
7822   * @type {Object}
7823   */
7824  static get DATE_HUGE() {
7825    return DATE_HUGE;
7826  }
7827
7828  /**
7829   * {@link DateTime#toLocaleString} format like '09:30 AM'. Only 12-hour if the locale is.
7830   * @type {Object}
7831   */
7832  static get TIME_SIMPLE() {
7833    return TIME_SIMPLE;
7834  }
7835
7836  /**
7837   * {@link DateTime#toLocaleString} format like '09:30:23 AM'. Only 12-hour if the locale is.
7838   * @type {Object}
7839   */
7840  static get TIME_WITH_SECONDS() {
7841    return TIME_WITH_SECONDS;
7842  }
7843
7844  /**
7845   * {@link DateTime#toLocaleString} format like '09:30:23 AM EDT'. Only 12-hour if the locale is.
7846   * @type {Object}
7847   */
7848  static get TIME_WITH_SHORT_OFFSET() {
7849    return TIME_WITH_SHORT_OFFSET;
7850  }
7851
7852  /**
7853   * {@link DateTime#toLocaleString} format like '09:30:23 AM Eastern Daylight Time'. Only 12-hour if the locale is.
7854   * @type {Object}
7855   */
7856  static get TIME_WITH_LONG_OFFSET() {
7857    return TIME_WITH_LONG_OFFSET;
7858  }
7859
7860  /**
7861   * {@link DateTime#toLocaleString} format like '09:30', always 24-hour.
7862   * @type {Object}
7863   */
7864  static get TIME_24_SIMPLE() {
7865    return TIME_24_SIMPLE;
7866  }
7867
7868  /**
7869   * {@link DateTime#toLocaleString} format like '09:30:23', always 24-hour.
7870   * @type {Object}
7871   */
7872  static get TIME_24_WITH_SECONDS() {
7873    return TIME_24_WITH_SECONDS;
7874  }
7875
7876  /**
7877   * {@link DateTime#toLocaleString} format like '09:30:23 EDT', always 24-hour.
7878   * @type {Object}
7879   */
7880  static get TIME_24_WITH_SHORT_OFFSET() {
7881    return TIME_24_WITH_SHORT_OFFSET;
7882  }
7883
7884  /**
7885   * {@link DateTime#toLocaleString} format like '09:30:23 Eastern Daylight Time', always 24-hour.
7886   * @type {Object}
7887   */
7888  static get TIME_24_WITH_LONG_OFFSET() {
7889    return TIME_24_WITH_LONG_OFFSET;
7890  }
7891
7892  /**
7893   * {@link DateTime#toLocaleString} format like '10/14/1983, 9:30 AM'. Only 12-hour if the locale is.
7894   * @type {Object}
7895   */
7896  static get DATETIME_SHORT() {
7897    return DATETIME_SHORT;
7898  }
7899
7900  /**
7901   * {@link DateTime#toLocaleString} format like '10/14/1983, 9:30:33 AM'. Only 12-hour if the locale is.
7902   * @type {Object}
7903   */
7904  static get DATETIME_SHORT_WITH_SECONDS() {
7905    return DATETIME_SHORT_WITH_SECONDS;
7906  }
7907
7908  /**
7909   * {@link DateTime#toLocaleString} format like 'Oct 14, 1983, 9:30 AM'. Only 12-hour if the locale is.
7910   * @type {Object}
7911   */
7912  static get DATETIME_MED() {
7913    return DATETIME_MED;
7914  }
7915
7916  /**
7917   * {@link DateTime#toLocaleString} format like 'Oct 14, 1983, 9:30:33 AM'. Only 12-hour if the locale is.
7918   * @type {Object}
7919   */
7920  static get DATETIME_MED_WITH_SECONDS() {
7921    return DATETIME_MED_WITH_SECONDS;
7922  }
7923
7924  /**
7925   * {@link DateTime#toLocaleString} format like 'Fri, 14 Oct 1983, 9:30 AM'. Only 12-hour if the locale is.
7926   * @type {Object}
7927   */
7928  static get DATETIME_MED_WITH_WEEKDAY() {
7929    return DATETIME_MED_WITH_WEEKDAY;
7930  }
7931
7932  /**
7933   * {@link DateTime#toLocaleString} format like 'October 14, 1983, 9:30 AM EDT'. Only 12-hour if the locale is.
7934   * @type {Object}
7935   */
7936  static get DATETIME_FULL() {
7937    return DATETIME_FULL;
7938  }
7939
7940  /**
7941   * {@link DateTime#toLocaleString} format like 'October 14, 1983, 9:30:33 AM EDT'. Only 12-hour if the locale is.
7942   * @type {Object}
7943   */
7944  static get DATETIME_FULL_WITH_SECONDS() {
7945    return DATETIME_FULL_WITH_SECONDS;
7946  }
7947
7948  /**
7949   * {@link DateTime#toLocaleString} format like 'Friday, October 14, 1983, 9:30 AM Eastern Daylight Time'. Only 12-hour if the locale is.
7950   * @type {Object}
7951   */
7952  static get DATETIME_HUGE() {
7953    return DATETIME_HUGE;
7954  }
7955
7956  /**
7957   * {@link DateTime#toLocaleString} format like 'Friday, October 14, 1983, 9:30:33 AM Eastern Daylight Time'. Only 12-hour if the locale is.
7958   * @type {Object}
7959   */
7960  static get DATETIME_HUGE_WITH_SECONDS() {
7961    return DATETIME_HUGE_WITH_SECONDS;
7962  }
7963}
7964
7965/**
7966 * @private
7967 */
7968function friendlyDateTime(dateTimeish) {
7969  if (DateTime.isDateTime(dateTimeish)) {
7970    return dateTimeish;
7971  } else if (dateTimeish && dateTimeish.valueOf && isNumber(dateTimeish.valueOf())) {
7972    return DateTime.fromJSDate(dateTimeish);
7973  } else if (dateTimeish && typeof dateTimeish === "object") {
7974    return DateTime.fromObject(dateTimeish);
7975  } else {
7976    throw new InvalidArgumentError(
7977      `Unknown datetime argument: ${dateTimeish}, of type ${typeof dateTimeish}`
7978    );
7979  }
7980}
7981
7982const VERSION = "3.5.0";
7983
7984export { DateTime, Duration, FixedOffsetZone, IANAZone, Info, Interval, InvalidZone, Settings, SystemZone, VERSION, Zone };
7985//# sourceMappingURL=luxon.js-241e61568d0a7bdb918f8f1f9fba6936.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.