@nmshd/runtime 2.9.1 → 2.10.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.
@@ -555,11 +555,11 @@ const content_1 = __webpack_require__(/*! @nmshd/content */ "@nmshd/content");
555
555
  const crypto_1 = __webpack_require__(/*! @nmshd/crypto */ "@nmshd/crypto");
556
556
  const transport_1 = __webpack_require__(/*! @nmshd/transport */ "@nmshd/transport");
557
557
  exports.buildInformation = {
558
- version: "2.9.1",
559
- build: "174",
560
- date: "2023-11-08T16:51:09+00:00",
561
- commit: "47dcb9c2b07e0a9dd9259c929749410be96e733b",
562
- dependencies: {"@js-soft/docdb-querytranslator":"1.1.1","@js-soft/logging-abstractions":"1.0.0","@js-soft/ts-serval":"2.0.9","@js-soft/ts-utils":"^2.3.1","@nmshd/consumption":"3.4.3","@nmshd/content":"2.7.4","@nmshd/crypto":"2.0.4","@nmshd/transport":"2.1.2","ajv":"^8.12.0","ajv-errors":"^3.0.0","ajv-formats":"^2.1.1","json-stringify-safe":"^5.0.1","lodash":"^4.17.21","luxon":"^3.4.3","qrcode":"1.5.3","reflect-metadata":"0.1.13","ts-simple-nameof":"1.3.1","typescript-ioc":"3.2.2"},
558
+ version: "2.10.0",
559
+ build: "175",
560
+ date: "2023-11-20T15:34:30+00:00",
561
+ commit: "b24d6bb0b3751226ba30efc81dad0e9adab6e97f",
562
+ dependencies: {"@js-soft/docdb-querytranslator":"1.1.2","@js-soft/logging-abstractions":"1.0.1","@js-soft/ts-serval":"2.0.10","@js-soft/ts-utils":"^2.3.3","@nmshd/consumption":"3.4.3","@nmshd/content":"2.7.4","@nmshd/crypto":"2.0.5","@nmshd/transport":"2.1.4","ajv":"^8.12.0","ajv-errors":"^3.0.0","ajv-formats":"^2.1.1","json-stringify-safe":"^5.0.1","lodash":"^4.17.21","luxon":"^3.4.4","qrcode":"1.5.3","reflect-metadata":"0.1.13","ts-simple-nameof":"1.3.1","typescript-ioc":"3.2.2"},
563
563
  libraries: {
564
564
  serval: ts_serval_1.buildInformation,
565
565
  consumption: consumption_1.buildInformation,
@@ -6351,7 +6351,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
6351
6351
  };
6352
6352
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6353
6353
  exports.QRCode = void 0;
6354
- const QRCodeLibrary = __importStar(__webpack_require__(/*! qrcode */ "./node_modules/qrcode/lib/browser.js"));
6354
+ const qrcodeLibrary = __importStar(__webpack_require__(/*! qrcode */ "./node_modules/qrcode/lib/browser.js"));
6355
6355
  class QRCode {
6356
6356
  constructor(base64) {
6357
6357
  this.base64 = base64;
@@ -6360,7 +6360,7 @@ class QRCode {
6360
6360
  return this.base64;
6361
6361
  }
6362
6362
  static async from(content, prefix) {
6363
- const dataUrl = await QRCodeLibrary.toDataURL(`nmshd://${prefix}#${content}`);
6363
+ const dataUrl = await qrcodeLibrary.toDataURL(`nmshd://${prefix}#${content}`);
6364
6364
  const base64 = dataUrl.split(",")[1];
6365
6365
  return new QRCode(base64);
6366
6366
  }
@@ -30091,6 +30091,13 @@ exports.RegisterPushNotificationTokenRequest = {
30091
30091
  },
30092
30092
  "appId": {
30093
30093
  "type": "string"
30094
+ },
30095
+ "environment": {
30096
+ "type": "string",
30097
+ "enum": [
30098
+ "Development",
30099
+ "Production"
30100
+ ]
30094
30101
  }
30095
30102
  },
30096
30103
  "required": [
@@ -36417,7 +36424,8 @@ let RegisterPushNotificationTokenUseCase = class RegisterPushNotificationTokenUs
36417
36424
  await this.accountController.registerPushNotificationToken({
36418
36425
  handle: request.handle,
36419
36426
  platform: request.platform,
36420
- appId: request.appId
36427
+ appId: request.appId,
36428
+ environment: request.environment
36421
36429
  });
36422
36430
  return ts_utils_1.Result.ok(undefined);
36423
36431
  }
@@ -71294,6 +71302,17 @@ function systemLocale() {
71294
71302
  return sysLocaleCache;
71295
71303
  }
71296
71304
  }
71305
+ let weekInfoCache = {};
71306
+ function getCachedWeekInfo(locString) {
71307
+ let data = weekInfoCache[locString];
71308
+ if (!data) {
71309
+ const locale = new Intl.Locale(locString);
71310
+ // browsers currently implement this as a property, but spec says it should be a getter function
71311
+ data = "getWeekInfo" in locale ? locale.getWeekInfo() : locale.weekInfo;
71312
+ weekInfoCache[locString] = data;
71313
+ }
71314
+ return data;
71315
+ }
71297
71316
  function parseLocaleString(localeStr) {
71298
71317
  // I really want to avoid writing a BCP 47 parser
71299
71318
  // see, e.g. https://github.com/wooorm/bcp-47
@@ -71531,6 +71550,11 @@ class PolyRelFormatter {
71531
71550
  }
71532
71551
  }
71533
71552
  }
71553
+ const fallbackWeekSettings = {
71554
+ firstDay: 1,
71555
+ minimalDays: 4,
71556
+ weekend: [6, 7]
71557
+ };
71534
71558
 
