@fr0st/datetime 6.0.1 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/date-time.js CHANGED
@@ -1,17 +1,394 @@
1
- import { getOffset } from './helpers.js';
2
- import { config, dateStringTimeZoneRegExp, offsetRegExp } from './vars.js';
3
- import { formatOffset } from './formatter/format.js';
1
+ import { clearDataCache as clearFactoryDataCache } from './factory.js';
2
+ import {
3
+ formatDay,
4
+ formatDayPeriod,
5
+ formatEra,
6
+ formatMonth,
7
+ formatOffset,
8
+ formatRelative,
9
+ formatTimeZoneName,
10
+ } from './formatter/format.js';
11
+ import tokens from './formatter/tokens.js';
12
+ import { decodeLiteral, getTokenRegExp, minimumDays, weekDay } from './formatter/utility.js';
13
+ import {
14
+ calculateDiff,
15
+ getBiggestDiff,
16
+ getOffset,
17
+ getOffsetTime,
18
+ parseCompare,
19
+ parseFactory,
20
+ parseLocalTimestamp,
21
+ setOffsetTime,
22
+ } from './helpers.js';
23
+ import {
24
+ config,
25
+ dateStringTimeZoneRegExp,
26
+ formats,
27
+ formatTokenRegExp,
28
+ monthDays,
29
+ offsetRegExp,
30
+ parseOrderKeys,
31
+ } from './vars.js';
4
32
 
5
33
  /**
6
- * DateTime class
7
- * @class
34
+ * @typedef {{timeZone?: string, locale?: string}} DateTimeOptions
35
+ */
36
+
37
+ /**
38
+ * An immutable date and time object with locale-aware formatting and time-zone support.
8
39
  */