71535
71559
  /**
71536
71560
  * @private
@@ -71538,15 +71562,16 @@ class PolyRelFormatter {
71538
71562
 
71539
71563
  class Locale {
71540
71564
  static fromOpts(opts) {
71541
- return Locale.create(opts.locale, opts.numberingSystem, opts.outputCalendar, opts.defaultToEN);
71565
+ return Locale.create(opts.locale, opts.numberingSystem, opts.outputCalendar, opts.weekSettings, opts.defaultToEN);
71542
71566
  }
71543
- static create(locale, numberingSystem, outputCalendar, defaultToEN = false) {
71567
+ static create(locale, numberingSystem, outputCalendar, weekSettings, defaultToEN = false) {
71544
71568
  const specifiedLocale = locale || Settings.defaultLocale;
71545
71569
  // the system locale is useful for human readable strings but annoying for parsing/formatting known formats
71546
71570
  const localeR = specifiedLocale || (defaultToEN ? "en-US" : systemLocale());
71547
71571
  const numberingSystemR = numberingSystem || Settings.defaultNumberingSystem;
71548
71572
  const outputCalendarR = outputCalendar || Settings.defaultOutputCalendar;
71549
- return new Locale(localeR, numberingSystemR, outputCalendarR, specifiedLocale);
71573
+ const weekSettingsR = validateWeekSettings(weekSettings) || Settings.defaultWeekSettings;
71574
+ return new Locale(localeR, numberingSystemR, outputCalendarR, weekSettingsR, specifiedLocale);
71550
71575
  }
71551
71576
  static resetCache() {
71552
71577
  sysLocaleCache = null;
@@ -71557,15 +71582,17 @@ class Locale {
71557
71582
  static fromObject({
71558
71583
  locale,
71559
71584
  numberingSystem,
71560
- outputCalendar
71585
+ outputCalendar,
71586
+ weekSettings
71561
71587
  } = {}) {
71562
- return Locale.create(locale, numberingSystem, outputCalendar);
71588
+ return Locale.create(locale, numberingSystem, outputCalendar, weekSettings);
71563
71589
  }
71564
- constructor(locale, numbering, outputCalendar, specifiedLocale) {
71590
+ constructor(locale, numbering, outputCalendar, weekSettings, specifiedLocale) {
71565
71591
  const [parsedLocale, parsedNumberingSystem, parsedOutputCalendar] = parseLocaleString(locale);
71566
71592
  this.locale = parsedLocale;
71567
71593
  this.numberingSystem = numbering || parsedNumberingSystem || null;
71568
71594
  this.outputCalendar = outputCalendar || parsedOutputCalendar || null;
71595
+ this.weekSettings = weekSettings;
71569
71596
  this.intl = intlConfigString(this.locale, this.numberingSystem, this.outputCalendar);
71570
71597
  this.weekdaysCache = {
71571
71598
  format: {},
@@ -71595,7 +71622,7 @@ class Locale {
71595
71622
  if (!alts || Object.getOwnPropertyNames(alts).length === 0) {
71596
71623
  return this;
71597
71624
  } else {
71598
- return Locale.create(alts.locale || this.specifiedLocale, alts.numberingSystem || this.numberingSystem, alts.outputCalendar || this.outputCalendar, alts.defaultToEN || false);
71625
+ return Locale.create(alts.locale || this.specifiedLocale, alts.numberingSystem || this.numberingSystem, alts.outputCalendar || this.outputCalendar, validateWeekSettings(alts.weekSettings) || this.weekSettings, alts.defaultToEN || false);
71599
71626
  }
71600
71627
  }
71601
71628
  redefaultToEN(alts = {}) {
@@ -71693,6 +71720,24 @@ class Locale {
71693
71720
  isEnglish() {
71694
71721
  return this.locale === "en" || this.locale.toLowerCase() === "en-us" || new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us");
71695
71722
  }
71723
+ getWeekSettings() {
71724
+ if (this.weekSettings) {
71725
+ return this.weekSettings;
71726
+ } else if (!hasLocaleWeekInfo()) {
71727
+ return fallbackWeekSettings;
71728
+ } else {
71729
+ return getCachedWeekInfo(this.locale);
71730
+ }
71731
+ }
71732
+ getStartOfWeek() {
71733
+ return this.getWeekSettings().firstDay;
71734
+ }
71735
+ getMinDaysInFirstWeek() {
71736
+ return this.getWeekSettings().minimalDays;
71737
+ }
71738
+ getWeekendDays() {
71739
+ return this.getWeekSettings().weekend;
71740
+ }
71696
71741
  equals(other) {
71697
71742
  return this.locale === other.locale && this.numberingSystem === other.numberingSystem && this.outputCalendar === other.outputCalendar;
71698
71743
  }
@@ -71876,7 +71921,8 @@ let now = () => Date.now(),
71876
71921
  defaultNumberingSystem = null,
71877
71922
  defaultOutputCalendar = null,
71878
71923
  twoDigitCutoffYear = 60,
71879
- throwOnInvalid;
71924
+ throwOnInvalid,
71925
+ defaultWeekSettings = null;
71880
71926
 
71881
71927
  /**
71882
71928
  * 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.
@@ -71967,6 +72013,31 @@ class Settings {
71967
72013
  defaultOutputCalendar = outputCalendar;
71968
72014
  }
71969
72015
 
72016
+ /**
72017
+ * @typedef {Object} WeekSettings
72018
+ * @property {number} firstDay
72019
+ * @property {number} minimalDays
72020
+ * @property {number[]} weekend
72021
+ */
72022
+
72023
+ /**
72024
+ * @return {WeekSettings|null}
72025
+ */
72026
+ static get defaultWeekSettings() {
72027
+ return defaultWeekSettings;
72028
+ }
72029
+
72030
+ /**
72031
+ * Allows overriding the default locale week settings, i.e. the start of the week, the weekend and
72032
+ * how many days are required in the first week of a year.
72033
+ * Does not affect existing instances.
72034
+ *
72035
+ * @param {WeekSettings|null} weekSettings
72036
+ */
72037
+ static set defaultWeekSettings(weekSettings) {
72038
+ defaultWeekSettings = validateWeekSettings(weekSettings);
72039
+ }
72040
+
71970
72041
  /**
71971
72042
  * Get the cutoff year after which a string encoding a year as two digits is interpreted to occur in the current century.
71972
72043
  * @type {number}
@@ -72013,6 +72084,224 @@ class Settings {
72013
72084
  }
72014
72085
  }
72015
72086
 
72087
+ class Invalid {
72088
+ constructor(reason, explanation) {
72089
+ this.reason = reason;
72090
+ this.explanation = explanation;
72091
+ }
72092
+ toMessage() {
72093
+ if (this.explanation) {
72094
+ return `${this.reason}: ${this.explanation}`;
72095
+ } else {
72096
+ return this.reason;
72097
+ }
72098
+ }
72099
+ }
72100
+
72101
+ const nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
72102
+ leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
72103
+ function unitOutOfRange(unit, value) {
72104
+ return new Invalid("unit out of range", `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`);
72105
+ }
72106
+ function dayOfWeek(year, month, day) {
72107
+ const d = new Date(Date.UTC(year, month - 1, day));
72108
+ if (year < 100 && year >= 0) {
72109
+ d.setUTCFullYear(d.getUTCFullYear() - 1900);
72110
+ }
72111
+ const js = d.getUTCDay();
72112
+ return js === 0 ? 7 : js;
72113
+ }
72114
+ function computeOrdinal(year, month, day) {
72115
+ return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1];
72116
+ }
72117
+ function uncomputeOrdinal(year, ordinal) {
72118
+ const table = isLeapYear(year) ? leapLadder : nonLeapLadder,
72119
+ month0 = table.findIndex(i => i < ordinal),
72120
+ day = ordinal - table[month0];
72121
+ return {
72122
+ month: month0 + 1,
72123
+ day
72124
+ };
72125
+ }
72126
+ function isoWeekdayToLocal(isoWeekday, startOfWeek) {
72127
+ return (isoWeekday - startOfWeek + 7) % 7 + 1;
72128
+ }
72129
+
72130
+ /**
72131
+ * @private
72132
+ */
72133
+
72134
+ function gregorianToWeek(gregObj, minDaysInFirstWeek = 4, startOfWeek = 1) {
72135
+ const {
72136
+ year,
72137
+ month,
72138
+ day
72139
+ } = gregObj,
72140
+ ordinal = computeOrdinal(year, month, day),
72141
+ weekday = isoWeekdayToLocal(dayOfWeek(year, month, day), startOfWeek);
72142
+ let weekNumber = Math.floor((ordinal - weekday + 14 - minDaysInFirstWeek) / 7),
72143
+ weekYear;
72144
+ if (weekNumber < 1) {
72145
+ weekYear = year - 1;
72146
+ weekNumber = weeksInWeekYear(weekYear, minDaysInFirstWeek, startOfWeek);
72147
+ } else if (weekNumber > weeksInWeekYear(year, minDaysInFirstWeek, startOfWeek)) {
72148
+ weekYear = year + 1;
72149
+ weekNumber = 1;
72150
+ } else {
72151
+ weekYear = year;
72152
+ }
72153
+ return {
72154
+ weekYear,
72155
+ weekNumber,
72156
+ weekday,
72157
+ ...timeObject(gregObj)
72158
+ };
72159
+ }
72160
+ function weekToGregorian(weekData, minDaysInFirstWeek = 4, startOfWeek = 1) {
72161
+ const {
72162
+ weekYear,
72163
+ weekNumber,
72164
+ weekday
72165
+ } = weekData,
72166
+ weekdayOfJan4 = isoWeekdayToLocal(dayOfWeek(weekYear, 1, minDaysInFirstWeek), startOfWeek),
72167
+ yearInDays = daysInYear(weekYear);
72168
+ let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 7 + minDaysInFirstWeek,
72169
+ year;
72170
+ if (ordinal < 1) {
72171
+ year = weekYear - 1;
72172
+ ordinal += daysInYear(year);
72173
+ } else if (ordinal > yearInDays) {
72174
+ year = weekYear + 1;
72175
+ ordinal -= daysInYear(weekYear);
72176
+ } else {
72177
+ year = weekYear;
72178
+ }
72179
+ const {
72180
+ month,
72181
+ day
72182
+ } = uncomputeOrdinal(year, ordinal);
72183
+ return {
72184
+ year,
72185
+ month,
72186
+ day,
72187
+ ...timeObject(weekData)
72188
+ };
72189
+ }
72190
+ function gregorianToOrdinal(gregData) {
72191
+ const {
72192
+ year,
72193
+ month,
72194
+ day
72195
+ } = gregData;
72196
+ const ordinal = computeOrdinal(year, month, day);
72197
+ return {
72198
+ year,
72199
+ ordinal,
72200
+ ...timeObject(gregData)
72201
+ };
72202
+ }
72203
+ function ordinalToGregorian(ordinalData) {
72204
+ const {
72205
+ year,
72206
+ ordinal
72207
+ } = ordinalData;
72208
+ const {
72209
+ month,
72210
+ day
72211
+ } = uncomputeOrdinal(year, ordinal);
72212
+ return {
72213
+ year,
72214
+ month,
72215
+ day,
72216
+ ...timeObject(ordinalData)
72217
+ };
72218
+ }
72219
+
72220
+ /**
72221
+ * Check if local week units like localWeekday are used in obj.
72222
+ * If so, validates that they are not mixed with ISO week units and then copies them to the normal week unit properties.
72223
+ * Modifies obj in-place!
72224
+ * @param obj the object values
72225
+ */
72226
+ function usesLocalWeekValues(obj, loc) {
72227
+ const hasLocaleWeekData = !isUndefined(obj.localWeekday) || !isUndefined(obj.localWeekNumber) || !isUndefined(obj.localWeekYear);
72228
+ if (hasLocaleWeekData) {
72229
+ const hasIsoWeekData = !isUndefined(obj.weekday) || !isUndefined(obj.weekNumber) || !isUndefined(obj.weekYear);
72230
+ if (hasIsoWeekData) {
72231
+ throw new ConflictingSpecificationError("Cannot mix locale-based week fields with ISO-based week fields");
72232
+ }
72233
+ if (!isUndefined(obj.localWeekday)) obj.weekday = obj.localWeekday;
72234
+ if (!isUndefined(obj.localWeekNumber)) obj.weekNumber = obj.localWeekNumber;
72235
+ if (!isUndefined(obj.localWeekYear)) obj.weekYear = obj.localWeekYear;
72236
+ delete obj.localWeekday;
72237
+ delete obj.localWeekNumber;
72238
+ delete obj.localWeekYear;
72239
+ return {
72240
+ minDaysInFirstWeek: loc.getMinDaysInFirstWeek(),
72241
+ startOfWeek: loc.getStartOfWeek()
72242
+ };
72243
+ } else {
72244
+ return {
72245
+ minDaysInFirstWeek: 4,
72246
+ startOfWeek: 1
72247
+ };
72248
+ }
72249
+ }
72250
+ function hasInvalidWeekData(obj, minDaysInFirstWeek = 4, startOfWeek = 1) {
72251
+ const validYear = isInteger(obj.weekYear),
72252
+ validWeek = integerBetween(obj.weekNumber, 1, weeksInWeekYear(obj.weekYear, minDaysInFirstWeek, startOfWeek)),
72253
+ validWeekday = integerBetween(obj.weekday, 1, 7);
72254
+ if (!validYear) {
72255
+ return unitOutOfRange("weekYear", obj.weekYear);
72256
+ } else if (!validWeek) {
72257
+ return unitOutOfRange("week", obj.weekNumber);
72258
+ } else if (!validWeekday) {
72259
+ return unitOutOfRange("weekday", obj.weekday);
72260
+ } else return false;
72261
+ }
72262
+ function hasInvalidOrdinalData(obj) {
72263
+ const validYear = isInteger(obj.year),
72264
+ validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year));
72265
+ if (!validYear) {
72266
+ return unitOutOfRange("year", obj.year);
72267
+ } else if (!validOrdinal) {
72268
+ return unitOutOfRange("ordinal", obj.ordinal);
72269
+ } else return false;
72270
+ }
72271
+ function hasInvalidGregorianData(obj) {
72272
+ const validYear = isInteger(obj.year),
72273
+ validMonth = integerBetween(obj.month, 1, 12),
72274
+ validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month));
72275
+ if (!validYear) {
72276
+ return unitOutOfRange("year", obj.year);
72277
+ } else if (!validMonth) {
72278
+ return unitOutOfRange("month", obj.month);
72279
+ } else if (!validDay) {
72280
+ return unitOutOfRange("day", obj.day);
72281
+ } else return false;
72282
+ }
72283
+ function hasInvalidTimeData(obj) {
72284
+ const {
72285
+ hour,
72286
+ minute,
72287
+ second,
72288
+ millisecond
72289
+ } = obj;
72290
+ const validHour = integerBetween(hour, 0, 23) || hour === 24 && minute === 0 && second === 0 && millisecond === 0,
72291
+ validMinute = integerBetween(minute, 0, 59),
72292
+ validSecond = integerBetween(second, 0, 59),
72293
+ validMillisecond = integerBetween(millisecond, 0, 999);
72294
+ if (!validHour) {
72295
+ return unitOutOfRange("hour", hour);
72296
+ } else if (!validMinute) {
72297
+ return unitOutOfRange("minute", minute);
72298
+ } else if (!validSecond) {
72299
+ return unitOutOfRange("second", second);
72300
+ } else if (!validMillisecond) {
72301
+ return unitOutOfRange("millisecond", millisecond);
72302
+ } else return false;
72303
+ }
72304
+
72016
72305
  /*
72017
72306
  This is just a junk drawer, containing anything used across multiple classes.
72018
72307
  Because Luxon is small(ish), this should stay small and we won't worry about splitting
@@ -72050,6 +72339,13 @@ function hasRelative() {
72050
72339
  return false;
72051
72340
  }
72052
72341
  }
72342
+ function hasLocaleWeekInfo() {
72343
+ try {
72344
+ return typeof Intl !== "undefined" && !!Intl.Locale && ("weekInfo" in Intl.Locale.prototype || "getWeekInfo" in Intl.Locale.prototype);
72345
+ } catch (e) {
72346
+ return false;
72347
+ }
72348
+ }
72053
72349
 
72054
72350
  // OBJECTS AND ARRAYS
72055
72351
 
@@ -72080,6 +72376,22 @@ function pick(obj, keys) {
72080
72376
  function hasOwnProperty(obj, prop) {
72081
72377
  return Object.prototype.hasOwnProperty.call(obj, prop);
72082
72378
  }
72379
+ function validateWeekSettings(settings) {
72380
+ if (settings == null) {
72381
+ return null;
72382
+ } else if (typeof settings !== "object") {
72383
+ throw new InvalidArgumentError("Week settings must be an object");
72384
+ } else {
72385
+ if (!integerBetween(settings.firstDay, 1, 7) || !integerBetween(settings.minimalDays, 1, 7) || !Array.isArray(settings.weekend) || settings.weekend.some(v => !integerBetween(v, 1, 7))) {
72386
+ throw new InvalidArgumentError("Invalid week settings");
72387
+ }
72388
+ return {
72389
+ firstDay: settings.firstDay,
72390
+ minimalDays: settings.minimalDays,
72391
+ weekend: Array.from(settings.weekend)
72392
+ };
72393
+ }
72394
+ }
72083
72395
 
72084
72396
  // NUMBERS AND STRINGS
72085
72397
 
@@ -72162,11 +72474,16 @@ function objToLocalTS(obj) {
72162
72474
  }
72163
72475
  return +d;
72164
72476
  }
72165
- function weeksInWeekYear(weekYear) {
72166
- const p1 = (weekYear + Math.floor(weekYear / 4) - Math.floor(weekYear / 100) + Math.floor(weekYear / 400)) % 7,
72167
- last = weekYear - 1,
72168
- p2 = (last + Math.floor(last / 4) - Math.floor(last / 100) + Math.floor(last / 400)) % 7;
72169
- return p1 === 4 || p2 === 3 ? 53 : 52;
72477
+
72478
+ // adapted from moment.js: https://github.com/moment/moment/blob/000ac1800e620f770f4eb31b5ae908f6167b0ab2/src/lib/units/week-calendar-utils.js
72479
+ function firstWeekOffset(year, minDaysInFirstWeek, startOfWeek) {
72480
+ const fwdlw = isoWeekdayToLocal(dayOfWeek(year, 1, minDaysInFirstWeek), startOfWeek);
72481
+ return -fwdlw + minDaysInFirstWeek - 1;
72482
+ }
72483
+ function weeksInWeekYear(weekYear, minDaysInFirstWeek = 4, startOfWeek = 1) {
72484
+ const weekOffset = firstWeekOffset(weekYear, minDaysInFirstWeek, startOfWeek);
72485
+ const weekOffsetNext = firstWeekOffset(weekYear + 1, minDaysInFirstWeek, startOfWeek);
72486
+ return (daysInYear(weekYear) - weekOffset + weekOffsetNext) / 7;
72170
72487
  }
72171
72488
  function untruncateYear(year) {
72172
72489
  if (year > 99) {
@@ -72707,6 +73024,14 @@ class Formatter {
72707
73024
  return this.num(dt.weekNumber);
72708
73025
  case "WW":
72709
73026
  return this.num(dt.weekNumber, 2);
73027
+ case "n":
73028
+ return this.num(dt.localWeekNumber);
73029
+ case "nn":
73030
+ return this.num(dt.localWeekNumber, 2);
73031
+ case "ii":
73032
+ return this.num(dt.localWeekYear.toString().slice(-2), 2);
73033
+ case "iiii":
73034
+ return this.num(dt.localWeekYear, 4);
72710
73035
  case "o":
72711
73036
  return this.num(dt.ordinal);
72712
73037
  case "ooo":
@@ -72768,20 +73093,6 @@ class Formatter {
72768
73093
  }
72769
73094
  }
72770
73095
 
72771
- class Invalid {
72772
- constructor(reason, explanation) {
72773
- this.reason = reason;
72774
- this.explanation = explanation;
72775
- }
72776
- toMessage() {
72777
- if (this.explanation) {
72778
- return `${this.reason}: ${this.explanation}`;
72779
- } else {
72780
- return this.reason;
72781
- }
72782
- }
72783
- }
72784
-
72785
73096
  /*
72786
73097
  * This file handles parsing for well-specified formats. Here's how it works:
72787
73098
  * Two things go into parsing: a regex to match with and an extractor to take apart the groups in the match.
@@ -73458,9 +73769,10 @@ class Duration {
73458
73769
 
73459
73770
  /**
73460
73771
  * Returns a string representation of a Duration with all units included.
73461
- * To modify its behavior use the `listStyle` and any Intl.NumberFormat option, though `unitDisplay` is especially relevant.
73462
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
73463
- * @param opts - On option object to override the formatting. Accepts the same keys as the options parameter of the native `Int.NumberFormat` constructor, as well as `listStyle`.
73772
+ * To modify its behavior, use `listStyle` and any Intl.NumberFormat option, though `unitDisplay` is especially relevant.
73773
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
73774
+ * @param {Object} opts - Formatting options. Accepts the same keys as the options parameter of the native `Intl.NumberFormat` constructor, as well as `listStyle`.
73775
+ * @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.
73464
73776
  * @example
73465
73777
  * ```js
73466
73778
  * var dur = Duration.fromObject({ days: 1, hours: 5, minutes: 6 })
@@ -73581,6 +73893,18 @@ class Duration {
73581
73893
  return this.toISO();
73582
73894
  }
73583
73895
 
73896
+ /**
73897
+ * Returns a string representation of this Duration appropriate for the REPL.
73898
+ * @return {string}
73899
+ */
73900
+ [Symbol.for("nodejs.util.inspect.custom")]() {
73901
+ if (this.isValid) {
73902
+ return `Duration { values: ${JSON.stringify(this.values)} }`;
73903
+ } else {
73904
+ return `Duration { Invalid, reason: ${this.invalidReason} }`;
73905
+ }
73906
+ }
73907
+
73584
73908
  /**
73585
73909
  * Returns an milliseconds value of this Duration.
73586
73910
  * @return {number}
@@ -73716,7 +74040,7 @@ class Duration {
73716
74040
  * Assuming the overall value of the Duration is positive, this means:
73717
74041
  * - excessive values for lower-order units are converted to higher-order units (if possible, see first and second example)
73718
74042
  * - negative lower-order units are converted to higher order units (there must be such a higher order unit, otherwise
73719
- * the overall value would be negative, see second example)
74043
+ * the overall value would be negative, see third example)
73720
74044
  * - fractional values for higher-order units are converted to lower-order units (if possible, see fourth example)
73721
74045
  *
73722
74046
  * If the overall value is negative, the result of this method is equivalent to `this.negate().normalize().negate()`.
@@ -74174,12 +74498,22 @@ class Interval {
74174
74498
  * Unlike {@link Interval#length} this counts sections of the calendar, not periods of time, e.g. specifying 'day'
74175
74499
  * asks 'what dates are included in this interval?', not 'how many days long is this interval?'
74176
74500
  * @param {string} [unit='milliseconds'] - the unit of time to count.
74501
+ * @param {Object} opts - options
74502
+ * @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
74177
74503
  * @return {number}
74178
74504
  */
74179
- count(unit = "milliseconds") {
74505
+ count(unit = "milliseconds", opts) {
74180
74506
  if (!this.isValid) return NaN;
74181
- const start = this.start.startOf(unit),
74182
- end = this.end.startOf(unit);
74507
+ const start = this.start.startOf(unit, opts);
74508
+ let end;
74509
+ if (opts != null && opts.useLocaleWeeks) {
74510
+ end = this.end.reconfigure({
74511
+ locale: start.locale
74512
+ });
74513
+ } else {
74514
+ end = this.end;
74515
+ }
74516
+ end = end.startOf(unit, opts);
74183
74517
  return Math.floor(end.diff(start, unit).get(unit)) + (end.valueOf() !== this.end.valueOf());
74184
74518
  }
74185
74519
 
@@ -74252,7 +74586,7 @@ class Interval {
74252
74586
  */
74253
74587
  splitAt(...dateTimes) {
74254
74588
  if (!this.isValid) return [];
74255
- const sorted = dateTimes.map(friendlyDateTime).filter(d => this.contains(d)).sort(),
74589
+ const sorted = dateTimes.map(friendlyDateTime).filter(d => this.contains(d)).sort((a, b) => a.toMillis() - b.toMillis()),
74256
74590
  results = [];
74257
74591
  let {
74258
74592
  s
@@ -74459,6 +74793,18 @@ class Interval {
74459
74793
  return `[${this.s.toISO()} – ${this.e.toISO()})`;
74460
74794
  }
74461
74795
 
74796
+ /**
74797
+ * Returns a string representation of this Interval appropriate for the REPL.
74798
+ * @return {string}
74799
+ */
74800
+ [Symbol.for("nodejs.util.inspect.custom")]() {
74801
+ if (this.isValid) {
74802
+ return `Interval { start: ${this.s.toISO()}, end: ${this.e.toISO()} }`;
74803
+ } else {
74804
+ return `Interval { Invalid, reason: ${this.invalidReason} }`;
74805
+ }
74806
+ }
74807
+
74462
74808
  /**
74463
74809
  * Returns a localized string representing this Interval. Accepts the same options as the
74464
74810
  * Intl.DateTimeFormat constructor and any presets defined by Luxon, such as
@@ -74609,6 +74955,50 @@ class Info {
74609
74955
  return normalizeZone(input, Settings.defaultZone);
74610
74956
  }
74611
74957
 
74958
+ /**
74959
+ * Get the weekday on which the week starts according to the given locale.
74960
+ * @param {Object} opts - options
74961
+ * @param {string} [opts.locale] - the locale code
74962
+ * @param {string} [opts.locObj=null] - an existing locale object to use
74963
+ * @returns {number} the start of the week, 1 for Monday through 7 for Sunday
74964
+ */
74965
+ static getStartOfWeek({
74966
+ locale = null,
74967
+ locObj = null
74968
+ } = {}) {
74969
+ return (locObj || Locale.create(locale)).getStartOfWeek();
74970
+ }
74971
+
74972
+ /**
74973
+ * Get the minimum number of days necessary in a week before it is considered part of the next year according
74974
+ * to the given locale.
74975
+ * @param {Object} opts - options
74976
+ * @param {string} [opts.locale] - the locale code
74977
+ * @param {string} [opts.locObj=null] - an existing locale object to use
74978
+ * @returns {number}
74979
+ */
74980
+ static getMinimumDaysInFirstWeek({
74981
+ locale = null,
74982
+ locObj = null
74983
+ } = {}) {
74984
+ return (locObj || Locale.create(locale)).getMinDaysInFirstWeek();
74985
+ }
74986
+
74987
+ /**
74988
+ * Get the weekdays, which are considered the weekend according to the given locale
74989
+ * @param {Object} opts - options
74990
+ * @param {string} [opts.locale] - the locale code
74991
+ * @param {string} [opts.locObj=null] - an existing locale object to use
74992
+ * @returns {number[]} an array of weekdays, 1 for Monday through 7 for Sunday
74993
+ */
74994
+ static getWeekendWeekdays({
74995
+ locale = null,
74996
+ locObj = null
74997
+ } = {}) {
74998
+ // copy the array, because we cache it internally
74999
+ return (locObj || Locale.create(locale)).getWeekendDays().slice();
75000
+ }
75001
+
74612
75002
  /**
74613
75003
  * Return an array of standalone month names.
74614
75004
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
@@ -74734,12 +75124,14 @@ class Info {
74734
75124
  * 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.
74735
75125
  * Keys:
74736
75126
  * * `relative`: whether this environment supports relative time formatting
74737
- * @example Info.features() //=> { relative: false }
75127
+ * * `localeWeek`: whether this environment supports different weekdays for the start of the week based on the locale
75128
+ * @example Info.features() //=> { relative: false, localeWeek: true }
74738
75129
  * @return {Object}
74739
75130
  */
74740
75131
  static features() {
74741
75132
  return {
74742
- relative: hasRelative()
75133
+ relative: hasRelative(),
75134
+ localeWeek: hasLocaleWeekInfo()
74743
75135
  };
74744
75136
  }
74745
75137
  }
@@ -75343,176 +75735,6 @@ function formatOptsToTokens(formatOpts, locale) {
75343
75735
  return parts.map(p => tokenForPart(p, formatOpts, resolvedOpts));
75344
75736
  }
75345
75737
 
75346
- const nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
75347
- leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
75348
- function unitOutOfRange(unit, value) {
75349
- return new Invalid("unit out of range", `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`);
75350
- }
75351
- function dayOfWeek(year, month, day) {
75352
- const d = new Date(Date.UTC(year, month - 1, day));
75353
- if (year < 100 && year >= 0) {
75354
- d.setUTCFullYear(d.getUTCFullYear() - 1900);
75355
- }
75356
- const js = d.getUTCDay();
75357
- return js === 0 ? 7 : js;
75358
- }
75359
- function computeOrdinal(year, month, day) {
75360
- return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1];
75361
- }
75362
- function uncomputeOrdinal(year, ordinal) {
75363
- const table = isLeapYear(year) ? leapLadder : nonLeapLadder,
75364
- month0 = table.findIndex(i => i < ordinal),
75365
- day = ordinal - table[month0];
75366
- return {
75367
- month: month0 + 1,
75368
- day
75369
- };
75370
- }
75371
-
75372
- /**
75373
- * @private
75374
- */
75375
-
75376
- function gregorianToWeek(gregObj) {
75377
- const {
75378
- year,
75379
- month,
75380
- day
75381
- } = gregObj,
75382
- ordinal = computeOrdinal(year, month, day),
75383
- weekday = dayOfWeek(year, month, day);
75384
- let weekNumber = Math.floor((ordinal - weekday + 10) / 7),
75385
- weekYear;
75386
- if (weekNumber < 1) {
75387
- weekYear = year - 1;
75388
- weekNumber = weeksInWeekYear(weekYear);
75389
- } else if (weekNumber > weeksInWeekYear(year)) {
75390
- weekYear = year + 1;
75391
- weekNumber = 1;
75392
- } else {
75393
- weekYear = year;
75394
- }
75395
- return {
75396
- weekYear,
75397
- weekNumber,
75398
- weekday,
75399
- ...timeObject(gregObj)
75400
- };
75401
- }
75402
- function weekToGregorian(weekData) {
75403
- const {
75404
- weekYear,
75405
- weekNumber,
75406
- weekday
75407
- } = weekData,
75408
- weekdayOfJan4 = dayOfWeek(weekYear, 1, 4),
75409
- yearInDays = daysInYear(weekYear);
75410
- let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 3,
75411
- year;
75412
- if (ordinal < 1) {
75413
- year = weekYear - 1;
75414
- ordinal += daysInYear(year);
75415
- } else if (ordinal > yearInDays) {
75416
- year = weekYear + 1;
75417
- ordinal -= daysInYear(weekYear);
75418
- } else {
75419
- year = weekYear;
75420
- }
75421
- const {
75422
- month,
75423
- day
75424
- } = uncomputeOrdinal(year, ordinal);
75425
- return {
75426
- year,
75427
- month,
75428
- day,
75429
- ...timeObject(weekData)
75430
- };
75431
- }
75432
- function gregorianToOrdinal(gregData) {
75433
- const {
75434
- year,
75435
- month,
75436
- day
75437
- } = gregData;
75438
- const ordinal = computeOrdinal(year, month, day);
75439
- return {
75440
- year,
75441
- ordinal,
75442
- ...timeObject(gregData)
75443
- };
75444
- }
75445
- function ordinalToGregorian(ordinalData) {
75446
- const {
75447
- year,
75448
- ordinal
75449
- } = ordinalData;
75450
- const {
75451
- month,
75452
- day
75453
- } = uncomputeOrdinal(year, ordinal);
75454
- return {
75455
- year,
75456
- month,
75457
- day,
75458
- ...timeObject(ordinalData)
75459
- };
75460
- }
75461
- function hasInvalidWeekData(obj) {
75462
- const validYear = isInteger(obj.weekYear),
75463
- validWeek = integerBetween(obj.weekNumber, 1, weeksInWeekYear(obj.weekYear)),
75464
- validWeekday = integerBetween(obj.weekday, 1, 7);
75465
- if (!validYear) {
75466
- return unitOutOfRange("weekYear", obj.weekYear);
75467
- } else if (!validWeek) {
75468
- return unitOutOfRange("week", obj.week);
75469
- } else if (!validWeekday) {
75470
- return unitOutOfRange("weekday", obj.weekday);
75471
- } else return false;
75472
- }
75473
- function hasInvalidOrdinalData(obj) {
75474
- const validYear = isInteger(obj.year),
75475
- validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year));
75476
- if (!validYear) {
75477
- return unitOutOfRange("year", obj.year);
75478
- } else if (!validOrdinal) {
75479
- return unitOutOfRange("ordinal", obj.ordinal);
75480
- } else return false;
75481
- }
75482
- function hasInvalidGregorianData(obj) {
75483
- const validYear = isInteger(obj.year),
75484
- validMonth = integerBetween(obj.month, 1, 12),
75485
- validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month));
75486
- if (!validYear) {
75487
- return unitOutOfRange("year", obj.year);
75488
- } else if (!validMonth) {
75489
- return unitOutOfRange("month", obj.month);
75490
- } else if (!validDay) {
75491
- return unitOutOfRange("day", obj.day);
75492
- } else return false;
75493
- }
75494
- function hasInvalidTimeData(obj) {
75495
- const {
75496
- hour,
75497
- minute,
75498
- second,
75499
- millisecond
75500
- } = obj;
75501
- const validHour = integerBetween(hour, 0, 23) || hour === 24 && minute === 0 && second === 0 && millisecond === 0,
75502
- validMinute = integerBetween(minute, 0, 59),
75503
- validSecond = integerBetween(second, 0, 59),
75504
- validMillisecond = integerBetween(millisecond, 0, 999);
75505
- if (!validHour) {
75506
- return unitOutOfRange("hour", hour);
75507
- } else if (!validMinute) {
75508
- return unitOutOfRange("minute", minute);
75509
- } else if (!validSecond) {
75510
- return unitOutOfRange("second", second);
75511
- } else if (!validMillisecond) {
75512
- return unitOutOfRange("millisecond", millisecond);
75513
- } else return false;
75514
- }
75515
-
75516
75738
  const INVALID = "Invalid DateTime";