9
40
  export default class DateTime {
10
41
  /**
11
- * New DateTime constructor.
12
- * @param {string|number|null} [date] The date or timestamp to parse.
13
- * @param {object} [options] Options for the new DateTime.
14
- * @param {string} [options.timeZone] The timeZone to use.
42
+ * Clears cached formatter and locale data.
43
+ */
44
+ static clearDataCache() {
45
+ clearFactoryDataCache();
46
+ }
47
+
48
+ /**
49
+ * Gets the day of the year for a year, month and date.
50
+ * @param {number} year The year.
51
+ * @param {number} month The month. (1-12)
52
+ * @param {number} date The date.
53
+ * @return {number} The day of the year. (1-366)
54
+ */
55
+ static dayOfYear(year, month, date) {
56
+ return new Array(month - 1)
57
+ .fill()
58
+ .reduce(
59
+ (d, _, i) =>
60
+ d + this.daysInMonth(year, i + 1),
61
+ date,
62
+ );
63
+ }
64
+
65
+ /**
66
+ * Gets the number of days in a month for a given year.
67
+ * @param {number} year The year.
68
+ * @param {number} month The month. (1-12)
69
+ * @return {number} The number of days in the month.
70
+ */
71
+ static daysInMonth(year, month) {
72
+ const date = new Date(0);
73
+ date.setUTCFullYear(year, month - 1, 1);
74
+ month = date.getUTCMonth();
75
+
76
+ return monthDays[month] +
77
+ (
78
+ month === 1 && this.isLeapYear(
79
+ date.getUTCFullYear(),
80
+ ) ?
81
+ 1 :
82
+ 0
83
+ );
84
+ }
85
+
86
+ /**
87
+ * Gets the number of days in a given year.
88
+ * @param {number} year The year.
89
+ * @return {number} The number of days in the year.
90
+ */
91
+ static daysInYear(year) {
92
+ return !this.isLeapYear(year) ?
93
+ 365 :
94
+ 366;
95
+ }
96
+
97
+ /**
98
+ * Creates a new DateTime from an array. Missing month/date values default to 1.
99
+ * Missing time values default to 0.
100
+ * @param {number[]} dateArray The date to parse.
101
+ * @param {DateTimeOptions} [options={}] Options for the new DateTime.
102
+ * @param {string} [options.timeZone] The time zone to use.
103
+ * @param {string} [options.locale] The locale to use.
104
+ * @return {DateTime} A new DateTime instance.
105
+ */
106
+ static fromArray(dateArray, options = {}) {
107
+ const dateValues = dateArray.slice(0, 3);
108
+ const timeValues = dateArray.slice(3);
109
+
110
+ if (dateValues.length < 3) {
111
+ dateValues.push(...new Array(3 - dateValues.length).fill(1));
112
+ }
113
+
114
+ if (timeValues.length < 4) {
115
+ timeValues.push(...new Array(4 - timeValues.length).fill(0));
116
+ }
117
+
118
+ return new this(null, options)
119
+ .withTimestamp(0)
120
+ .withYear(...dateValues)
121
+ .withHours(...timeValues);
122
+ }
123
+
124
+ /**
125
+ * Creates a new DateTime from a Date.
126
+ * @param {Date} date The date.
127
+ * @param {DateTimeOptions} [options={}] Options for the new DateTime.
128
+ * @param {string} [options.timeZone] The time zone to use.
129
+ * @param {string} [options.locale] The locale to use.
130
+ * @return {DateTime} A new DateTime instance.
131
+ */
132
+ static fromDate(date, options = {}) {
133
+ return new this(date.getTime(), options);
134
+ }
135
+
136
+ /**
137
+ * Creates a new DateTime from a format string.
138
+ * @param {string} formatString The format string.
139
+ * @param {string} dateString The date string.
140
+ * @param {DateTimeOptions} [options={}] Options for the new DateTime.
141
+ * @param {string} [options.timeZone] The time zone to use.
142
+ * @param {string} [options.locale] The locale to use.
143
+ * @throws {Error} Throws when the format contains unsupported parsing tokens such as
144
+ * `MMMMM` or `LLLLL`.
145
+ * @return {DateTime} A new DateTime instance.
146
+ */
147
+ static fromFormat(formatString, dateString, options = {}) {
148
+ const locale = 'locale' in options ?
149
+ options.locale :
150
+ config.defaultLocale;
151
+ const requestedTimeZone = 'timeZone' in options ?
152
+ options.timeZone :
153
+ config.defaultTimeZone;
154
+
155
+ const values = [];
156
+
157
+ let match;
158
+ let previousTokenNumeric = false;
159
+ while (formatString && (match = formatString.match(formatTokenRegExp))) {
160
+ const token = match[1];
161
+ const position = match.index;
162
+ const length = match[0].length;
163
+
164
+ if (position) {
165
+ const formatTest = formatString.substring(0, position);
166
+ parseCompare(formatTest, dateString);
167
+ }
168
+
169
+ formatString = formatString.substring(position + length);
170
+ dateString = dateString.substring(position);
171
+
172
+ if (!token) {
173
+ const literal = decodeLiteral(match[0]);
174
+ parseCompare(literal, dateString);
175
+ dateString = dateString.substring(literal.length);
176
+ previousTokenNumeric = false;
177
+ continue;
178
+ }
179
+
180
+ if (!(token in tokens)) {
181
+ throw new Error(`Invalid token in DateTime format: ${token}`);
182
+ }
183
+
184
+ if (tokens[token].supportsLength?.(length, true) === false) {
185
+ throw new Error(`Unsupported parsing token in DateTime format: ${token.repeat(length)}`);
186
+ }
187
+
188
+ const previousNumeric = previousTokenNumeric && !position;
189
+ let nextSource = null;
190
+
191
+ if (!previousNumeric) {
192
+ const nextToken = formatString[0];
193
+ if (nextToken && nextToken in tokens) {
194
+ const nextLength = formatString.match(/^(.)\1*/)[0].length;
195
+ nextSource = tokens[nextToken].regex(locale, nextLength);
196
+ }
197
+ }
198
+
199
+ const { numeric, source } = getTokenRegExp(
200
+ tokens[token].regex(locale, length),
201
+ nextSource,
202
+ length,
203
+ locale,
204
+ previousNumeric,
205
+ );
206
+ const matchedValue = dateString.match(new RegExp(`^${source}`));
207
+
208
+ if (!matchedValue) {
209
+ throw new Error(`Unmatched token in DateTime string: ${token}`);
210
+ }
211
+
212
+ const literal = matchedValue[0];
213
+ const value = tokens[token].input(locale, literal, length);
214
+
215
+ if (value !== null) {
216
+ const key = tokens[token].key;
217
+ values.push({ key, value, literal, token, length });
218
+ }
219
+
220
+ dateString = dateString.substring(literal.length);
221
+ previousTokenNumeric = numeric;
222
+ }
223
+
224
+ if (formatString) {
225
+ parseCompare(formatString, dateString);
226
+ dateString = dateString.substring(formatString.length);
227
+ }
228
+
229
+ if (dateString) {
230
+ throw new Error(`Unmatched trailing characters in DateTime string: ${dateString}`);
231
+ }
232
+
233
+ let timeZone = requestedTimeZone;
234
+ for (const { key, value } of values) {
235
+ if (key !== 'timeZone') {
236
+ continue;
237
+ }
238
+
239
+ timeZone = value;
240
+ }
241
+
242
+ let datetime = this.fromArray([1970, 1, 1], {
243
+ locale,
244
+ timeZone,
245
+ });
246
+
247
+ const methods = parseFactory();
248
+
249
+ const testValues = [];
250
+
251
+ for (const subKeys of parseOrderKeys) {
252
+ for (const subKey of subKeys) {
253
+ if (subKey === 'era' && !values.find((data) => data.key === 'year')) {
254
+ continue;
255
+ }
256
+
257
+ for (const data of values) {
258
+ const { key, value } = data;
259
+
260
+ if (key !== subKey) {
261
+ continue;
262
+ }
263
+
264
+ datetime = methods[key].set(datetime, value);
265
+ testValues.push(data);
266
+ }
267
+ }
268
+ }
269
+
270
+ let isValid = true;
271
+ for (const { key, value } of testValues) {
272
+ if (key in methods && methods[key].get(datetime) !== value) {
273
+ isValid = false;
274
+ break;
275
+ }
276
+ }
277
+
278
+ if (requestedTimeZone !== timeZone) {
279
+ datetime = datetime.withTimeZone(requestedTimeZone);
280
+ }
281
+
282
+ datetime.isValid = isValid;
283
+
284
+ return datetime;
285
+ }
286
+
287
+ /**
288
+ * Creates a new DateTime from an ISO format string.
289
+ * @param {string} dateString The date string.
290
+ * @param {DateTimeOptions} [options={}] Options for the new DateTime.
291
+ * @param {string} [options.timeZone] The time zone to use.
292
+ * @param {string} [options.locale] The locale to use.
293
+ * @return {DateTime} A new DateTime instance.
294
+ */
295
+ static fromISOString(dateString, options = {}) {
296
+ let date = this.fromFormat(formats.rfc3339_extended, dateString, {
297
+ locale: 'en',
298
+ });
299
+
300
+ if ('timeZone' in options) {
301
+ date = date.withTimeZone(options.timeZone);
302
+ }
303
+
304
+ if ('locale' in options) {
305
+ date = date.withLocale(options.locale);
306
+ }
307
+
308
+ return date;
309
+ }
310
+
311
+ /**
312
+ * Creates a new DateTime from a timestamp.
313
+ * @param {number} timestamp The number of seconds since the UNIX epoch.
314
+ * @param {DateTimeOptions} [options={}] Options for the new DateTime.
315
+ * @param {string} [options.timeZone] The time zone to use.
316
+ * @param {string} [options.locale] The locale to use.
317
+ * @return {DateTime} A new DateTime instance.
318
+ */
319
+ static fromTimestamp(timestamp, options = {}) {
320
+ return new this(null, options)
321
+ .withTimestamp(timestamp);
322
+ }
323
+
324
+ /**
325
+ * Gets the default locale.
326
+ * @return {string} The locale.
327
+ */
328
+ static getDefaultLocale() {
329
+ return config.defaultLocale;
330
+ }
331
+
332
+ /**
333
+ * Gets the default time zone.
334
+ * @return {string} The default time zone.
335
+ */
336
+ static getDefaultTimeZone() {
337
+ return config.defaultTimeZone;
338
+ }
339
+
340
+ /**
341
+ * Checks whether the year is a leap year.
342
+ * @param {number} year The year.
343
+ * @return {boolean} Whether the given year is a leap year.
344
+ */
345
+ static isLeapYear(year) {
346
+ const date = new Date(0);
347
+ date.setUTCFullYear(year, 1, 29);
348
+
349
+ return date.getUTCDate() === 29;
350
+ }
351
+
352
+ /**
353
+ * Creates a new DateTime for the current time.
354
+ * @param {DateTimeOptions} [options={}] Options for the new DateTime.
355
+ * @param {string} [options.timeZone] The time zone to use.
356
+ * @param {string} [options.locale] The locale to use.
357
+ * @return {DateTime} A new DateTime instance.
358
+ */
359
+ static now(options = {}) {
360
+ return new this(null, options);
361
+ }
362
+
363
+ /**
364
+ * Sets whether dates will be clamped when changing months.
365
+ * @param {boolean} clampDates Whether to clamp dates.
366
+ */
367
+ static setDateClamping(clampDates) {
368
+ config.clampDates = clampDates;
369
+ }
370
+
371
+ /**
372
+ * Sets the default locale.
373
+ * @param {string} locale The locale.
374
+ */
375
+ static setDefaultLocale(locale) {
376
+ config.defaultLocale = locale;
377
+ }
378
+
379
+ /**
380
+ * Sets the default time zone.
381
+ * @param {string} timeZone The time zone name.
382
+ */
383
+ static setDefaultTimeZone(timeZone) {
384
+ config.defaultTimeZone = timeZone;
385
+ }
386
+
387
+ /**
388
+ * Creates a new DateTime from the current time, epoch milliseconds, or a date string.
389
+ * @param {string|number|null} [date=null] The source date. Numbers are interpreted as milliseconds since the UNIX epoch.
390
+ * @param {DateTimeOptions} [options={}] Options for the new DateTime.
391
+ * @param {string} [options.timeZone] The time zone to use.
15
392
  * @param {string} [options.locale] The locale to use.
16
393
  */
17
394
  constructor(date = null, options = {}) {
@@ -20,7 +397,7 @@ export default class DateTime {
20
397
 
21
398
  if (date === null) {
22
399
  timestamp = Date.now();
23
- } else if (!isNaN(parseInt(date)) && isFinite(date)) {
400
+ } else if (typeof date === 'number' && Number.isFinite(date)) {
24
401
  timestamp = date;
25
402
  } else if (date === `${date}`) {
26
403
  timestamp = Date.parse(date);
@@ -29,13 +406,17 @@ export default class DateTime {
29
406
  throw new Error('Invalid date string supplied');
30
407
  }
31
408
 
32
- if (!date.match(dateStringTimeZoneRegExp)) {
33
- timestamp -= new Date()
34
- .getTimezoneOffset() *
35
- 60000;
36
- }
409
+ adjustOffset = !dateStringTimeZoneRegExp.test(date);
410
+
411
+ if (adjustOffset) {
412
+ const localTimestamp = parseLocalTimestamp(date);
37
413
 
38
- adjustOffset = true;
414
+ if (localTimestamp === null) {
415
+ timestamp -= new Date(timestamp).getTimezoneOffset() * 60000;
416
+ } else {
417
+ timestamp = localTimestamp;
418
+ }
419
+ }
39
420
  } else {
40
421
  throw new Error('Invalid date supplied');
41
422
  }
@@ -56,7 +437,10 @@ export default class DateTime {
56
437
 
57
438
  const match = timeZone.match(offsetRegExp);
58
439
  if (match) {
59
- this._offset = match[2] * 60 + parseInt(match[4] || 0);
440
+ this._offset =
441
+ match[2] * 60 +
442
+ parseInt(match[4] || 0, 10) +
443
+ parseInt(match[5] || 0, 10) / 60;
60
444
  if (this._offset && match[1] === '+') {
61
445
  this._offset *= -1;
62
446
  }
@@ -72,128 +456,1748 @@ export default class DateTime {
72
456
  this._timeZone = timeZone;
73
457
  }
74
458
 
459
+ this._locale = 'locale' in options ?
460
+ options.locale :
461
+ config.defaultLocale;
462
+
75
463
  if (this._dynamicTz) {
76
464
  this._offset = getOffset(this);
77
465
  }
78
466
 
79
467
  if (adjustOffset && this._offset) {
80
- const oldOffset = this._offset;
468
+ const resolvedDate = setOffsetTime(this, timestamp);
469
+ this._date.setTime(resolvedDate.getTime());
470
+ this._offset = resolvedDate.getTimeZoneOffset();
471
+ }
472
+ }
81
473
 
82
- this._date.setTime(this.getTime() + this._offset * 60000);
474
+ /**
475
+ * Adds a day to the current DateTime.
476
+ * @return {DateTime} A new DateTime instance.
477
+ */
478
+ addDay() {
479
+ return this.addDays(1);
480
+ }
83
481
 
84
- if (this._dynamicTz) {
85
- this._offset = getOffset(this);
482
+ /**
483
+ * Adds days to the current DateTime.
484
+ * @param {number} amount The number of days to add.
485
+ * @return {DateTime} A new DateTime instance.
486
+ */
487
+ addDays(amount) {
488
+ return setOffsetTime(
489
+ this,
490
+ new Date(getOffsetTime(this)).setUTCDate(
491
+ this.getDate() + amount,
492
+ ),
493
+ amount,
494
+ );
495
+ }
86
496
 
87
- // compensate for DST transitions
88
- if (oldOffset !== this._offset) {
89
- this._date.setTime(this.getTime() - ((oldOffset - offset) * 60000));
90
- }
91
- }
92
- }
497
+ /**
498
+ * Adds an hour to the current DateTime.
499
+ * @return {DateTime} A new DateTime instance.
500
+ */
501
+ addHour() {
502
+ return this.addHours(1);
503
+ }
93
504
 
94
- if (!('locale' in options)) {
95
- options.locale = config.defaultLocale;
96
- }
505
+ /**
506
+ * Adds hours to the current DateTime.
507
+ * @param {number} amount The number of hours to add.
508
+ * @return {DateTime} A new DateTime instance.
509
+ */
510
+ addHours(amount) {
511
+ return this.withTime(
512
+ this.getTime() + (amount * 3600000),
513
+ );
514
+ }
97
515
 
98
- this._locale = options.locale;
516
+ /**
517
+ * Adds a minute to the current DateTime.
518
+ * @return {DateTime} A new DateTime instance.
519
+ */
520
+ addMinute() {
521
+ return this.addMinutes(1);
99
522
  }
100
523
 
101
524
  /**
102
- * Get the name of the current locale.
103
- * @return {string} The name of the current locale.
525
+ * Adds minutes to the current DateTime.
526
+ * @param {number} amount The number of minutes to add.
527
+ * @return {DateTime} A new DateTime instance.
104
528
  */
105
- getLocale() {
106
- return this._locale;
529
+ addMinutes(amount) {
530
+ return this.withTime(
531
+ this.getTime() + (amount * 60000),
532
+ );
107
533
  }
108
534
 
109
535
  /**
110
- * Get the number of milliseconds since the UNIX epoch.
111
- * @return {number} The number of milliseconds since the UNIX epoch.
536
+ * Adds a month to the current DateTime.
537
+ * @return {DateTime} A new DateTime instance.
112
538
  */
113
- getTime() {
114
- return this._date.getTime();
539
+ addMonth() {
540
+ return this.addMonths(1);
115
541
  }
116
542
 
117
543
  /**
118
- * Get the name of the current timeZone.
119
- * @return {string} The name of the current timeZone.
544
+ * Adds months to the current DateTime.
545
+ * @param {number} amount The number of months to add.
546
+ * @return {DateTime} A new DateTime instance.
120
547
  */
121
- getTimeZone() {
122
- return this._timeZone;
548
+ addMonths(amount) {
549
+ return this.withMonth(
550
+ this.getMonth() + amount,
551
+ );
123
552
  }
124
553
 
125
554
  /**
126
- * Get the UTC offset (in minutes) of the current timeZone.
127
- * @return {number} The UTC offset (in minutes) of the current timeZone.
555
+ * Adds a second to the current DateTime.
556
+ * @return {DateTime} A new DateTime instance.
128
557
  */
129
- getTimeZoneOffset() {
130
- return this._offset;
558
+ addSecond() {
559
+ return this.addSeconds(1);
131
560
  }
132
561
 
133
562
  /**
134
- * Set the current locale.
135
- * @param {string} locale The name of the timeZone.
136
- * @return {DateTime} The DateTime object.
563
+ * Adds seconds to the current DateTime.
564
+ * @param {number} amount The number of seconds to add.
565
+ * @return {DateTime} A new DateTime instance.
137
566
  */
138
- setLocale(locale) {
139
- return new DateTime(this.getTime(), {
140
- locale,
141
- timeZone: this._timeZone,
142
- });
567
+ addSeconds(amount) {
568
+ return this.withTime(
569
+ this.getTime() + (amount * 1000),
570
+ );
143
571
  }
144
572
 
145
573
  /**
146
- * Set the number of milliseconds since the UNIX epoch.
147
- * @param {number} time The number of milliseconds since the UNIX epoch.
148
- * @return {DateTime} The DateTime object.
574
+ * Adds a week to the current DateTime.
575
+ * @return {DateTime} A new DateTime instance.
149
576
  */
150
- setTime(time) {
151
- return new DateTime(time, {
152
- locale: this._locale,
153
- timeZone: this._timeZone,
154
- });
577
+ addWeek() {
578
+ return this.addWeeks(1);
155
579
  }
156
580
 
157
581
  /**
158
- * Set the current timeZone.
159
- * @param {string} timeZone The name of the timeZone.
160
- * @return {DateTime} The DateTime object.
582
+ * Adds weeks to the current DateTime.
583
+ * @param {number} amount The number of weeks to add.
584
+ * @return {DateTime} A new DateTime instance.
161
585
  */
162
- setTimeZone(timeZone) {
163
- return new DateTime(this.getTime(), {
164
- locale: this._locale,
165
- timeZone,
166
- });
586
+ addWeeks(amount) {
587
+ return this.withDate(
588
+ this.getDate() + (amount * 7),
589
+ );
167
590
  }
168
591
 
169
592
  /**
170
- * Set the current UTC offset.
171
- * @param {number} offset The UTC offset (in minutes).
172
- * @return {DateTime} The DateTime object.
593
+ * Adds a year to the current DateTime.
594
+ * @return {DateTime} A new DateTime instance.
173
595
  */
174
- setTimeZoneOffset(offset) {
175
- return new DateTime(this.getTime(), {
176
- locale: this._locale,
177
- timeZone: formatOffset(offset),
178
- });
596
+ addYear() {
597
+ return this.addYears(1);
179
598
  }
180
599
 
181
600
  /**
182
- * Get the number of milliseconds since the UNIX epoch.
183
- * @return {number} The number of milliseconds since the UNIX epoch.
601
+ * Adds years to the current DateTime.
602
+ * @param {number} amount The number of years to add.
603
+ * @return {DateTime} A new DateTime instance.
184
604
  */
185
- valueOf() {
186
- return this.getTime();
605
+ addYears(amount) {
606
+ return this.withYear(
607
+ this.getYear() + amount,
608
+ );
187
609
  }
188
610
 
189
611
  /**
190
- * Return a primitive value of the DateTime.
191
- * @param {string} hint The type hint.
192
- * @return {string|number}
612
+ * Gets the localized day name for the current date.
613
+ * @param {'long'|'short'|'narrow'} [type='long'] The type of day name to return.
614
+ * @return {string} The localized day name.
193
615
  */
194
- [Symbol.toPrimitive](hint) {
195
- return hint === 'number' ?
196
- this.valueOf() :
197
- this.toString();
616
+ dayName(type = 'long') {
617
+ return formatDay(this.getLocale(), this.getDay(), type);
618
+ }
619
+
620
+ /**
621
+ * Gets the localized day period for the current time.
622
+ * @param {'long'|'short'|'narrow'} [type='long'] The type of day period to return.
623
+ * @return {string} The localized day period.
624
+ */
625
+ dayPeriod(type = 'long') {
626
+ return formatDayPeriod(
627
+ this.getLocale(),
628
+ this.getHours() < 12 ?
629
+ 0 :
630
+ 1,
631
+ type,
632
+ );
633
+ }
634
+
635
+ /**
636
+ * Gets the number of days in the current month.
637
+ * @return {number} The number of days in the current month.
638
+ */
639
+ daysInMonth() {
640
+ return this.constructor.daysInMonth(
641
+ this.getYear(),
642
+ this.getMonth(),
643
+ );
644
+ }
645
+
646
+ /**
647
+ * Gets the number of days in the current year.
648
+ * @return {number} The number of days in the current year.
649
+ */
650
+ daysInYear() {
651
+ return this.constructor.daysInYear(
652
+ this.getYear(),
653
+ );
654
+ }
655
+
656
+ /**
657
+ * Gets the difference between this and another Date in milliseconds.
658
+ * @param {DateTime} other The date to compare to.
659
+ * @return {number} The difference.
660
+ */
661
+ diff(other) {
662
+ return this - other;
663
+ }
664
+
665
+ /**
666
+ * Gets the difference between this and another Date in days.
667
+ * @param {DateTime} other The date to compare to.
668
+ * @param {{relative?: boolean}} [options] Options for comparing the dates.
669
+ * @return {number} The difference.
670
+ */
671
+ diffInDays(other, { relative = true } = {}) {
672
+ return calculateDiff(this, other, 'day', relative);
673
+ }
674
+
675
+ /**
676
+ * Gets the difference between this and another Date in hours.
677
+ * @param {DateTime} other The date to compare to.
678
+ * @param {{relative?: boolean}} [options] Options for comparing the dates.
679
+ * @return {number} The difference.
680
+ */
681
+ diffInHours(other, { relative = true } = {}) {
682
+ return calculateDiff(this, other, 'hour', relative);
683
+ }
684
+
685
+ /**
686
+ * Gets the difference between this and another Date in minutes.
687
+ * @param {DateTime} other The date to compare to.
688
+ * @param {{relative?: boolean}} [options] Options for comparing the dates.
689
+ * @return {number} The difference.
690
+ */
691
+ diffInMinutes(other, { relative = true } = {}) {
692
+ return calculateDiff(this, other, 'minute', relative);
693
+ }
694
+
695
+ /**
696
+ * Gets the difference between this and another Date in months.
697
+ * @param {DateTime} other The date to compare to.
698
+ * @param {{relative?: boolean}} [options] Options for comparing the dates.
699
+ * @return {number} The difference.
700
+ */
701
+ diffInMonths(other, { relative = true } = {}) {
702
+ return calculateDiff(this, other, 'month', relative);
703
+ }
704
+
705
+ /**
706
+ * Gets the difference between this and another Date in seconds.
707
+ * @param {DateTime} other The date to compare to.
708
+ * @param {{relative?: boolean}} [options] Options for comparing the dates.
709
+ * @return {number} The difference.
710
+ */
711
+ diffInSeconds(other, { relative = true } = {}) {
712
+ return calculateDiff(this, other, 'second', relative);
713
+ }
714
+
715
+ /**
716
+ * Gets the difference between this and another Date in weeks.
717
+ * @param {DateTime} other The date to compare to.
718
+ * @param {{relative?: boolean}} [options] Options for comparing the dates.
719
+ * @return {number} The difference.
720
+ */
721
+ diffInWeeks(other, { relative = true } = {}) {
722
+ return calculateDiff(this, other, 'week', relative);
723
+ }
724
+
725
+ /**
726
+ * Gets the difference between this and another Date in years.
727
+ * @param {DateTime} other The date to compare to.
728
+ * @param {{relative?: boolean}} [options] Options for comparing the dates.
729
+ * @return {number} The difference.
730
+ */
731
+ diffInYears(other, { relative = true } = {}) {
732
+ return calculateDiff(this, other, 'year', relative);
733
+ }
734
+
735
+ /**
736
+ * Sets the DateTime to the end of the day.
737
+ * @return {DateTime} A new DateTime instance.
738
+ */
739
+ endOfDay() {
740
+ return this.withHours(23, 59, 59, 999);
741
+ }
742
+
743
+ /**
744
+ * Sets the DateTime to the end of the hour.
745
+ * @return {DateTime} A new DateTime instance.
746
+ */
747
+ endOfHour() {
748
+ return this.withMinutes(59, 59, 999);
749
+ }
750
+
751
+ /**
752
+ * Sets the DateTime to the end of the minute.
753
+ * @return {DateTime} A new DateTime instance.
754
+ */
755
+ endOfMinute() {
756
+ return this.withSeconds(59, 999);
757
+ }
758
+
759
+ /**
760
+ * Sets the DateTime to the end of the month.
761
+ * @return {DateTime} A new DateTime instance.
762
+ */
763
+ endOfMonth() {
764
+ return this.withDate(this.daysInMonth())
765
+ .endOfDay();
766
+ }
767
+
768
+ /**
769
+ * Sets the DateTime to the end of the quarter.
770
+ * @return {DateTime} A new DateTime instance.
771
+ */
772
+ endOfQuarter() {
773
+ const month = this.getQuarter() * 3;
774
+ return this.withMonth(month, this.constructor.daysInMonth(this.getYear(), month))
775
+ .endOfDay();
776
+ }
777
+
778
+ /**
779
+ * Sets the DateTime to the end of the second.
780
+ * @return {DateTime} A new DateTime instance.
781
+ */
782
+ endOfSecond() {
783
+ return this.withMilliseconds(999);
784
+ }
785
+
786
+ /**
787
+ * Sets the DateTime to the end of the week.
788
+ * @return {DateTime} A new DateTime instance.
789
+ */
790
+ endOfWeek() {
791
+ return this.withWeekDay(7)
792
+ .endOfDay();
793
+ }
794
+
795
+ /**
796
+ * Sets the DateTime to the end of the year.
797
+ * @return {DateTime} A new DateTime instance.
798
+ */
799
+ endOfYear() {
800
+ return this.withMonth(12, 31)
801
+ .endOfDay();
802
+ }
803
+
804
+ /**
805
+ * Gets the localized era for the current date.
806
+ * @param {'long'|'short'|'narrow'} [type='long'] The type of era to return.
807
+ * @return {string} The localized era.
808
+ */
809
+ era(type = 'long') {
810
+ return formatEra(
811
+ this.getLocale(),
812
+ this.getYear() < 0 ?
813
+ 0 :
814
+ 1,
815
+ type,
816
+ );
817
+ }
818
+
819
+ /**
820
+ * Formats the current date using a format string.
821
+ * @param {string} formatString The format string.
822
+ * @return {string} The formatted date string.
823
+ */
824
+ format(formatString) {
825
+ let match;
826
+ let output = '';
827
+
828
+ while (formatString && (match = formatString.match(formatTokenRegExp))) {
829
+ const token = match[1];
830
+ const position = match.index;
831
+ const length = match[0].length;
832
+
833
+ if (position) {
834
+ output += formatString.substring(0, position);
835
+ }
836
+
837
+ formatString = formatString.substring(position + length);
838
+
839
+ if (!token) {
840
+ output += decodeLiteral(match[0]);
841
+ continue;
842
+ }
843
+
844
+ if (!(token in tokens)) {
845
+ throw new Error(`Invalid token in DateTime format: ${token}`);
846
+ }
847
+
848
+ if (tokens[token].supportsLength?.(length) === false) {
849
+ throw new Error(`Unsupported token in DateTime format: ${token.repeat(length)}`);
850
+ }
851
+
852
+ output += tokens[token].output(this, length);
853
+ }
854
+
855
+ output += formatString;
856
+
857
+ return output;
858
+ }
859
+
860
+ /**
861
+ * Gets the date of the month in the current time zone.
862
+ * @return {number} The date of the month.
863
+ */
864
+ getDate() {
865
+ return new Date(getOffsetTime(this)).getUTCDate();
866
+ }
867
+
868
+ /**
869
+ * Gets the day of the week in the current time zone.
870
+ * @return {number} The day of the week. (0 = Sunday, 6 = Saturday)
871
+ */
872
+ getDay() {
873
+ return new Date(getOffsetTime(this)).getUTCDay();
874
+ }
875
+
876
+ /**
877
+ * Gets the day of the year in the current time zone.
878
+ * @return {number} The day of the year. (1-366)
879
+ */
880
+ getDayOfYear() {
881
+ return this.constructor.dayOfYear(
882
+ this.getYear(),
883
+ this.getMonth(),
884
+ this.getDate(),
885
+ );
886
+ }
887
+
888
+ /**
889
+ * Gets the hours of the day in the current time zone.
890
+ * @return {number} The hours of the day. (0-23)
891
+ */
892
+ getHours() {
893
+ return new Date(getOffsetTime(this)).getUTCHours();
894
+ }
895
+
896
+ /**
897
+ * Gets the current locale.
898
+ * @return {string} The locale.
899
+ */
900
+ getLocale() {
901
+ return this._locale;
902
+ }
903
+
904
+ /**
905
+ * Gets the milliseconds in the current time zone.
906
+ * @return {number} The milliseconds.
907
+ */
908
+ getMilliseconds() {
909
+ return new Date(getOffsetTime(this)).getUTCMilliseconds();
910
+ }
911
+
912
+ /**
913
+ * Gets the minutes in the current time zone.
914
+ * @return {number} The minutes. (0-59)
915
+ */
916
+ getMinutes() {
917
+ return new Date(getOffsetTime(this)).getUTCMinutes();
918
+ }
919
+
920
+ /**
921
+ * Gets the month in the current time zone.
922
+ * @return {number} The month. (1-12)
923
+ */
924
+ getMonth() {
925
+ return new Date(getOffsetTime(this)).getUTCMonth() + 1;
926
+ }
927
+
928
+ /**
929
+ * Gets the quarter of the year in the current time zone.
930
+ * @return {number} The quarter of the year. (1-4)
931
+ */
932
+ getQuarter() {
933
+ return Math.ceil(this.getMonth() / 3);
934
+ }
935
+
936
+ /**
937
+ * Gets the seconds in the current time zone.
938
+ * @return {number} The seconds. (0-59)
939
+ */
940
+ getSeconds() {
941
+ return new Date(getOffsetTime(this)).getUTCSeconds();
942
+ }
943
+
944
+ /**
945
+ * Gets the number of milliseconds since the UNIX epoch.
946
+ * @return {number} The number of milliseconds since the UNIX epoch.
947
+ */
948
+ getTime() {
949
+ return this._date.getTime();
950
+ }
951
+
952
+ /**
953
+ * Gets the number of seconds since the UNIX epoch.
954
+ * @return {number} The number of seconds since the UNIX epoch.
955
+ */
956
+ getTimestamp() {
957
+ return Math.floor(this.getTime() / 1000);
958
+ }
959
+
960
+ /**
961
+ * Gets the current time zone.
962
+ * @return {string} The time zone.
963
+ */
964
+ getTimeZone() {
965
+ return this._timeZone;
966
+ }
967
+
968
+ /**
969
+ * Gets the current UTC offset in minutes.
970
+ * @return {number} The UTC offset in minutes.
971
+ */
972
+ getTimeZoneOffset() {
973
+ return this._offset;
974
+ }
975
+
976
+ /**
977
+ * Gets the local week in the current time zone.
978
+ * @return {number} The local week. (1-53)
979
+ */
980
+ getWeek() {
981
+ const thisWeek = this.startOfDay().withWeekDay(1);
982
+ const firstWeek = thisWeek.withWeek(1, 1);
983
+
984
+ return 1 + Math.floor(
985
+ (getOffsetTime(thisWeek) - getOffsetTime(firstWeek)) /
986
+ 604800000,
987
+ );
988
+ }
989
+
990
+ /**
991
+ * Gets the local day of the week in the current time zone.
992
+ * @return {number} The local day of the week. (1-7)
993
+ */
994
+ getWeekDay() {
995
+ return weekDay(
996
+ this.getLocale(),
997
+ this.getDay(),
998
+ );
999
+ }
1000
+
1001
+ /**
1002
+ * Gets the week day in month in the current time zone.
1003
+ * @return {number} The week day in month.
1004
+ */
1005
+ getWeekDayInMonth() {
1006
+ const thisWeek = this.getWeek();
1007
+ const first = this.withDate(1);
1008
+ const firstWeek = first.getWeek();
1009
+ const offset = first.getWeekDay() > this.getWeekDay() ?
1010
+ 0 : 1;
1011
+ return firstWeek > thisWeek ?
1012
+ thisWeek + offset :
1013
+ thisWeek - firstWeek + offset;
1014
+ }
1015
+
1016
+ /**
1017
+ * Gets the week of month in the current time zone.
1018
+ * @return {number} The week of month.
1019
+ */
1020
+ getWeekOfMonth() {
1021
+ const thisWeek = this.getWeek();
1022
+ const firstWeek = this.withDate(1).getWeek();
1023
+ return firstWeek > thisWeek ?
1024
+ thisWeek + 1 :
1025
+ thisWeek - firstWeek + 1;
1026
+ }
1027
+
1028
+ /**
1029
+ * Gets the week year in the current time zone.
1030
+ * @return {number} The week year.
1031
+ */
1032
+ getWeekYear() {
1033
+ const minDays = minimumDays(this.getLocale());
1034
+ return this.withWeekDay(7 - minDays + 1).getYear();
1035
+ }
1036
+
1037
+ /**
1038
+ * Gets the year in the current time zone.
1039
+ * @return {number} The year.
1040
+ */
1041
+ getYear() {
1042
+ return new Date(getOffsetTime(this)).getUTCFullYear();
1043
+ }
1044
+
1045
+ /**
1046
+ * Gets the difference between this and another Date in human readable form.
1047
+ * @param {DateTime} other The date to compare to.
1048
+ * @return {string} The difference in human readable form.
1049
+ */
1050
+ humanDiff(other) {
1051
+ const [amount, unit] = getBiggestDiff(this, other);
1052
+ return formatRelative(this.getLocale(), amount, unit);
1053
+ }
1054
+
1055
+ /**
1056
+ * Gets the difference between this and another Date in days in human readable form.
1057
+ * @param {DateTime} other The date to compare to.
1058
+ * @return {string} The difference in days in human readable form.
1059
+ */
1060
+ humanDiffInDays(other) {
1061
+ return formatRelative(this.getLocale(), this.diffInDays(other), 'day');
1062
+ }
1063
+
1064
+ /**
1065
+ * Gets the difference between this and another Date in hours in human readable form.
1066
+ * @param {DateTime} other The date to compare to.
1067
+ * @return {string} The difference in hours in human readable form.
1068
+ */
1069
+ humanDiffInHours(other) {
1070
+ return formatRelative(this.getLocale(), this.diffInHours(other), 'hour');
1071
+ }
1072
+
1073
+ /**
1074
+ * Gets the difference between this and another Date in minutes in human readable form.
1075
+ * @param {DateTime} other The date to compare to.
1076
+ * @return {string} The difference in minutes in human readable form.
1077
+ */
1078
+ humanDiffInMinutes(other) {
1079
+ return formatRelative(this.getLocale(), this.diffInMinutes(other), 'minute');
1080
+ }
1081
+
1082
+ /**
1083
+ * Gets the difference between this and another Date in months in human readable form.
1084
+ * @param {DateTime} other The date to compare to.
1085
+ * @return {string} The difference in months in human readable form.
1086
+ */
1087
+ humanDiffInMonths(other) {
1088
+ return formatRelative(this.getLocale(), this.diffInMonths(other), 'month');
1089
+ }
1090
+
1091
+ /**
1092
+ * Gets the difference between this and another Date in seconds in human readable form.
1093
+ * @param {DateTime} other The date to compare to.
1094
+ * @return {string} The difference in seconds in human readable form.
1095
+ */
1096
+ humanDiffInSeconds(other) {
1097
+ return formatRelative(this.getLocale(), this.diffInSeconds(other), 'second');
1098
+ }
1099
+
1100
+ /**
1101
+ * Gets the difference between this and another Date in weeks in human readable form.
1102
+ * @param {DateTime} other The date to compare to.
1103
+ * @return {string} The difference in weeks in human readable form.
1104
+ */
1105
+ humanDiffInWeeks(other) {
1106
+ return formatRelative(this.getLocale(), this.diffInWeeks(other), 'week');
1107
+ }
1108
+
1109
+ /**
1110
+ * Gets the difference between this and another Date in years in human readable form.
1111
+ * @param {DateTime} other The date to compare to.
1112
+ * @return {string} The difference in years in human readable form.
1113
+ */
1114
+ humanDiffInYears(other) {
1115
+ return formatRelative(this.getLocale(), this.diffInYears(other), 'year');
1116
+ }
1117
+
1118
+ /**
1119
+ * Checks whether this DateTime is after another date.
1120
+ * @param {DateTime} other The date to compare to.
1121
+ * @return {boolean} Whether this DateTime is after the other date.
1122
+ */
1123
+ isAfter(other) {
1124
+ return this.diff(other) > 0;
1125
+ }
1126
+
1127
+ /**
1128
+ * Checks whether this DateTime is after another date (comparing by day).
1129
+ * @param {DateTime} other The date to compare to.
1130
+ * @return {boolean} Whether this DateTime is after the other date (comparing by day).
1131
+ */
1132
+ isAfterDay(other) {
1133
+ return this.diffInDays(other) > 0;
1134
+ }
1135
+
1136
+ /**
1137
+ * Checks whether this DateTime is after another date (comparing by hour).
1138
+ * @param {DateTime} other The date to compare to.
1139
+ * @return {boolean} Whether this DateTime is after the other date (comparing by hour).
1140
+ */
1141
+ isAfterHour(other) {
1142
+ return this.diffInHours(other) > 0;
1143
+ }
1144
+
1145
+ /**
1146
+ * Checks whether this DateTime is after another date (comparing by minute).
1147
+ * @param {DateTime} other The date to compare to.
1148
+ * @return {boolean} Whether this DateTime is after the other date (comparing by minute).
1149
+ */
1150
+ isAfterMinute(other) {
1151
+ return this.diffInMinutes(other) > 0;
1152
+ }
1153
+
1154
+ /**
1155
+ * Checks whether this DateTime is after another date (comparing by month).
1156
+ * @param {DateTime} other The date to compare to.
1157
+ * @return {boolean} Whether this DateTime is after the other date (comparing by month).
1158
+ */
1159
+ isAfterMonth(other) {
1160
+ return this.diffInMonths(other) > 0;
1161
+ }
1162
+
1163
+ /**
1164
+ * Checks whether this DateTime is after another date (comparing by second).
1165
+ * @param {DateTime} other The date to compare to.
1166
+ * @return {boolean} Whether this DateTime is after the other date (comparing by second).
1167
+ */
1168
+ isAfterSecond(other) {
1169
+ return this.diffInSeconds(other) > 0;
1170
+ }
1171
+
1172
+ /**
1173
+ * Checks whether this DateTime is after another date (comparing by week).
1174
+ * @param {DateTime} other The date to compare to.
1175
+ * @return {boolean} Whether this DateTime is after the other date (comparing by week).
1176
+ */
1177
+ isAfterWeek(other) {
1178
+ return this.diffInWeeks(other) > 0;
1179
+ }
1180
+
1181
+ /**
1182
+ * Checks whether this DateTime is after another date (comparing by year).
1183
+ * @param {DateTime} other The date to compare to.
1184
+ * @return {boolean} Whether this DateTime is after the other date (comparing by year).
1185
+ */
1186
+ isAfterYear(other) {
1187
+ return this.diffInYears(other) > 0;
1188
+ }
1189
+
1190
+ /**
1191
+ * Checks whether this DateTime is before another date.
1192
+ * @param {DateTime} other The date to compare to.
1193
+ * @return {boolean} Whether this DateTime is before the other date.
1194
+ */
1195
+ isBefore(other) {
1196
+ return this.diff(other) < 0;
1197
+ }
1198
+
1199
+ /**
1200
+ * Checks whether this DateTime is before another date (comparing by day).
1201
+ * @param {DateTime} other The date to compare to.
1202
+ * @return {boolean} Whether this DateTime is before the other date (comparing by day).
1203
+ */
1204
+ isBeforeDay(other) {
1205
+ return this.diffInDays(other) < 0;
1206
+ }
1207
+
1208
+ /**
1209
+ * Checks whether this DateTime is before another date (comparing by hour).
1210
+ * @param {DateTime} other The date to compare to.
1211
+ * @return {boolean} Whether this DateTime is before the other date (comparing by hour).
1212
+ */
1213
+ isBeforeHour(other) {
1214
+ return this.diffInHours(other) < 0;
1215
+ }
1216
+
1217
+ /**
1218
+ * Checks whether this DateTime is before another date (comparing by minute).
1219
+ * @param {DateTime} other The date to compare to.
1220
+ * @return {boolean} Whether this DateTime is before the other date (comparing by minute).
1221
+ */
1222
+ isBeforeMinute(other) {
1223
+ return this.diffInMinutes(other) < 0;
1224
+ }
1225
+
1226
+ /**
1227
+ * Checks whether this DateTime is before another date (comparing by month).
1228
+ * @param {DateTime} other The date to compare to.
1229
+ * @return {boolean} Whether this DateTime is before the other date (comparing by month).
1230
+ */
1231
+ isBeforeMonth(other) {
1232
+ return this.diffInMonths(other) < 0;
1233
+ }
1234
+
1235
+ /**
1236
+ * Checks whether this DateTime is before another date (comparing by second).
1237
+ * @param {DateTime} other The date to compare to.
1238
+ * @return {boolean} Whether this DateTime is before the other date (comparing by second).
1239
+ */
1240
+ isBeforeSecond(other) {
1241
+ return this.diffInSeconds(other) < 0;
1242
+ }
1243
+
1244
+ /**
1245
+ * Checks whether this DateTime is before another date (comparing by week).
1246
+ * @param {DateTime} other The date to compare to.
1247
+ * @return {boolean} Whether this DateTime is before the other date (comparing by week).
1248
+ */
1249
+ isBeforeWeek(other) {
1250
+ return this.diffInWeeks(other) < 0;
1251
+ }
1252
+
1253
+ /**
1254
+ * Checks whether this DateTime is before another date (comparing by year).
1255
+ * @param {DateTime} other The date to compare to.
1256
+ * @return {boolean} Whether this DateTime is before the other date (comparing by year).
1257
+ */
1258
+ isBeforeYear(other) {
1259
+ return this.diffInYears(other) < 0;
1260
+ }
1261
+
1262
+ /**
1263
+ * Checks whether this DateTime is between two other dates.
1264
+ * @param {DateTime} start The first date to compare to.
1265
+ * @param {DateTime} end The second date to compare to.
1266
+ * @return {boolean} Whether this DateTime is between two other dates.
1267
+ */
1268
+ isBetween(start, end) {
1269
+ return this.isAfter(start) && this.isBefore(end);
1270
+ }
1271
+
1272
+ /**
1273
+ * Checks whether this DateTime is between two other dates (comparing by day).
1274
+ * @param {DateTime} start The first date to compare to.
1275
+ * @param {DateTime} end The second date to compare to.
1276
+ * @return {boolean} Whether this DateTime is between two other dates (comparing by day).
1277
+ */
1278
+ isBetweenDay(start, end) {
1279
+ return this.isAfterDay(start) && this.isBeforeDay(end);
1280
+ }
1281
+
1282
+ /**
1283
+ * Checks whether this DateTime is between two other dates (comparing by hour).
1284
+ * @param {DateTime} start The first date to compare to.
1285
+ * @param {DateTime} end The second date to compare to.
1286
+ * @return {boolean} Whether this DateTime is between two other dates (comparing by hour).
1287
+ */
1288
+ isBetweenHour(start, end) {
1289
+ return this.isAfterHour(start) && this.isBeforeHour(end);
1290
+ }
1291
+
1292
+ /**
1293
+ * Checks whether this DateTime is between two other dates (comparing by minute).
1294
+ * @param {DateTime} start The first date to compare to.
1295
+ * @param {DateTime} end The second date to compare to.
1296
+ * @return {boolean} Whether this DateTime is between two other dates (comparing by minute).
1297
+ */
1298
+ isBetweenMinute(start, end) {
1299
+ return this.isAfterMinute(start) && this.isBeforeMinute(end);
1300
+ }
1301
+
1302
+ /**
1303
+ * Checks whether this DateTime is between two other dates (comparing by month).
1304
+ * @param {DateTime} start The first date to compare to.
1305
+ * @param {DateTime} end The second date to compare to.
1306
+ * @return {boolean} Whether this DateTime is between two other dates (comparing by month).
1307
+ */
1308
+ isBetweenMonth(start, end) {
1309
+ return this.isAfterMonth(start) && this.isBeforeMonth(end);
1310
+ }
1311
+
1312
+ /**
1313
+ * Checks whether this DateTime is between two other dates (comparing by second).
1314
+ * @param {DateTime} start The first date to compare to.
1315
+ * @param {DateTime} end The second date to compare to.
1316
+ * @return {boolean} Whether this DateTime is between two other dates (comparing by second).
1317
+ */
1318
+ isBetweenSecond(start, end) {
1319
+ return this.isAfterSecond(start) && this.isBeforeSecond(end);
1320
+ }
1321
+
1322
+ /**
1323
+ * Checks whether this DateTime is between two other dates (comparing by week).
1324
+ * @param {DateTime} start The first date to compare to.
1325
+ * @param {DateTime} end The second date to compare to.
1326
+ * @return {boolean} Whether this DateTime is between two other dates (comparing by week).
1327
+ */
1328
+ isBetweenWeek(start, end) {
1329
+ return this.isAfterWeek(start) && this.isBeforeWeek(end);
1330
+ }
1331
+
1332
+ /**
1333
+ * Checks whether this DateTime is between two other dates (comparing by year).
1334
+ * @param {DateTime} start The first date to compare to.
1335
+ * @param {DateTime} end The second date to compare to.
1336
+ * @return {boolean} Whether this DateTime is between two other dates (comparing by year).
1337
+ */
1338
+ isBetweenYear(start, end) {
1339
+ return this.isAfterYear(start) && this.isBeforeYear(end);
1340
+ }
1341
+
1342
+ /**
1343
+ * Checks whether the DateTime is in daylight saving time.
1344
+ * @return {boolean} Whether the current time is in daylight saving time.
1345
+ */
1346
+ isDst() {
1347
+ if (!this._dynamicTz) {
1348
+ return false;
1349
+ }
1350
+
1351
+ const year = this.getYear();
1352
+ const dateA = this.constructor.fromArray([year, 1, 1], {
1353
+ timeZone: this.getTimeZone(),
1354
+ });
1355
+ const dateB = this.constructor.fromArray([year, 6, 1], {
1356
+ timeZone: this.getTimeZone(),
1357
+ });
1358
+
1359
+ return this.getTimeZoneOffset() < Math.max(dateA.getTimeZoneOffset(), dateB.getTimeZoneOffset());
1360
+ }
1361
+
1362
+ /**
1363
+ * Checks whether the year is a leap year.
1364
+ * @return {boolean} Whether the current year is a leap year.
1365
+ */
1366
+ isLeapYear() {
1367
+ return this.constructor.isLeapYear(
1368
+ this.getYear(),
1369
+ );
1370
+ }
1371
+
1372
+ /**
1373
+ * Checks whether this DateTime is the same as another date.
1374
+ * @param {DateTime} other The date to compare to.
1375
+ * @return {boolean} Whether this DateTime is the same as the other date.
1376
+ */
1377
+ isSame(other) {
1378
+ return this.diff(other) === 0;
1379
+ }
1380
+
1381
+ /**
1382
+ * Checks whether this DateTime is the same as another date (comparing by day).
1383
+ * @param {DateTime} other The date to compare to.
1384
+ * @return {boolean} Whether this DateTime is the same as the other date (comparing by day).
1385
+ */
1386
+ isSameDay(other) {
1387
+ return this.diffInDays(other) === 0;
1388
+ }
1389
+
1390
+ /**
1391
+ * Checks whether this DateTime is the same as another date (comparing by hour).
1392
+ * @param {DateTime} other The date to compare to.
1393
+ * @return {boolean} Whether this DateTime is the same as the other date (comparing by hour).
1394
+ */
1395
+ isSameHour(other) {
1396
+ return this.diffInHours(other) === 0;
1397
+ }
1398
+
1399
+ /**
1400
+ * Checks whether this DateTime is the same as another date (comparing by minute).
1401
+ * @param {DateTime} other The date to compare to.
1402
+ * @return {boolean} Whether this DateTime is the same as the other date (comparing by minute).
1403
+ */
1404
+ isSameMinute(other) {
1405
+ return this.diffInMinutes(other) === 0;
1406
+ }
1407
+
1408
+ /**
1409
+ * Checks whether this DateTime is the same as another date (comparing by month).
1410
+ * @param {DateTime} other The date to compare to.
1411
+ * @return {boolean} Whether this DateTime is the same as the other date (comparing by month).
1412
+ */
1413
+ isSameMonth(other) {
1414
+ return this.diffInMonths(other) === 0;
1415
+ }
1416
+
1417
+ /**
1418
+ * Checks whether this DateTime is the same as or after another date.
1419
+ * @param {DateTime} other The date to compare to.
1420
+ * @return {boolean} Whether this DateTime is the same as or after the other date.
1421
+ */
1422
+ isSameOrAfter(other) {
1423
+ return this.diff(other) >= 0;
1424
+ }
1425
+
1426
+ /**
1427
+ * Checks whether this DateTime is the same as or after another date (comparing by day).
1428
+ * @param {DateTime} other The date to compare to.
1429
+ * @return {boolean} Whether this DateTime is the same as or after the other date (comparing by day).
1430
+ */
1431
+ isSameOrAfterDay(other) {
1432
+ return this.diffInDays(other) >= 0;
1433
+ }
1434
+
1435
+ /**
1436
+ * Checks whether this DateTime is the same as or after another date (comparing by hour).
1437
+ * @param {DateTime} other The date to compare to.
1438
+ * @return {boolean} Whether this DateTime is the same as or after the other date (comparing by hour).
1439
+ */
1440
+ isSameOrAfterHour(other) {
1441
+ return this.diffInHours(other) >= 0;
1442
+ }
1443
+
1444
+ /**
1445
+ * Checks whether this DateTime is the same as or after another date (comparing by minute).
1446
+ * @param {DateTime} other The date to compare to.
1447
+ * @return {boolean} Whether this DateTime is the same as or after the other date (comparing by minute).
1448
+ */
1449
+ isSameOrAfterMinute(other) {
1450
+ return this.diffInMinutes(other) >= 0;
1451
+ }
1452
+
1453
+ /**
1454
+ * Checks whether this DateTime is the same as or after another date (comparing by month).
1455
+ * @param {DateTime} other The date to compare to.
1456
+ * @return {boolean} Whether this DateTime is the same as or after the other date (comparing by month).
1457
+ */
1458
+ isSameOrAfterMonth(other) {
1459
+ return this.diffInMonths(other) >= 0;
1460
+ }
1461
+
1462
+ /**
1463
+ * Checks whether this DateTime is the same as or after another date (comparing by second).
1464
+ * @param {DateTime} other The date to compare to.
1465
+ * @return {boolean} Whether this DateTime is the same as or after the other date (comparing by second).
1466
+ */
1467
+ isSameOrAfterSecond(other) {
1468
+ return this.diffInSeconds(other) >= 0;
1469
+ }
1470
+
1471
+ /**
1472
+ * Checks whether this DateTime is the same as or after another date (comparing by week).
1473
+ * @param {DateTime} other The date to compare to.
1474
+ * @return {boolean} Whether this DateTime is the same as or after the other date (comparing by week).
1475
+ */
1476
+ isSameOrAfterWeek(other) {
1477
+ return this.diffInWeeks(other) >= 0;
1478
+ }
1479
+
1480
+ /**
1481
+ * Checks whether this DateTime is the same as or after another date (comparing by year).
1482
+ * @param {DateTime} other The date to compare to.
1483
+ * @return {boolean} Whether this DateTime is the same as or after the other date (comparing by year).
1484
+ */
1485
+ isSameOrAfterYear(other) {
1486
+ return this.diffInYears(other) >= 0;
1487
+ }
1488
+
1489
+ /**
1490
+ * Checks whether this DateTime is the same as or before another date.
1491
+ * @param {DateTime} other The date to compare to.
1492
+ * @return {boolean} Whether this DateTime is the same as or before the other date.
1493
+ */
1494
+ isSameOrBefore(other) {
1495
+ return this.diff(other) <= 0;
1496
+ }
1497
+
1498
+ /**
1499
+ * Checks whether this DateTime is the same as or before another date (comparing by day).
1500
+ * @param {DateTime} other The date to compare to.
1501
+ * @return {boolean} Whether this DateTime is the same as or before the other date (comparing by day).
1502
+ */
1503
+ isSameOrBeforeDay(other) {
1504
+ return this.diffInDays(other) <= 0;
1505
+ }
1506
+
1507
+ /**
1508
+ * Checks whether this DateTime is the same as or before another date (comparing by hour).
1509
+ * @param {DateTime} other The date to compare to.
1510
+ * @return {boolean} Whether this DateTime is the same as or before the other date (comparing by hour).
1511
+ */
1512
+ isSameOrBeforeHour(other) {
1513
+ return this.diffInHours(other) <= 0;
1514
+ }
1515
+
1516
+ /**
1517
+ * Checks whether this DateTime is the same as or before another date (comparing by minute).
1518
+ * @param {DateTime} other The date to compare to.
1519
+ * @return {boolean} Whether this DateTime is the same as or before the other date (comparing by minute).
1520
+ */
1521
+ isSameOrBeforeMinute(other) {
1522
+ return this.diffInMinutes(other) <= 0;
1523
+ }
1524
+
1525
+ /**
1526
+ * Checks whether this DateTime is the same as or before another date (comparing by month).
1527
+ * @param {DateTime} other The date to compare to.
1528
+ * @return {boolean} Whether this DateTime is the same as or before the other date (comparing by month).
1529
+ */
1530
+ isSameOrBeforeMonth(other) {
1531
+ return this.diffInMonths(other) <= 0;
1532
+ }
1533
+
1534
+ /**
1535
+ * Checks whether this DateTime is the same as or before another date (comparing by second).
1536
+ * @param {DateTime} other The date to compare to.
1537
+ * @return {boolean} Whether this DateTime is the same as or before the other date (comparing by second).
1538
+ */
1539
+ isSameOrBeforeSecond(other) {
1540
+ return this.diffInSeconds(other) <= 0;
1541
+ }
1542
+
1543
+ /**
1544
+ * Checks whether this DateTime is the same as or before another date (comparing by week).
1545
+ * @param {DateTime} other The date to compare to.
1546
+ * @return {boolean} Whether this DateTime is the same as or before the other date (comparing by week).
1547
+ */
1548
+ isSameOrBeforeWeek(other) {
1549
+ return this.diffInWeeks(other) <= 0;
1550
+ }
1551
+
1552
+ /**
1553
+ * Checks whether this DateTime is the same as or before another date (comparing by year).
1554
+ * @param {DateTime} other The date to compare to.
1555
+ * @return {boolean} Whether this DateTime is the same as or before the other date (comparing by year).
1556
+ */
1557
+ isSameOrBeforeYear(other) {
1558
+ return this.diffInYears(other) <= 0;
1559
+ }
1560
+
1561
+ /**
1562
+ * Checks whether this DateTime is the same as another date (comparing by second).
1563
+ * @param {DateTime} other The date to compare to.
1564
+ * @return {boolean} Whether this DateTime is the same as the other date (comparing by second).
1565
+ */
1566
+ isSameSecond(other) {
1567
+ return this.diffInSeconds(other) === 0;
1568
+ }
1569
+
1570
+ /**
1571
+ * Checks whether this DateTime is the same as another date (comparing by week).
1572
+ * @param {DateTime} other The date to compare to.
1573
+ * @return {boolean} Whether this DateTime is the same as the other date (comparing by week).
1574
+ */
1575
+ isSameWeek(other) {
1576
+ return this.diffInWeeks(other) === 0;
1577
+ }
1578
+
1579
+ /**
1580
+ * Checks whether this DateTime is the same as another date (comparing by year).
1581
+ * @param {DateTime} other The date to compare to.
1582
+ * @return {boolean} Whether this DateTime is the same as the other date (comparing by year).
1583
+ */
1584
+ isSameYear(other) {
1585
+ return this.diffInYears(other) === 0;
1586
+ }
1587
+
1588
+ /**
1589
+ * Gets the localized month name for the current date.
1590
+ * @param {'long'|'short'|'narrow'} [type='long'] The type of month name to return.
1591
+ * @return {string} The localized month name.
1592
+ */
1593
+ monthName(type = 'long') {
1594
+ return formatMonth(this.getLocale(), this.getMonth(), type);
1595
+ }
1596
+
1597
+ /**
1598
+ * Sets the DateTime to the start of the day.
1599
+ * @return {DateTime} A new DateTime instance.
1600
+ */
1601
+ startOfDay() {
1602
+ return this.withHours(0, 0, 0, 0);
1603
+ }
1604
+
1605
+ /**
1606
+ * Sets the DateTime to the start of the hour.
1607
+ * @return {DateTime} A new DateTime instance.
1608
+ */
1609
+ startOfHour() {
1610
+ return this.withMinutes(0, 0, 0);
1611
+ }
1612
+
1613
+ /**
1614
+ * Sets the DateTime to the start of the minute.
1615
+ * @return {DateTime} A new DateTime instance.
1616
+ */
1617
+ startOfMinute() {
1618
+ return this.withSeconds(0, 0);
1619
+ }
1620
+
1621
+ /**
1622
+ * Sets the DateTime to the start of the month.
1623
+ * @return {DateTime} A new DateTime instance.
1624
+ */
1625
+ startOfMonth() {
1626
+ return this.withDate(1)
1627
+ .startOfDay();
1628
+ }
1629
+
1630
+ /**
1631
+ * Sets the DateTime to the start of the quarter.
1632
+ * @return {DateTime} A new DateTime instance.
1633
+ */
1634
+ startOfQuarter() {
1635
+ const month = this.getQuarter() * 3 - 2;
1636
+ return this.withMonth(month, 1)
1637
+ .startOfDay();
1638
+ }
1639
+
1640
+ /**
1641
+ * Sets the DateTime to the start of the second.
1642
+ * @return {DateTime} A new DateTime instance.
1643
+ */
1644
+ startOfSecond() {
1645
+ return this.withMilliseconds(0);
1646
+ }
1647
+
1648
+ /**
1649
+ * Sets the DateTime to the start of the week.
1650
+ * @return {DateTime} A new DateTime instance.
1651
+ */
1652
+ startOfWeek() {
1653
+ return this.withWeekDay(1)
1654
+ .startOfDay();
1655
+ }
1656
+
1657
+ /**
1658
+ * Sets the DateTime to the start of the year.
1659
+ * @return {DateTime} A new DateTime instance.
1660
+ */
1661
+ startOfYear() {
1662
+ return this.withMonth(1, 1)
1663
+ .startOfDay();
1664
+ }
1665
+
1666
+ /**
1667
+ * Subtracts a day from the current DateTime.
1668
+ * @return {DateTime} A new DateTime instance.
1669
+ */
1670
+ subDay() {
1671
+ return this.addDays(-1);
1672
+ }
1673
+
1674
+ /**
1675
+ * Subtracts days from the current DateTime.
1676
+ * @param {number} amount The number of days to subtract.
1677
+ * @return {DateTime} A new DateTime instance.
1678
+ */
1679
+ subDays(amount) {
1680
+ return this.addDays(-amount);
1681
+ }
1682
+
1683
+ /**
1684
+ * Subtracts an hour from the current DateTime.
1685
+ * @return {DateTime} A new DateTime instance.
1686
+ */
1687
+ subHour() {
1688
+ return this.addHours(-1);
1689
+ }
1690
+
1691
+ /**
1692
+ * Subtracts hours from the current DateTime.
1693
+ * @param {number} amount The number of hours to subtract.
1694
+ * @return {DateTime} A new DateTime instance.
1695
+ */
1696
+ subHours(amount) {
1697
+ return this.addHours(-amount);
1698
+ }
1699
+
1700
+ /**
1701
+ * Subtracts a minute from the current DateTime.
1702
+ * @return {DateTime} A new DateTime instance.
1703
+ */
1704
+ subMinute() {
1705
+ return this.addMinutes(-1);
1706
+ }
1707
+
1708
+ /**
1709
+ * Subtracts minutes from the current DateTime.
1710
+ * @param {number} amount The number of minutes to subtract.
1711
+ * @return {DateTime} A new DateTime instance.
1712
+ */
1713
+ subMinutes(amount) {
1714
+ return this.addMinutes(-amount);
1715
+ }
1716
+
1717
+ /**
1718
+ * Subtracts a month from the current DateTime.
1719
+ * @return {DateTime} A new DateTime instance.
1720
+ */
1721
+ subMonth() {
1722
+ return this.addMonths(-1);
1723
+ }
1724
+
1725
+ /**
1726
+ * Subtracts months from the current DateTime.
1727
+ * @param {number} amount The number of months to subtract.
1728
+ * @return {DateTime} A new DateTime instance.
1729
+ */
1730
+ subMonths(amount) {
1731
+ return this.addMonths(-amount);
1732
+ }
1733
+
1734
+ /**
1735
+ * Subtracts a second from the current DateTime.
1736
+ * @return {DateTime} A new DateTime instance.
1737
+ */
1738
+ subSecond() {
1739
+ return this.addSeconds(-1);
1740
+ }
1741
+
1742
+ /**
1743
+ * Subtracts seconds from the current DateTime.
1744
+ * @param {number} amount The number of seconds to subtract.
1745
+ * @return {DateTime} A new DateTime instance.
1746
+ */
1747
+ subSeconds(amount) {
1748
+ return this.addSeconds(-amount);
1749
+ }
1750
+
1751
+ /**
1752
+ * Subtracts a week from the current DateTime.
1753
+ * @return {DateTime} A new DateTime instance.
1754
+ */
1755
+ subWeek() {
1756
+ return this.addWeeks(-1);
1757
+ }
1758
+
1759
+ /**
1760
+ * Subtracts weeks from the current DateTime.
1761
+ * @param {number} amount The number of weeks to subtract.
1762
+ * @return {DateTime} A new DateTime instance.
1763
+ */
1764
+ subWeeks(amount) {
1765
+ return this.addWeeks(-amount);
1766
+ }
1767
+
1768
+ /**
1769
+ * Subtracts a year from the current DateTime.
1770
+ * @return {DateTime} A new DateTime instance.
1771
+ */
1772
+ subYear() {
1773
+ return this.addYears(-1);
1774
+ }
1775
+
1776
+ /**
1777
+ * Subtracts years from the current DateTime.
1778
+ * @param {number} amount The number of years to subtract.
1779
+ * @return {DateTime} A new DateTime instance.
1780
+ */
1781
+ subYears(amount) {
1782
+ return this.addYears(-amount);
1783
+ }
1784
+
1785
+ /**
1786
+ * Returns the primitive representation of the DateTime.
1787
+ * @param {'default'|'number'|'string'} hint The conversion hint.
1788
+ * @return {string|number} A string for default/string coercion or epoch milliseconds for numeric coercion.
1789
+ */
1790
+ [Symbol.toPrimitive](hint) {
1791
+ return hint === 'number' ?
1792
+ this.valueOf() :
1793
+ this.toString();
1794
+ }
1795
+
1796
+ /**
1797
+ * Gets the name of the current time zone.
1798
+ * @param {'long'|'short'} [type='long'] The formatting type.
1799
+ * @return {string} The name of the time zone.
1800
+ */
1801
+ timeZoneName(type = 'long') {
1802
+ return this._dynamicTz ?
1803
+ formatTimeZoneName(this.getLocale(), this.getTime(), this.getTimeZone(), type) :
1804
+ 'GMT' + formatOffset(this.getTimeZoneOffset(), true, type === 'short');
1805
+ }
1806
+
1807
+ /**
1808
+ * Formats the current date using "eee MMM dd yyyy".
1809
+ * @return {string} The formatted date string.
1810
+ */
1811
+ toDateString() {
1812
+ return this.format(formats.date);
1813
+ }
1814
+
1815
+ /**
1816
+ * Formats the current date using "yyyy-MM-dd'T'HH:mm:ss.SSSxxx".
1817
+ * @return {string} The formatted date string.
1818
+ */
1819
+ toISOString() {
1820
+ return this
1821
+ .withLocale('en')
1822
+ .withTimeZone('UTC')
1823
+ .format(formats.rfc3339_extended);
1824
+ }
1825
+
1826
+ /**
1827
+ * Returns the JSON representation of the current date.
1828
+ * @return {string|null} The ISO string for valid dates or null for invalid dates.
1829
+ */
1830
+ toJSON() {
1831
+ return this.isValid ?
1832
+ this.toISOString() :
1833
+ null;
1834
+ }
1835
+
1836
+ /**
1837
+ * Formats the current date using "eee MMM dd yyyy HH:mm:ss xx (VV)".
1838
+ * @return {string} The formatted date string.
1839
+ */
1840
+ toString() {
1841
+ return this.format(formats.string);
1842
+ }
1843
+
1844
+ /**
1845
+ * Formats the current date using "HH:mm:ss xx (VV)".
1846
+ * @return {string} The formatted date string.
1847
+ */
1848
+ toTimeString() {
1849
+ return this.format(formats.time);
1850
+ }
1851
+
1852
+ /**
1853
+ * Formats the current date in the UTC time zone using "eee MMM dd yyyy HH:mm:ss xx (VV)".
1854
+ * @return {string} The formatted date string.
1855
+ */
1856
+ toUTCString() {
1857
+ return this
1858
+ .withLocale('en')
1859
+ .withTimeZone('UTC')
1860
+ .toString();
1861
+ }
1862
+
1863
+ /**
1864
+ * Returns the number of milliseconds since the UNIX epoch.
1865
+ * @return {number} The number of milliseconds since the UNIX epoch.
1866
+ */
1867
+ valueOf() {
1868
+ return this.getTime();
1869
+ }
1870
+
1871
+ /**
1872
+ * Gets the number of weeks in the current year.
1873
+ * @return {number} The number of weeks in the current year.
1874
+ */
1875
+ weeksInYear() {
1876
+ const minDays = minimumDays(this.getLocale());
1877
+ return this.withMonth(12, 24 + minDays).getWeek();
1878
+ }
1879
+
1880
+ /**
1881
+ * Returns a copy with the date of the month changed in the current time zone.
1882
+ * @param {number} date The date of the month.
1883
+ * @return {DateTime} A new DateTime instance.
1884
+ */
1885
+ withDate(date) {
1886
+ return setOffsetTime(
1887
+ this,
1888
+ new Date(getOffsetTime(this)).setUTCDate(date),
1889
+ );
1890
+ }
1891
+
1892
+ /**
1893
+ * Returns a copy with the day of the week changed in the current time zone.
1894
+ * @param {number} day The day of the week. (0 = Sunday, 6 = Saturday)
1895
+ * @return {DateTime} A new DateTime instance.
1896
+ */
1897
+ withDay(day) {
1898
+ return setOffsetTime(
1899
+ this,
1900
+ new Date(getOffsetTime(this)).setUTCDate(
1901
+ this.getDate() -
1902
+ this.getDay() +
1903
+ parseInt(day, 10),
1904
+ ),
1905
+ );
1906
+ }
1907
+
1908
+ /**
1909
+ * Returns a copy with the day of the year changed in the current time zone.
1910
+ * @param {number} day The day of the year. (1-366)
1911
+ * @return {DateTime} A new DateTime instance.
1912
+ */
1913
+ withDayOfYear(day) {
1914
+ return setOffsetTime(
1915
+ this,
1916
+ new Date(getOffsetTime(this)).setUTCMonth(
1917
+ 0,
1918
+ day,
1919
+ ),
1920
+ );
1921
+ }
1922
+
1923
+ /**
1924
+ * Returns a copy with the hours changed in the current time zone.
1925
+ * @param {number} hours The hours. (0-23)
1926
+ * @param {number} [minutes] The minutes. (0-59)
1927
+ * @param {number} [seconds] The seconds. (0-59)
1928
+ * @param {number} [milliseconds] The milliseconds.
1929
+ * @return {DateTime} A new DateTime instance.
1930
+ */
1931
+ withHours(...args) {
1932
+ return setOffsetTime(
1933
+ this,
1934
+ new Date(getOffsetTime(this)).setUTCHours(...args),
1935
+ );
1936
+ }
1937
+
1938
+ /**
1939
+ * Returns a copy with a different locale.
1940
+ * @param {string} locale The locale to use.
1941
+ * @return {DateTime} A new DateTime instance.
1942
+ */
1943
+ withLocale(locale) {
1944
+ return new this.constructor(this.getTime(), {
1945
+ locale,
1946
+ timeZone: this._timeZone,
1947
+ });
1948
+ }
1949
+
1950
+ /**
1951
+ * Returns a copy with the milliseconds changed in the current time zone.
1952
+ * @param {number} milliseconds The milliseconds.
1953
+ * @return {DateTime} A new DateTime instance.
1954
+ */
1955
+ withMilliseconds(milliseconds) {
1956
+ return setOffsetTime(
1957
+ this,
1958
+ new Date(getOffsetTime(this)).setUTCMilliseconds(milliseconds),
1959
+ );
1960
+ }
1961
+
1962
+ /**
1963
+ * Returns a copy with the minutes changed in the current time zone.
1964
+ * @param {number} minutes The minutes. (0-59)
1965
+ * @param {number} [seconds] The seconds. (0-59)
1966
+ * @param {number} [milliseconds] The milliseconds.
1967
+ * @return {DateTime} A new DateTime instance.
1968
+ */
1969
+ withMinutes(...args) {
1970
+ return setOffsetTime(
1971
+ this,
1972
+ new Date(getOffsetTime(this)).setUTCMinutes(...args),
1973
+ );
1974
+ }
1975
+
1976
+ /**
1977
+ * Returns a copy with the month changed in the current time zone.
1978
+ * @param {number} month The month. (1-12)
1979
+ * @param {number|null} [date] The date of the month.
1980
+ * @return {DateTime} A new DateTime instance.
1981
+ */
1982
+ withMonth(month, date = null) {
1983
+ if (date === null) {
1984
+ date = this.getDate();
1985
+
1986
+ if (config.clampDates) {
1987
+ date = Math.min(
1988
+ date,
1989
+ this.constructor.daysInMonth(
1990
+ this.getYear(),
1991
+ month,
1992
+ ),
1993
+ );
1994
+ }
1995
+ }
1996
+
1997
+ return setOffsetTime(
1998
+ this,
1999
+ new Date(getOffsetTime(this)).setUTCMonth(
2000
+ month - 1,
2001
+ date,
2002
+ ),
2003
+ );
2004
+ }
2005
+
2006
+ /**
2007
+ * Returns a copy with the quarter of the year changed in the current time zone.
2008
+ * @param {number} quarter The quarter of the year. (1-4)
2009
+ * @return {DateTime} A new DateTime instance.
2010
+ */
2011
+ withQuarter(quarter) {
2012
+ return setOffsetTime(
2013
+ this,
2014
+ new Date(getOffsetTime(this)).setUTCMonth(
2015
+ quarter * 3 -
2016
+ 3,
2017
+ ),
2018
+ );
2019
+ }
2020
+
2021
+ /**
2022
+ * Returns a copy with the seconds changed in the current time zone.
2023
+ * @param {number} seconds The seconds. (0-59)
2024
+ * @param {number} [milliseconds] The milliseconds.
2025
+ * @return {DateTime} A new DateTime instance.
2026
+ */
2027
+ withSeconds(...args) {
2028
+ return setOffsetTime(
2029
+ this,
2030
+ new Date(getOffsetTime(this)).setUTCSeconds(...args),
2031
+ );
2032
+ }
2033
+
2034
+ /**
2035
+ * Returns a copy with a different epoch-millisecond value.
2036
+ * @param {number} time The number of milliseconds since the UNIX epoch.
2037
+ * @return {DateTime} A new DateTime instance.
2038
+ */
2039
+ withTime(time) {
2040
+ return new this.constructor(time, {
2041
+ locale: this._locale,
2042
+ timeZone: this._timeZone,
2043
+ });
2044
+ }
2045
+
2046
+ /**
2047
+ * Returns a copy with a different number of seconds since the UNIX epoch.
2048
+ * @param {number} timestamp The number of seconds since the UNIX epoch.
2049
+ * @return {DateTime} A new DateTime instance.
2050
+ */
2051
+ withTimestamp(timestamp) {
2052
+ return this.withTime(timestamp * 1000);
2053
+ }
2054
+
2055
+ /**
2056
+ * Returns a copy in a different time zone.
2057
+ * @param {string} timeZone The time zone to use.
2058
+ * @return {DateTime} A new DateTime instance.
2059
+ */
2060
+ withTimeZone(timeZone) {
2061
+ return new this.constructor(this.getTime(), {
2062
+ locale: this._locale,
2063
+ timeZone,
2064
+ });
2065
+ }
2066
+
2067
+ /**
2068
+ * Returns a copy with a fixed numeric UTC offset.
2069
+ * @param {number} offset The UTC offset in minutes.
2070
+ * @return {DateTime} A new DateTime instance.
2071
+ */
2072
+ withTimeZoneOffset(offset) {
2073
+ return new this.constructor(this.getTime(), {
2074
+ locale: this._locale,
2075
+ timeZone: formatOffset(offset),
2076
+ });
2077
+ }
2078
+
2079
+ /**
2080
+ * Returns a copy with the local week changed in the current time zone.
2081
+ * @param {number} week The local week.
2082
+ * @param {number|null} [day] The local day of the week. (1-7)
2083
+ * @return {DateTime} A new DateTime instance.
2084
+ */
2085
+ withWeek(week, day = null) {
2086
+ if (day === null) {
2087
+ day = this.getWeekDay();
2088
+ }
2089
+
2090
+ const minDays = minimumDays(this.getLocale());
2091
+ return this.withYear(this.getWeekYear(), 1, minDays + ((week - 1) * 7)).withWeekDay(day);
2092
+ }
2093
+
2094
+ /**
2095
+ * Returns a copy with the local day of the week changed in the current time zone.
2096
+ * @param {number} day The local day of the week. (1-7)
2097
+ * @return {DateTime} A new DateTime instance.
2098
+ */
2099
+ withWeekDay(day) {
2100
+ return setOffsetTime(
2101
+ this,
2102
+ new Date(getOffsetTime(this)).setUTCDate(
2103
+ this.getDate() -
2104
+ this.getWeekDay() +
2105
+ parseInt(day, 10),
2106
+ ),
2107
+ );
2108
+ }
2109
+
2110
+ /**
2111
+ * Returns a copy with the week day in month changed in the current time zone.
2112
+ * @param {number} week The week day in month.
2113
+ * @return {DateTime} A new DateTime instance.
2114
+ */
2115
+ withWeekDayInMonth(week) {
2116
+ return this.withDate(
2117
+ this.getDate() +
2118
+ (
2119
+ week -
2120
+ this.getWeekDayInMonth()
2121
+ ) * 7,
2122
+ );
2123
+ }
2124
+
2125
+ /**
2126
+ * Returns a copy with the week of month changed in the current time zone.
2127
+ * @param {number} week The week of month.
2128
+ * @return {DateTime} A new DateTime instance.
2129
+ */
2130
+ withWeekOfMonth(week) {
2131
+ return this.withDate(
2132
+ this.getDate() +
2133
+ (
2134
+ week -
2135
+ this.getWeekOfMonth()
2136
+ ) * 7,
2137
+ );
2138
+ }
2139
+
2140
+ /**
2141
+ * Returns a copy with the local week year changed in the current time zone.
2142
+ * @param {number} year The local week year.
2143
+ * @param {number|null} [week] The local week.
2144
+ * @param {number|null} [day] The local day of the week. (1-7)
2145
+ * @return {DateTime} A new DateTime instance.
2146
+ */
2147
+ withWeekYear(year, week = null, day = null) {
2148
+ const minDays = minimumDays(this.getLocale());
2149
+ const Constructor = this.constructor;
2150
+
2151
+ if (week === null) {
2152
+ week = Math.min(
2153
+ this.getWeek(),
2154
+ Constructor.fromArray([year, 1, minDays], {
2155
+ locale: this.getLocale(),
2156
+ timeZone: this.getTimeZone(),
2157
+ }).weeksInYear(),
2158
+ );
2159
+ }
2160
+
2161
+ if (day === null) {
2162
+ day = this.getWeekDay();
2163
+ }
2164
+
2165
+ return this.withYear(year, 1, minDays + ((week - 1) * 7)).withWeekDay(day);
2166
+ }
2167
+
2168
+ /**
2169
+ * Returns a copy with the year changed in the current time zone.
2170
+ * @param {number} year The year.
2171
+ * @param {number|null} [month] The month. (1-12)
2172
+ * @param {number|null} [date] The date of the month.
2173
+ * @return {DateTime} A new DateTime instance.
2174
+ */
2175
+ withYear(year, month = null, date = null) {
2176
+ if (month === null) {
2177
+ month = this.getMonth();
2178
+ }
2179
+
2180
+ if (date === null) {
2181
+ date = this.getDate();
2182
+
2183
+ if (config.clampDates) {
2184
+ date = Math.min(
2185
+ date,
2186
+ this.constructor.daysInMonth(
2187
+ year,
2188
+ month,
2189
+ ),
2190
+ );
2191
+ }
2192
+ }
2193
+
2194
+ return setOffsetTime(
2195
+ this,
2196
+ new Date(getOffsetTime(this)).setUTCFullYear(
2197
+ year,
2198
+ month - 1,
2199
+ date,
2200
+ ),
2201
+ );
198
2202
  }
199
2203
  }