75517
75739
  const MAX_DATE = 8.64e15;
75518
75740
  function unsupportedZone(zone) {
@@ -75520,6 +75742,9 @@ function unsupportedZone(zone) {
75520
75742
  }
75521
75743
 
75522
75744
  // we cache week data on the DT object and this intermediates the cache
75745
+ /**
75746
+ * @param {DateTime} dt
75747
+ */
75523
75748
  function possiblyCachedWeekData(dt) {
75524
75749
  if (dt.weekData === null) {
75525
75750
  dt.weekData = gregorianToWeek(dt.c);
@@ -75527,6 +75752,16 @@ function possiblyCachedWeekData(dt) {
75527
75752
  return dt.weekData;
75528
75753
  }
75529
75754
 
75755
+ /**
75756
+ * @param {DateTime} dt
75757
+ */
75758
+ function possiblyCachedLocalWeekData(dt) {
75759
+ if (dt.localWeekData === null) {
75760
+ dt.localWeekData = gregorianToWeek(dt.c, dt.loc.getMinDaysInFirstWeek(), dt.loc.getStartOfWeek());
75761
+ }
75762
+ return dt.localWeekData;
75763
+ }
75764
+
75530
75765
  // clone really means, "make a new object with these modifications". all "setters" really use this
75531
75766
  // to create a new object while only changing some of the properties
75532
75767
  function clone(inst, alts) {
@@ -75771,6 +76006,21 @@ function normalizeUnit(unit) {
75771
76006
  if (!normalized) throw new InvalidUnitError(unit);
75772
76007
  return normalized;
75773
76008
  }
76009
+ function normalizeUnitWithLocalWeeks(unit) {
76010
+ switch (unit.toLowerCase()) {
76011
+ case "localweekday":
76012
+ case "localweekdays":
76013
+ return "localWeekday";
76014
+ case "localweeknumber":
76015
+ case "localweeknumbers":
76016
+ return "localWeekNumber";
76017
+ case "localweekyear":
76018
+ case "localweekyears":
76019
+ return "localWeekYear";
76020
+ default:
76021
+ return normalizeUnit(unit);
76022
+ }
76023
+ }
75774
76024
 
75775
76025
  // this is a dumbed down version of fromObject() that runs about 60% faster
75776
76026
  // but doesn't do any validation, makes a bunch of assumptions about what units
@@ -75905,6 +76155,10 @@ class DateTime {
75905
76155
  * @access private
75906
76156
  */
75907
76157
  this.weekData = null;
76158
+ /**
76159
+ * @access private
76160
+ */
76161
+ this.localWeekData = null;
75908
76162
  /**
75909
76163
  * @access private
75910
76164
  */
@@ -76086,13 +76340,16 @@ class DateTime {
76086
76340
  * @param {number} obj.weekYear - an ISO week year
76087
76341
  * @param {number} obj.weekNumber - an ISO week number, between 1 and 52 or 53, depending on the year
76088
76342
  * @param {number} obj.weekday - an ISO weekday, 1-7, where 1 is Monday and 7 is Sunday
76343
+ * @param {number} obj.localWeekYear - a week year, according to the locale
76344
+ * @param {number} obj.localWeekNumber - a week number, between 1 and 52 or 53, depending on the year, according to the locale
76345
+ * @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
76089
76346
  * @param {number} obj.hour - hour of the day, 0-23
76090
76347
  * @param {number} obj.minute - minute of the hour, 0-59
76091
76348
  * @param {number} obj.second - second of the minute, 0-59
76092
76349
  * @param {number} obj.millisecond - millisecond of the second, 0-999
76093
76350
  * @param {Object} opts - options for creating this DateTime
76094
76351
  * @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()
76095
- * @param {string} [opts.locale='system's locale'] - a locale to set on the resulting DateTime instance
76352
+ * @param {string} [opts.locale='system\'s locale'] - a locale to set on the resulting DateTime instance
76096
76353
  * @param {string} opts.outputCalendar - the output calendar to set on the resulting DateTime instance
76097
76354
  * @param {string} opts.numberingSystem - the numbering system to set on the resulting DateTime instance
76098
76355
  * @example DateTime.fromObject({ year: 1982, month: 5, day: 25}).toISODate() //=> '1982-05-25'
@@ -76102,6 +76359,7 @@ class DateTime {
76102
76359
  * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'local' })
76103
76360
  * @example DateTime.fromObject({ hour: 10, minute: 26, second: 6 }, { zone: 'America/New_York' })
76104
76361
  * @example DateTime.fromObject({ weekYear: 2016, weekNumber: 2, weekday: 3 }).toISODate() //=> '2016-01-13'
76362
+ * @example DateTime.fromObject({ localWeekYear: 2022, localWeekNumber: 1, localWeekday: 1 }, { locale: "en-US" }).toISODate() //=> '2021-12-26'
76105
76363
  * @return {DateTime}
76106
76364
  */
76107
76365
  static fromObject(obj, opts = {}) {
@@ -76110,15 +76368,19 @@ class DateTime {
76110
76368
  if (!zoneToUse.isValid) {
76111
76369
  return DateTime.invalid(unsupportedZone(zoneToUse));
76112
76370
  }
76371
+ const loc = Locale.fromObject(opts);
76372
+ const normalized = normalizeObject(obj, normalizeUnitWithLocalWeeks);
76373
+ const {
76374
+ minDaysInFirstWeek,
76375
+ startOfWeek
76376
+ } = usesLocalWeekValues(normalized, loc);
76113
76377
  const tsNow = Settings.now(),
76114
76378
  offsetProvis = !isUndefined(opts.specificOffset) ? opts.specificOffset : zoneToUse.offset(tsNow),
76115
- normalized = normalizeObject(obj, normalizeUnit),
76116
76379
  containsOrdinal = !isUndefined(normalized.ordinal),
76117
76380
  containsGregorYear = !isUndefined(normalized.year),
76118
76381
  containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day),
76119
76382
  containsGregor = containsGregorYear || containsGregorMD,
76120
- definiteWeekDef = normalized.weekYear || normalized.weekNumber,
76121
- loc = Locale.fromObject(opts);
76383
+ definiteWeekDef = normalized.weekYear || normalized.weekNumber;
76122
76384
 
76123
76385
  // cases:
76124
76386
  // just a weekday -> this week's instance of that weekday, no worries
@@ -76141,7 +76403,7 @@ class DateTime {
76141
76403
  if (useWeekData) {
76142
76404
  units = orderedWeekUnits;
76143
76405
  defaultValues = defaultWeekUnitValues;
76144
- objNow = gregorianToWeek(objNow);
76406
+ objNow = gregorianToWeek(objNow, minDaysInFirstWeek, startOfWeek);
76145
76407
  } else if (containsOrdinal) {
76146
76408
  units = orderedOrdinalUnits;
76147
76409
  defaultValues = defaultOrdinalUnitValues;
@@ -76165,14 +76427,14 @@ class DateTime {
76165
76427
  }
76166
76428
 
76167
76429
  // make sure the values we have are in range
76168
- const higherOrderInvalid = useWeekData ? hasInvalidWeekData(normalized) : containsOrdinal ? hasInvalidOrdinalData(normalized) : hasInvalidGregorianData(normalized),
76430
+ const higherOrderInvalid = useWeekData ? hasInvalidWeekData(normalized, minDaysInFirstWeek, startOfWeek) : containsOrdinal ? hasInvalidOrdinalData(normalized) : hasInvalidGregorianData(normalized),
76169
76431
  invalid = higherOrderInvalid || hasInvalidTimeData(normalized);
76170
76432
  if (invalid) {
76171
76433
  return DateTime.invalid(invalid);
76172
76434
  }
76173
76435
 
76174
76436
  // compute the actual time
76175
- const gregorian = useWeekData ? weekToGregorian(normalized) : containsOrdinal ? ordinalToGregorian(normalized) : normalized,
76437
+ const gregorian = useWeekData ? weekToGregorian(normalized, minDaysInFirstWeek, startOfWeek) : containsOrdinal ? ordinalToGregorian(normalized) : normalized,
76176
76438
  [tsFinal, offsetFinal] = objToTS(gregorian, offsetProvis, zoneToUse),
76177
76439
  inst = new DateTime({
76178
76440
  ts: tsFinal,
@@ -76551,6 +76813,43 @@ class DateTime {
76551
76813
  return this.isValid ? possiblyCachedWeekData(this).weekday : NaN;
76552
76814
  }
76553
76815
 
76816
+ /**
76817
+ * Returns true if this date is on a weekend according to the locale, false otherwise
76818
+ * @returns {boolean}
76819
+ */
76820
+ get isWeekend() {
76821
+ return this.isValid && this.loc.getWeekendDays().includes(this.weekday);
76822
+ }
76823
+
76824
+ /**
76825
+ * Get the day of the week according to the locale.
76826
+ * 1 is the first day of the week and 7 is the last day of the week.
76827
+ * If the locale assigns Sunday as the first day of the week, then a date which is a Sunday will return 1,
76828
+ * @returns {number}
76829
+ */
76830
+ get localWeekday() {
76831
+ return this.isValid ? possiblyCachedLocalWeekData(this).weekday : NaN;
76832
+ }
76833
+
76834
+ /**
76835
+ * Get the week number of the week year according to the locale. Different locales assign week numbers differently,
76836
+ * because the week can start on different days of the week (see localWeekday) and because a different number of days
76837
+ * is required for a week to count as the first week of a year.
76838
+ * @returns {number}
76839
+ */
76840
+ get localWeekNumber() {
76841
+ return this.isValid ? possiblyCachedLocalWeekData(this).weekNumber : NaN;
76842
+ }
76843
+
76844
+ /**
76845
+ * Get the week year according to the locale. Different locales assign week numbers (and therefor week years)
76846
+ * differently, see localWeekNumber.
76847
+ * @returns {number}
76848
+ */
76849
+ get localWeekYear() {
76850
+ return this.isValid ? possiblyCachedLocalWeekData(this).weekYear : NaN;
76851
+ }
76852
+
76554
76853
  /**
76555
76854
  * Get the ordinal (meaning the day of the year)
76556
76855
  * @example DateTime.local(2017, 5, 25).ordinal //=> 145
@@ -76751,6 +77050,16 @@ class DateTime {
76751
77050
  return this.isValid ? weeksInWeekYear(this.weekYear) : NaN;
76752
77051
  }
76753
77052
 
77053
+ /**
77054
+ * Returns the number of weeks in this DateTime's local week year
77055
+ * @example DateTime.local(2020, 6, {locale: 'en-US'}).weeksInLocalWeekYear //=> 52
77056
+ * @example DateTime.local(2020, 6, {locale: 'de-DE'}).weeksInLocalWeekYear //=> 53
77057
+ * @type {number}
77058
+ */
77059
+ get weeksInLocalWeekYear() {
77060
+ return this.isValid ? weeksInWeekYear(this.localWeekYear, this.loc.getMinDaysInFirstWeek(), this.loc.getStartOfWeek()) : NaN;
77061
+ }
77062
+
76754
77063
  /**
76755
77064
  * Returns the resolved Intl options for this DateTime.
76756
77065
  * This is useful in understanding the behavior of formatting methods
@@ -76862,6 +77171,9 @@ class DateTime {
76862
77171
  /**
76863
77172
  * "Set" the values of specified units. Returns a newly-constructed DateTime.
76864
77173
  * You can only set units with this method; for "setting" metadata, see {@link DateTime#reconfigure} and {@link DateTime#setZone}.
77174
+ *
77175
+ * This method also supports setting locale-based week units, i.e. `localWeekday`, `localWeekNumber` and `localWeekYear`.
77176
+ * They cannot be mixed with ISO-week units like `weekday`.
76865
77177
  * @param {Object} values - a mapping of units to numbers
76866
77178
  * @example dt.set({ year: 2017 })
76867
77179
  * @example dt.set({ hour: 8, minute: 30 })
@@ -76871,8 +77183,12 @@ class DateTime {
76871
77183
  */
76872
77184
  set(values) {
76873
77185
  if (!this.isValid) return this;
76874
- const normalized = normalizeObject(values, normalizeUnit),
76875
- settingWeekStuff = !isUndefined(normalized.weekYear) || !isUndefined(normalized.weekNumber) || !isUndefined(normalized.weekday),
77186
+ const normalized = normalizeObject(values, normalizeUnitWithLocalWeeks);
77187
+ const {
77188
+ minDaysInFirstWeek,
77189
+ startOfWeek
77190
+ } = usesLocalWeekValues(normalized, this.loc);
77191
+ const settingWeekStuff = !isUndefined(normalized.weekYear) || !isUndefined(normalized.weekNumber) || !isUndefined(normalized.weekday),
76876
77192
  containsOrdinal = !isUndefined(normalized.ordinal),
76877
77193
  containsGregorYear = !isUndefined(normalized.year),
76878
77194
  containsGregorMD = !isUndefined(normalized.month) || !isUndefined(normalized.day),
@@ -76887,9 +77203,9 @@ class DateTime {
76887
77203
  let mixed;
76888
77204
  if (settingWeekStuff) {
76889
77205
  mixed = weekToGregorian({
76890
- ...gregorianToWeek(this.c),
77206
+ ...gregorianToWeek(this.c, minDaysInFirstWeek, startOfWeek),
76891
77207
  ...normalized
76892
- });
77208
+ }, minDaysInFirstWeek, startOfWeek);
76893
77209
  } else if (!isUndefined(normalized.ordinal)) {
76894
77210
  mixed = ordinalToGregorian({
76895
77211
  ...gregorianToOrdinal(this.c),
@@ -76948,6 +77264,8 @@ class DateTime {
76948
77264
  /**
76949
77265
  * "Set" this DateTime to the beginning of a unit of time.
76950
77266
  * @param {string} unit - The unit to go to the beginning of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'.
77267
+ * @param {Object} opts - options
77268
+ * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week
76951
77269
  * @example DateTime.local(2014, 3, 3).startOf('month').toISODate(); //=> '2014-03-01'
76952
77270
  * @example DateTime.local(2014, 3, 3).startOf('year').toISODate(); //=> '2014-01-01'
76953
77271
  * @example DateTime.local(2014, 3, 3).startOf('week').toISODate(); //=> '2014-03-03', weeks always start on Mondays
@@ -76955,7 +77273,9 @@ class DateTime {
76955
77273
  * @example DateTime.local(2014, 3, 3, 5, 30).startOf('hour').toISOTime(); //=> '05:00:00.000-05:00'
76956
77274
  * @return {DateTime}
76957
77275
  */
76958
- startOf(unit) {
77276
+ startOf(unit, {
77277
+ useLocaleWeeks = false
77278
+ } = {}) {
76959
77279
  if (!this.isValid) return this;
76960
77280
  const o = {},
76961
77281
  normalizedUnit = Duration.normalizeUnit(unit);
@@ -76984,7 +77304,18 @@ class DateTime {
76984
77304
  }
76985
77305
 
76986
77306
  if (normalizedUnit === "weeks") {
76987
- o.weekday = 1;
77307
+ if (useLocaleWeeks) {
77308
+ const startOfWeek = this.loc.getStartOfWeek();
77309
+ const {
77310
+ weekday
77311
+ } = this;
77312
+ if (weekday < startOfWeek) {
77313
+ o.weekNumber = this.weekNumber - 1;
77314
+ }
77315
+ o.weekday = startOfWeek;
77316
+ } else {
77317
+ o.weekday = 1;
77318
+ }
76988
77319
  }
76989
77320
  if (normalizedUnit === "quarters") {
76990
77321
  const q = Math.ceil(this.month / 3);
@@ -76996,6 +77327,8 @@ class DateTime {
76996
77327
  /**
76997
77328
  * "Set" this DateTime to the end (meaning the last millisecond) of a unit of time
76998
77329
  * @param {string} unit - The unit to go to the end of. Can be 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', or 'millisecond'.
77330
+ * @param {Object} opts - options
77331
+ * @param {boolean} [opts.useLocaleWeeks=false] - If true, use weeks based on the locale, i.e. use the locale-dependent start of the week
76999
77332
  * @example DateTime.local(2014, 3, 3).endOf('month').toISO(); //=> '2014-03-31T23:59:59.999-05:00'
77000
77333
  * @example DateTime.local(2014, 3, 3).endOf('year').toISO(); //=> '2014-12-31T23:59:59.999-05:00'
77001
77334
  * @example DateTime.local(2014, 3, 3).endOf('week').toISO(); // => '2014-03-09T23:59:59.999-05:00', weeks start on Mondays
@@ -77003,10 +77336,10 @@ class DateTime {
77003
77336
  * @example DateTime.local(2014, 3, 3, 5, 30).endOf('hour').toISO(); //=> '2014-03-03T05:59:59.999-05:00'
77004
77337
  * @return {DateTime}
77005
77338
  */
77006
- endOf(unit) {
77339
+ endOf(unit, opts) {
77007
77340
  return this.isValid ? this.plus({
77008
77341
  [unit]: 1
77009
- }).startOf(unit).minus(1) : this;
77342
+ }).startOf(unit, opts).minus(1) : this;
77010
77343
  }
77011
77344
 
77012
77345
  // OUTPUT
@@ -77246,6 +77579,18 @@ class DateTime {
77246
77579
  return this.isValid ? this.toISO() : INVALID;
77247
77580
  }
77248
77581
 
77582
+ /**
77583
+ * Returns a string representation of this DateTime appropriate for the REPL.
77584
+ * @return {string}
77585
+ */
77586
+ [Symbol.for("nodejs.util.inspect.custom")]() {
77587
+ if (this.isValid) {
77588
+ return `DateTime { ts: ${this.toISO()}, zone: ${this.zone.name}, locale: ${this.locale} }`;
77589
+ } else {
77590
+ return `DateTime { Invalid, reason: ${this.invalidReason} }`;
77591
+ }
77592
+ }
77593
+
77249
77594
  /**
77250
77595
  * Returns the epoch milliseconds of this DateTime. Alias of {@link DateTime#toMillis}
77251
77596
  * @return {number}
@@ -77383,16 +77728,18 @@ class DateTime {
77383
77728
  * 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.
77384
77729
  * @param {DateTime} otherDateTime - the other DateTime
77385
77730
  * @param {string} unit - the unit of time to check sameness on
77731
+ * @param {Object} opts - options
77732
+ * @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
77386
77733
  * @example DateTime.now().hasSame(otherDT, 'day'); //~> true if otherDT is in the same current calendar day
77387
77734
  * @return {boolean}
77388
77735
  */
77389
- hasSame(otherDateTime, unit) {
77736
+ hasSame(otherDateTime, unit, opts) {
77390
77737
  if (!this.isValid) return false;
77391
77738
  const inputMs = otherDateTime.valueOf();
77392
77739
  const adjustedToZone = this.setZone(otherDateTime.zone, {
77393
77740
  keepLocalTime: true
77394
77741
  });
77395
- return adjustedToZone.startOf(unit) <= inputMs && inputMs <= adjustedToZone.endOf(unit);
77742
+ return adjustedToZone.startOf(unit, opts) <= inputMs && inputMs <= adjustedToZone.endOf(unit, opts);
77396
77743
  }
77397
77744
 
77398
77745
  /**
@@ -77716,7 +78063,7 @@ function friendlyDateTime(dateTimeish) {
77716
78063
  }
77717
78064
  }
77718
78065
 
77719
- const VERSION = "3.4.3";
78066
+ const VERSION = "3.4.4";
77720
78067
 
77721
78068
  exports.DateTime = DateTime;
77722
78069
  exports.Duration = Duration;