@full-ui/headless-calendar 7.0.0-beta.5 → 7.0.0-beta.7

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.
@@ -100,16 +100,6 @@ interface Locale {
100
100
  options: any;
101
101
  }
102
102
 
103
- declare abstract class NamedTimeZoneImpl {
104
- timeZoneName: string;
105
- constructor(timeZoneName: string);
106
- abstract offsetForArray(a: number[]): number;
107
- abstract timestampToArray(ms: number): number[];
108
- }
109
- type NamedTimeZoneImplClass = {
110
- new (timeZoneName: string): NamedTimeZoneImpl;
111
- };
112
-
113
103
  interface ZonedMarker {
114
104
  marker: DateMarker;
115
105
  timeZoneOffset: number;
@@ -154,7 +144,6 @@ interface DateFormatter {
154
144
  type WeekNumberCalculation = 'local' | 'ISO' | ((m: Date) => number);
155
145
  interface DateEnvSettings {
156
146
  timeZone: string;
157
- namedTimeZoneImpl?: NamedTimeZoneImplClass;
158
147
  calendarSystem: string;
159
148
  locale: Locale;
160
149
  weekNumberCalculation?: WeekNumberCalculation;
@@ -168,12 +157,9 @@ type DateInput = Date | string | number | number[];
168
157
  interface DateMarkerMeta {
169
158
  marker: DateMarker;
170
159
  isTimeUnspecified: boolean;
171
- forcedTzo: number | null;
172
160
  }
173
161
  declare class DateEnv {
174
162
  timeZone: string;
175
- namedTimeZoneImpl: NamedTimeZoneImpl;
176
- canComputeOffset: boolean;
177
163
  calendarSystem: CalendarSystem;
178
164
  locale: Locale;
179
165
  weekDow: number;
@@ -190,7 +176,6 @@ declare class DateEnv {
190
176
  parse(s: string): {
191
177
  marker: Date;
192
178
  isTimeUnspecified: boolean;
193
- forcedTzo: any;
194
179
  };
195
180
  getYear(marker: DateMarker): number;
196
181
  getMonth(marker: DateMarker): number;
@@ -211,19 +196,15 @@ declare class DateEnv {
211
196
  startOfMonth(m: DateMarker): DateMarker;
212
197
  startOfWeek(m: DateMarker): DateMarker;
213
198
  computeWeekNumber(marker: DateMarker): number;
214
- format(marker: DateMarker, formatter: DateFormatter, dateOptions?: {
215
- forcedTzo?: number;
216
- }): [string, Intl.DateTimeFormatPart[]];
199
+ format(marker: DateMarker, formatter: DateFormatter): [string, Intl.DateTimeFormatPart[]];
217
200
  formatRange(start: DateMarker, end: DateMarker, formatter: DateFormatter, dateOptions?: {
218
- forcedStartTzo?: number;
219
- forcedEndTzo?: number;
220
201
  isEndExclusive?: boolean;
221
202
  defaultSeparator?: string;
222
203
  }): string;
223
204
  formatIso(marker: DateMarker, extraOptions?: any): string;
224
205
  timestampToMarker(ms: number): Date;
225
206
  offsetForMarker(m: DateMarker): number;
226
- toDate(m: DateMarker, forcedTzo?: number): Date;
207
+ toDate(m: DateMarker): Date;
227
208
  }
228
209
 
229
210
  interface DateRangeInput {
@@ -281,4 +262,4 @@ declare function isInt(n: any): boolean;
281
262
  declare function trimEnd(s: string): string;
282
263
  declare function padStart(val: any, len: any): string;
283
264
 
284
- export { CalendarSystem, CmdFormatter, CmdFormatterFunc, DateEnv, DateEnvSettings, DateFormatter, DateFormattingContext, DateInput, DateMarker, DateMarkerMeta, DateRange, DateRangeInput, Duration, DurationInput, DurationObjectInput, ExpandedZonedMarker, FuncFormatter, FuncFormatterFunc, Locale, LocaleCodeArg, NamedTimeZoneImpl, NamedTimeZoneImplClass, OpenDateRange, VerboseFormattingData, WeekNumberCalculation, ZonedMarker, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
265
+ export { CalendarSystem, CmdFormatter, CmdFormatterFunc, DateEnv, DateEnvSettings, DateFormatter, DateFormattingContext, DateInput, DateMarker, DateMarkerMeta, DateRange, DateRangeInput, Duration, DurationInput, DurationObjectInput, ExpandedZonedMarker, FuncFormatter, FuncFormatterFunc, Locale, LocaleCodeArg, OpenDateRange, VerboseFormattingData, WeekNumberCalculation, ZonedMarker, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse as parseMarker, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
@@ -1,3 +1,5 @@
1
+ import { Temporal } from 'temporal-polyfill';
2
+
1
3
  // Adding
2
4
  function addWeeks(m, n) {
3
5
  let a = dateToUtcArray(m);
@@ -564,12 +566,7 @@ function parse(str) {
564
566
  class DateEnv {
565
567
  constructor(settings) {
566
568
  var _a;
567
- let timeZone = this.timeZone = settings.timeZone;
568
- let isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
569
- if (settings.namedTimeZoneImpl && isNamedTimeZone) {
570
- this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
571
- }
572
- this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
569
+ this.timeZone = settings.timeZone;
573
570
  this.calendarSystem = createCalendarSystem(settings.calendarSystem);
574
571
  this.locale = settings.locale;
575
572
  this.weekDow = settings.locale.week.dow;
@@ -598,12 +595,7 @@ class DateEnv {
598
595
  return meta.marker;
599
596
  }
600
597
  createNowMarker() {
601
- if (this.canComputeOffset) {
602
- return this.timestampToMarker(new Date().valueOf());
603
- }
604
- // if we can't compute the current date val for a timezone,
605
- // better to give the current local date vals than UTC
606
- return arrayToUtcDate(dateToLocalArray(new Date()));
598
+ return this.timestampToMarker(new Date().valueOf());
607
599
  }
608
600
  createMarkerMeta(input) {
609
601
  if (typeof input === 'string') {
@@ -625,7 +617,7 @@ class DateEnv {
625
617
  if (marker === null || !isValidDate(marker)) {
626
618
  return null;
627
619
  }
628
- return { marker, isTimeUnspecified: false, forcedTzo: null };
620
+ return { marker, isTimeUnspecified: false };
629
621
  }
630
622
  parse(s) {
631
623
  let parts = parse(s);
@@ -633,16 +625,10 @@ class DateEnv {
633
625
  return null;
634
626
  }
635
627
  let { marker } = parts;
636
- let forcedTzo = null;
637
628
  if (parts.timeZoneOffset !== null) {
638
- if (this.canComputeOffset) {
639
- marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
640
- }
641
- else {
642
- forcedTzo = parts.timeZoneOffset;
643
- }
629
+ marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
644
630
  }
645
- return { marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo };
631
+ return { marker, isTimeUnspecified: parts.isTimeUnspecified };
646
632
  }
647
633
  // Accessors
648
634
  getYear(marker) {
@@ -807,12 +793,10 @@ class DateEnv {
807
793
  return weekOfYear(marker, this.weekDow, this.weekDoy);
808
794
  }
809
795
  // TODO: choke on timeZoneName: long
810
- format(marker, formatter, dateOptions = {}) {
796
+ format(marker, formatter) {
811
797
  return formatter.format({
812
798
  marker,
813
- timeZoneOffset: dateOptions.forcedTzo != null ?
814
- dateOptions.forcedTzo :
815
- this.offsetForMarker(marker),
799
+ timeZoneOffset: this.offsetForMarker(marker),
816
800
  }, this);
817
801
  }
818
802
  // Unlike format(), returns plain string!
@@ -822,14 +806,10 @@ class DateEnv {
822
806
  }
823
807
  return formatter.formatRange({
824
808
  marker: start,
825
- timeZoneOffset: dateOptions.forcedStartTzo != null ?
826
- dateOptions.forcedStartTzo :
827
- this.offsetForMarker(start),
809
+ timeZoneOffset: this.offsetForMarker(start),
828
810
  }, {
829
811
  marker: end,
830
- timeZoneOffset: dateOptions.forcedEndTzo != null ?
831
- dateOptions.forcedEndTzo :
832
- this.offsetForMarker(end),
812
+ timeZoneOffset: this.offsetForMarker(end),
833
813
  }, this, dateOptions.defaultSeparator);
834
814
  }
835
815
  /*
@@ -839,12 +819,7 @@ class DateEnv {
839
819
  formatIso(marker, extraOptions = {}) {
840
820
  let timeZoneOffset = null;
841
821
  if (!extraOptions.omitTimeZoneOffset) {
842
- if (extraOptions.forcedTzo != null) {
843
- timeZoneOffset = extraOptions.forcedTzo;
844
- }
845
- else {
846
- timeZoneOffset = this.offsetForMarker(marker);
847
- }
822
+ timeZoneOffset = this.offsetForMarker(marker);
848
823
  }
849
824
  return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
850
825
  }
@@ -853,10 +828,13 @@ class DateEnv {
853
828
  if (this.timeZone === 'local') {
854
829
  return arrayToUtcDate(dateToLocalArray(new Date(ms)));
855
830
  }
856
- if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
831
+ if (this.timeZone === 'UTC') {
857
832
  return new Date(ms);
858
833
  }
859
- return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
834
+ const zdt = Temporal.Instant.fromEpochMilliseconds(ms)
835
+ .toZonedDateTimeISO(this.timeZone);
836
+ return new Date(// a "Date Marker", which is like PlainDateTime
837
+ Date.UTC(zdt.year, zdt.month - 1, zdt.day, zdt.hour, zdt.minute, zdt.second, zdt.millisecond));
860
838
  }
861
839
  offsetForMarker(m) {
862
840
  if (this.timeZone === 'local') {
@@ -865,24 +843,17 @@ class DateEnv {
865
843
  if (this.timeZone === 'UTC') {
866
844
  return 0;
867
845
  }
868
- if (this.namedTimeZoneImpl) {
869
- return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
870
- }
871
- return null;
846
+ return new Temporal.PlainDateTime(m.getUTCFullYear(), m.getUTCMonth() + 1, m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes(), m.getUTCSeconds(), m.getUTCMilliseconds()).toZonedDateTime(this.timeZone).offsetNanoseconds / (1000000000 * 60);
872
847
  }
873
848
  // Conversion
874
- toDate(m, forcedTzo) {
849
+ toDate(m) {
875
850
  if (this.timeZone === 'local') {
876
851
  return arrayToLocalDate(dateToUtcArray(m));
877
852
  }
878
853
  if (this.timeZone === 'UTC') {
879
854
  return new Date(m.valueOf()); // make sure it's a copy
880
855
  }
881
- if (!this.namedTimeZoneImpl) {
882
- return new Date(m.valueOf() - (forcedTzo || 0));
883
- }
884
- return new Date(m.valueOf() -
885
- this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);
856
+ return new Date(new Temporal.PlainDateTime(m.getUTCFullYear(), m.getUTCMonth() + 1, m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes(), m.getUTCSeconds(), m.getUTCMilliseconds()).toZonedDateTime(this.timeZone).epochMilliseconds);
886
857
  }
887
858
  }
888
859
 
@@ -936,10 +907,4 @@ class FuncFormatter {
936
907
  }
937
908
  }
938
909
 
939
- class NamedTimeZoneImpl {
940
- constructor(timeZoneName) {
941
- this.timeZoneName = timeZoneName;
942
- }
943
- }
944
-
945
- export { CmdFormatter, DateEnv, FuncFormatter, NamedTimeZoneImpl, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
910
+ export { CmdFormatter, DateEnv, FuncFormatter, addDays, addDurations, addMs, addWeeks, arrayToLocalDate, arrayToUtcDate, asCleanDays, asRoughDays, asRoughHours, asRoughMinutes, asRoughMonths, asRoughMs, asRoughSeconds, asRoughYears, buildIsoString, constrainMarkerToRange, createCalendarSystem, createDuration, createVerboseFormattingArg, dateToLocalArray, dateToUtcArray, diffDayAndTime, diffDays, diffHours, diffMinutes, diffSeconds, diffWeeks, diffWholeDays, diffWholeWeeks, durationsEqual, expandZonedMarker, formatDayString, formatIsoMonthStr, formatIsoTimeString, formatTimeZoneOffset, greatestDurationDenominator, intersectRanges, invertRanges, isInt, isValidDate, joinDateTimeFormatParts, multiplyDuration, padStart, parse as parseMarker, parseRange, rangeContainsMarker, rangeContainsRange, rangesEqual, rangesIntersect, registerCalendarSystem, startOfDay, startOfHour, startOfMinute, startOfSecond, subtractDurations, timeAsMs, trimEnd, weekOfYear, wholeDivideDurations };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@full-ui/headless-calendar",
3
- "version": "7.0.0-beta.5",
3
+ "version": "7.0.0-beta.7",
4
4
  "keywords": [
5
5
  "headless",
6
6
  "calendar",
@@ -8,6 +8,9 @@
8
8
  ],
9
9
  "title": "Headless Calendar Library",
10
10
  "description": "Headless calendar library by the makers of FullCalendar",
11
+ "peerDependencies": {
12
+ "temporal-polyfill": "^0.3.0"
13
+ },
11
14
  "type": "module",
12
15
  "homepage": "https://fullcalendar.io",
13
16
  "bugs": "https://fullcalendar.io/reporting-bugs",
@@ -23,17 +26,13 @@
23
26
  "url": "http://arshaw.com/"
24
27
  },
25
28
  "copyright": "2025 Adam Shaw",
26
- "types": "./esm/index.d.ts",
27
- "module": "./esm/index.js",
28
- "main": "./cjs/index.cjs",
29
+ "types": "./index.d.ts",
30
+ "main": "./index.js",
29
31
  "exports": {
30
32
  "./package.json": "./package.json",
31
33
  ".": {
32
- "import": {
33
- "types": "./esm/index.d.ts",
34
- "default": "./esm/index.js"
35
- },
36
- "require": "./cjs/index.cjs"
34
+ "types": "./index.d.ts",
35
+ "default": "./index.js"
37
36
  }
38
37
  },
39
38
  "sideEffects": false
package/cjs/index.cjs DELETED
@@ -1,1011 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- // Adding
6
- function addWeeks(m, n) {
7
- let a = dateToUtcArray(m);
8
- a[2] += n * 7;
9
- return arrayToUtcDate(a);
10
- }
11
- function addDays(m, n) {
12
- let a = dateToUtcArray(m);
13
- a[2] += n;
14
- return arrayToUtcDate(a);
15
- }
16
- function addMs(m, n) {
17
- let a = dateToUtcArray(m);
18
- a[6] += n;
19
- return arrayToUtcDate(a);
20
- }
21
- // Diffing (all return floats)
22
- // TODO: why not use ranges?
23
- function diffWeeks(m0, m1) {
24
- return diffDays(m0, m1) / 7;
25
- }
26
- function diffDays(m0, m1) {
27
- return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
28
- }
29
- function diffHours(m0, m1) {
30
- return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
31
- }
32
- function diffMinutes(m0, m1) {
33
- return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
34
- }
35
- function diffSeconds(m0, m1) {
36
- return (m1.valueOf() - m0.valueOf()) / 1000;
37
- }
38
- function diffDayAndTime(m0, m1) {
39
- let m0day = startOfDay(m0);
40
- let m1day = startOfDay(m1);
41
- return {
42
- years: 0,
43
- months: 0,
44
- days: Math.round(diffDays(m0day, m1day)),
45
- milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()),
46
- };
47
- }
48
- // Diffing Whole Units
49
- function diffWholeWeeks(m0, m1) {
50
- let d = diffWholeDays(m0, m1);
51
- if (d !== null && d % 7 === 0) {
52
- return d / 7;
53
- }
54
- return null;
55
- }
56
- function diffWholeDays(m0, m1) {
57
- if (timeAsMs(m0) === timeAsMs(m1)) {
58
- return Math.round(diffDays(m0, m1));
59
- }
60
- return null;
61
- }
62
- // Start-Of
63
- function startOfDay(m) {
64
- return arrayToUtcDate([
65
- m.getUTCFullYear(),
66
- m.getUTCMonth(),
67
- m.getUTCDate(),
68
- ]);
69
- }
70
- function startOfHour(m) {
71
- return arrayToUtcDate([
72
- m.getUTCFullYear(),
73
- m.getUTCMonth(),
74
- m.getUTCDate(),
75
- m.getUTCHours(),
76
- ]);
77
- }
78
- function startOfMinute(m) {
79
- return arrayToUtcDate([
80
- m.getUTCFullYear(),
81
- m.getUTCMonth(),
82
- m.getUTCDate(),
83
- m.getUTCHours(),
84
- m.getUTCMinutes(),
85
- ]);
86
- }
87
- function startOfSecond(m) {
88
- return arrayToUtcDate([
89
- m.getUTCFullYear(),
90
- m.getUTCMonth(),
91
- m.getUTCDate(),
92
- m.getUTCHours(),
93
- m.getUTCMinutes(),
94
- m.getUTCSeconds(),
95
- ]);
96
- }
97
- // Week Computation
98
- function weekOfYear(marker, dow, doy) {
99
- let y = marker.getUTCFullYear();
100
- let w = weekOfGivenYear(marker, y, dow, doy);
101
- if (w < 1) {
102
- return weekOfGivenYear(marker, y - 1, dow, doy);
103
- }
104
- let nextW = weekOfGivenYear(marker, y + 1, dow, doy);
105
- if (nextW >= 1) {
106
- return Math.min(w, nextW);
107
- }
108
- return w;
109
- }
110
- function weekOfGivenYear(marker, year, dow, doy) {
111
- let firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
112
- let dayStart = startOfDay(marker);
113
- let days = Math.round(diffDays(firstWeekStart, dayStart));
114
- return Math.floor(days / 7) + 1; // zero-indexed
115
- }
116
- // start-of-first-week - start-of-year
117
- function firstWeekOffset(year, dow, doy) {
118
- // first-week day -- which january is always in the first week (4 for iso, 1 for other)
119
- let fwd = 7 + dow - doy;
120
- // first-week day local weekday -- which local weekday is fwd
121
- let fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
122
- return -fwdlw + fwd - 1;
123
- }
124
- // Array Conversion
125
- function dateToLocalArray(date) {
126
- return [
127
- date.getFullYear(),
128
- date.getMonth(),
129
- date.getDate(),
130
- date.getHours(),
131
- date.getMinutes(),
132
- date.getSeconds(),
133
- date.getMilliseconds(),
134
- ];
135
- }
136
- function arrayToLocalDate(a) {
137
- return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month
138
- a[3] || 0, a[4] || 0, a[5] || 0);
139
- }
140
- function dateToUtcArray(date) {
141
- return [
142
- date.getUTCFullYear(),
143
- date.getUTCMonth(),
144
- date.getUTCDate(),
145
- date.getUTCHours(),
146
- date.getUTCMinutes(),
147
- date.getUTCSeconds(),
148
- date.getUTCMilliseconds(),
149
- ];
150
- }
151
- function arrayToUtcDate(a) {
152
- // according to web standards (and Safari), a month index is required.
153
- // massage if only given a year.
154
- if (a.length === 1) {
155
- a = a.concat([0]);
156
- }
157
- return new Date(Date.UTC(...a));
158
- }
159
- // Other Utils
160
- function isValidDate(m) {
161
- return !isNaN(m.valueOf());
162
- }
163
- function timeAsMs(m) {
164
- return m.getUTCHours() * 1000 * 60 * 60 +
165
- m.getUTCMinutes() * 1000 * 60 +
166
- m.getUTCSeconds() * 1000 +
167
- m.getUTCMilliseconds();
168
- }
169
-
170
- let calendarSystemClassMap = {};
171
- function registerCalendarSystem(name, theClass) {
172
- calendarSystemClassMap[name] = theClass;
173
- }
174
- function createCalendarSystem(name) {
175
- return new calendarSystemClassMap[name]();
176
- }
177
- class GregorianCalendarSystem {
178
- getMarkerYear(d) {
179
- return d.getUTCFullYear();
180
- }
181
- getMarkerMonth(d) {
182
- return d.getUTCMonth();
183
- }
184
- getMarkerDay(d) {
185
- return d.getUTCDate();
186
- }
187
- arrayToMarker(arr) {
188
- return arrayToUtcDate(arr);
189
- }
190
- markerToArray(marker) {
191
- return dateToUtcArray(marker);
192
- }
193
- }
194
- registerCalendarSystem('gregory', GregorianCalendarSystem);
195
-
196
- function parseRange(input, dateEnv) {
197
- let start = null;
198
- let end = null;
199
- if (input.start) {
200
- start = dateEnv.createMarker(input.start);
201
- }
202
- if (input.end) {
203
- end = dateEnv.createMarker(input.end);
204
- }
205
- if (!start && !end) {
206
- return null;
207
- }
208
- if (start && end && end < start) {
209
- return null;
210
- }
211
- return { start, end };
212
- }
213
- // SIDE-EFFECT: will mutate ranges.
214
- // Will return a new array result.
215
- function invertRanges(ranges, constraintRange) {
216
- let invertedRanges = [];
217
- let { start } = constraintRange; // the end of the previous range. the start of the new range
218
- let i;
219
- let dateRange;
220
- // ranges need to be in order. required for our date-walking algorithm
221
- ranges.sort(compareRanges);
222
- for (i = 0; i < ranges.length; i += 1) {
223
- dateRange = ranges[i];
224
- // add the span of time before the event (if there is any)
225
- if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)
226
- invertedRanges.push({ start, end: dateRange.start });
227
- }
228
- if (dateRange.end > start) {
229
- start = dateRange.end;
230
- }
231
- }
232
- // add the span of time after the last event (if there is any)
233
- if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)
234
- invertedRanges.push({ start, end: constraintRange.end });
235
- }
236
- return invertedRanges;
237
- }
238
- function compareRanges(range0, range1) {
239
- return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
240
- }
241
- function intersectRanges(range0, range1) {
242
- let { start, end } = range0;
243
- let newRange = null;
244
- if (range1.start !== null) {
245
- if (start === null) {
246
- start = range1.start;
247
- }
248
- else {
249
- start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
250
- }
251
- }
252
- if (range1.end != null) {
253
- if (end === null) {
254
- end = range1.end;
255
- }
256
- else {
257
- end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
258
- }
259
- }
260
- if (start === null || end === null || start < end) {
261
- newRange = { start, end };
262
- }
263
- return newRange;
264
- }
265
- function rangesEqual(range0, range1) {
266
- return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
267
- (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
268
- }
269
- function rangesIntersect(range0, range1) {
270
- return (range0.end === null || range1.start === null || range0.end > range1.start) &&
271
- (range0.start === null || range1.end === null || range0.start < range1.end);
272
- }
273
- function rangeContainsRange(outerRange, innerRange) {
274
- return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
275
- (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
276
- }
277
- function rangeContainsMarker(range, date) {
278
- return (range.start === null || date >= range.start) &&
279
- (range.end === null || date < range.end);
280
- }
281
- // If the given date is not within the given range, move it inside.
282
- // (If it's past the end, make it one millisecond before the end).
283
- function constrainMarkerToRange(date, range) {
284
- if (range.start != null && date < range.start) {
285
- return range.start;
286
- }
287
- if (range.end != null && date >= range.end) {
288
- return new Date(range.end.valueOf() - 1);
289
- }
290
- return date;
291
- }
292
-
293
- function expandZonedMarker(dateInfo, calendarSystem) {
294
- let a = calendarSystem.markerToArray(dateInfo.marker);
295
- return {
296
- marker: dateInfo.marker,
297
- timeZoneOffset: dateInfo.timeZoneOffset,
298
- array: a,
299
- year: a[0],
300
- month: a[1],
301
- day: a[2],
302
- hour: a[3],
303
- minute: a[4],
304
- second: a[5],
305
- millisecond: a[6],
306
- };
307
- }
308
-
309
- function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
310
- let startInfo = expandZonedMarker(start, context.calendarSystem);
311
- let endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
312
- return {
313
- date: startInfo,
314
- start: startInfo,
315
- end: endInfo,
316
- timeZone: context.timeZone,
317
- localeCodes: context.locale.codes,
318
- defaultSeparator: betterDefaultSeparator || context.defaultSeparator,
319
- };
320
- }
321
-
322
- function isInt(n) {
323
- return n % 1 === 0;
324
- }
325
- function trimEnd(s) {
326
- return s.replace(/\s+$/, '');
327
- }
328
- function padStart(val, len) {
329
- let s = String(val);
330
- return '000'.substr(0, len - s.length) + s;
331
- }
332
-
333
- const INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
334
- const PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
335
- // Parsing and Creation
336
- function createDuration(input, unit) {
337
- if (typeof input === 'string') {
338
- return parseString(input);
339
- }
340
- if (typeof input === 'object' && input) { // non-null object
341
- return parseObject(input);
342
- }
343
- if (typeof input === 'number') {
344
- return parseObject({ [unit || 'milliseconds']: input });
345
- }
346
- return null;
347
- }
348
- function parseString(s) {
349
- let m = PARSE_RE.exec(s);
350
- if (m) {
351
- let sign = m[1] ? -1 : 1;
352
- return {
353
- years: 0,
354
- months: 0,
355
- days: sign * (m[2] ? parseInt(m[2], 10) : 0),
356
- milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours
357
- (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes
358
- (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds
359
- (m[6] ? parseInt(m[6], 10) : 0) // ms
360
- ),
361
- };
362
- }
363
- return null;
364
- }
365
- function parseObject(obj) {
366
- let duration = {
367
- years: obj.years || obj.year || 0,
368
- months: obj.months || obj.month || 0,
369
- days: obj.days || obj.day || 0,
370
- milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours
371
- (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes
372
- (obj.seconds || obj.second || 0) * 1000 + // seconds
373
- (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms
374
- };
375
- let weeks = obj.weeks || obj.week;
376
- if (weeks) {
377
- duration.days += weeks * 7;
378
- duration.specifiedWeeks = true;
379
- }
380
- return duration;
381
- }
382
- // Equality
383
- function durationsEqual(d0, d1) {
384
- return d0.years === d1.years &&
385
- d0.months === d1.months &&
386
- d0.days === d1.days &&
387
- d0.milliseconds === d1.milliseconds;
388
- }
389
- function asCleanDays(dur) {
390
- if (!dur.years && !dur.months && !dur.milliseconds) {
391
- return dur.days;
392
- }
393
- return 0;
394
- }
395
- // Simple Math
396
- function addDurations(d0, d1) {
397
- return {
398
- years: d0.years + d1.years,
399
- months: d0.months + d1.months,
400
- days: d0.days + d1.days,
401
- milliseconds: d0.milliseconds + d1.milliseconds,
402
- };
403
- }
404
- function subtractDurations(d1, d0) {
405
- return {
406
- years: d1.years - d0.years,
407
- months: d1.months - d0.months,
408
- days: d1.days - d0.days,
409
- milliseconds: d1.milliseconds - d0.milliseconds,
410
- };
411
- }
412
- function multiplyDuration(d, n) {
413
- return {
414
- years: d.years * n,
415
- months: d.months * n,
416
- days: d.days * n,
417
- milliseconds: d.milliseconds * n,
418
- };
419
- }
420
- // Conversions
421
- // "Rough" because they are based on average-case Gregorian months/years
422
- function asRoughYears(dur) {
423
- return asRoughDays(dur) / 365;
424
- }
425
- function asRoughMonths(dur) {
426
- return asRoughDays(dur) / 30;
427
- }
428
- function asRoughDays(dur) {
429
- return asRoughMs(dur) / 864e5;
430
- }
431
- function asRoughHours(dur) {
432
- return asRoughMs(dur) / (1000 * 60 * 60);
433
- }
434
- function asRoughMinutes(dur) {
435
- return asRoughMs(dur) / (1000 * 60);
436
- }
437
- function asRoughSeconds(dur) {
438
- return asRoughMs(dur) / 1000;
439
- }
440
- function asRoughMs(dur) {
441
- return dur.years * (365 * 864e5) +
442
- dur.months * (30 * 864e5) +
443
- dur.days * 864e5 +
444
- dur.milliseconds;
445
- }
446
- // Advanced Math
447
- function wholeDivideDurations(numerator, denominator) {
448
- let res = null;
449
- for (let i = 0; i < INTERNAL_UNITS.length; i += 1) {
450
- let unit = INTERNAL_UNITS[i];
451
- if (denominator[unit]) {
452
- let localRes = numerator[unit] / denominator[unit];
453
- if (!isInt(localRes) || (res !== null && res !== localRes)) {
454
- return null;
455
- }
456
- res = localRes;
457
- }
458
- else if (numerator[unit]) {
459
- // needs to divide by something but can't!
460
- return null;
461
- }
462
- }
463
- return res;
464
- }
465
- function greatestDurationDenominator(dur) {
466
- let ms = dur.milliseconds;
467
- if (ms) {
468
- if (ms % 1000 !== 0) {
469
- return { unit: 'millisecond', value: ms };
470
- }
471
- if (ms % (1000 * 60) !== 0) {
472
- return { unit: 'second', value: ms / 1000 };
473
- }
474
- if (ms % (1000 * 60 * 60) !== 0) {
475
- return { unit: 'minute', value: ms / (1000 * 60) };
476
- }
477
- if (ms) {
478
- return { unit: 'hour', value: ms / (1000 * 60 * 60) };
479
- }
480
- }
481
- if (dur.days) {
482
- if (dur.specifiedWeeks && dur.days % 7 === 0) {
483
- return { unit: 'week', value: dur.days / 7 };
484
- }
485
- return { unit: 'day', value: dur.days };
486
- }
487
- if (dur.months) {
488
- return { unit: 'month', value: dur.months };
489
- }
490
- if (dur.years) {
491
- return { unit: 'year', value: dur.years };
492
- }
493
- return { unit: 'millisecond', value: 0 };
494
- }
495
-
496
- // timeZoneOffset is in minutes
497
- function buildIsoString(marker, timeZoneOffset, stripZeroTime = false) {
498
- let s = marker.toISOString();
499
- s = s.replace('.000', '');
500
- if (stripZeroTime) {
501
- s = s.replace('T00:00:00Z', '');
502
- }
503
- if (s.length > 10) { // time part wasn't stripped, can add timezone info
504
- if (timeZoneOffset == null) {
505
- s = s.replace('Z', '');
506
- }
507
- else if (timeZoneOffset !== 0) {
508
- s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
509
- }
510
- // otherwise, its UTC-0 and we want to keep the Z
511
- }
512
- return s;
513
- }
514
- // formats the date, but with no time part
515
- // TODO: somehow merge with buildIsoString and stripZeroTime
516
- // TODO: rename. omit "string"
517
- function formatDayString(marker) {
518
- return marker.toISOString().replace(/T.*$/, '');
519
- }
520
- function formatIsoMonthStr(marker) {
521
- return marker.toISOString().match(/^\d{4}-\d{2}/)[0];
522
- }
523
- // TODO: use Date::toISOString and use everything after the T?
524
- function formatIsoTimeString(marker) {
525
- return padStart(marker.getUTCHours(), 2) + ':' +
526
- padStart(marker.getUTCMinutes(), 2) + ':' +
527
- padStart(marker.getUTCSeconds(), 2);
528
- }
529
- function formatTimeZoneOffset(minutes, doIso = false) {
530
- let sign = minutes < 0 ? '-' : '+';
531
- let abs = Math.abs(minutes);
532
- let hours = Math.floor(abs / 60);
533
- let mins = Math.round(abs % 60);
534
- if (doIso) {
535
- return `${sign + padStart(hours, 2)}:${padStart(mins, 2)}`;
536
- }
537
- return `GMT${sign}${hours}${mins ? `:${padStart(mins, 2)}` : ''}`;
538
- }
539
- function joinDateTimeFormatParts(parts) {
540
- let s = '';
541
- for (const part of parts) {
542
- s += part.value;
543
- }
544
- return s;
545
- }
546
-
547
- const ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
548
- function parse(str) {
549
- let m = ISO_RE.exec(str);
550
- if (m) {
551
- let marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number(`0.${m[12]}`) * 1000 : 0));
552
- if (isValidDate(marker)) {
553
- let timeZoneOffset = null;
554
- if (m[13]) {
555
- timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
556
- Number(m[18] || 0));
557
- }
558
- return {
559
- marker,
560
- isTimeUnspecified: !m[6],
561
- timeZoneOffset,
562
- };
563
- }
564
- }
565
- return null;
566
- }
567
-
568
- class DateEnv {
569
- constructor(settings) {
570
- var _a;
571
- let timeZone = this.timeZone = settings.timeZone;
572
- let isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
573
- if (settings.namedTimeZoneImpl && isNamedTimeZone) {
574
- this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
575
- }
576
- this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
577
- this.calendarSystem = createCalendarSystem(settings.calendarSystem);
578
- this.locale = settings.locale;
579
- this.weekDow = settings.locale.week.dow;
580
- this.weekDoy = settings.locale.week.doy;
581
- if (settings.weekNumberCalculation === 'ISO') {
582
- this.weekDow = 1;
583
- this.weekDoy = 4;
584
- }
585
- if (typeof settings.firstDay === 'number') {
586
- this.weekDow = settings.firstDay;
587
- }
588
- if (typeof settings.weekNumberCalculation === 'function') {
589
- this.weekNumberFunc = settings.weekNumberCalculation;
590
- }
591
- this.weekText = settings.weekText;
592
- this.weekTextShort = (_a = settings.weekTextShort) !== null && _a !== void 0 ? _a : settings.weekText;
593
- this.cmdFormatter = settings.cmdFormatter;
594
- this.defaultSeparator = settings.defaultSeparator;
595
- }
596
- // Creating / Parsing
597
- createMarker(input) {
598
- let meta = this.createMarkerMeta(input);
599
- if (meta === null) {
600
- return null;
601
- }
602
- return meta.marker;
603
- }
604
- createNowMarker() {
605
- if (this.canComputeOffset) {
606
- return this.timestampToMarker(new Date().valueOf());
607
- }
608
- // if we can't compute the current date val for a timezone,
609
- // better to give the current local date vals than UTC
610
- return arrayToUtcDate(dateToLocalArray(new Date()));
611
- }
612
- createMarkerMeta(input) {
613
- if (typeof input === 'string') {
614
- return this.parse(input);
615
- }
616
- let marker = null;
617
- if (typeof input === 'number') {
618
- marker = this.timestampToMarker(input);
619
- }
620
- else if (input instanceof Date) {
621
- input = input.valueOf();
622
- if (!isNaN(input)) {
623
- marker = this.timestampToMarker(input);
624
- }
625
- }
626
- else if (Array.isArray(input)) {
627
- marker = arrayToUtcDate(input);
628
- }
629
- if (marker === null || !isValidDate(marker)) {
630
- return null;
631
- }
632
- return { marker, isTimeUnspecified: false, forcedTzo: null };
633
- }
634
- parse(s) {
635
- let parts = parse(s);
636
- if (parts === null) {
637
- return null;
638
- }
639
- let { marker } = parts;
640
- let forcedTzo = null;
641
- if (parts.timeZoneOffset !== null) {
642
- if (this.canComputeOffset) {
643
- marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
644
- }
645
- else {
646
- forcedTzo = parts.timeZoneOffset;
647
- }
648
- }
649
- return { marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo };
650
- }
651
- // Accessors
652
- getYear(marker) {
653
- return this.calendarSystem.getMarkerYear(marker);
654
- }
655
- getMonth(marker) {
656
- return this.calendarSystem.getMarkerMonth(marker);
657
- }
658
- getDay(marker) {
659
- return this.calendarSystem.getMarkerDay(marker);
660
- }
661
- // Adding / Subtracting
662
- add(marker, dur) {
663
- let a = this.calendarSystem.markerToArray(marker);
664
- a[0] += dur.years;
665
- a[1] += dur.months;
666
- a[2] += dur.days;
667
- a[6] += dur.milliseconds;
668
- return this.calendarSystem.arrayToMarker(a);
669
- }
670
- subtract(marker, dur) {
671
- let a = this.calendarSystem.markerToArray(marker);
672
- a[0] -= dur.years;
673
- a[1] -= dur.months;
674
- a[2] -= dur.days;
675
- a[6] -= dur.milliseconds;
676
- return this.calendarSystem.arrayToMarker(a);
677
- }
678
- addYears(marker, n) {
679
- let a = this.calendarSystem.markerToArray(marker);
680
- a[0] += n;
681
- return this.calendarSystem.arrayToMarker(a);
682
- }
683
- addMonths(marker, n) {
684
- let a = this.calendarSystem.markerToArray(marker);
685
- a[1] += n;
686
- return this.calendarSystem.arrayToMarker(a);
687
- }
688
- // Diffing Whole Units
689
- diffWholeYears(m0, m1) {
690
- let { calendarSystem } = this;
691
- if (timeAsMs(m0) === timeAsMs(m1) &&
692
- calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
693
- calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
694
- return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
695
- }
696
- return null;
697
- }
698
- diffWholeMonths(m0, m1) {
699
- let { calendarSystem } = this;
700
- if (timeAsMs(m0) === timeAsMs(m1) &&
701
- calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
702
- return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
703
- (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
704
- }
705
- return null;
706
- }
707
- // Range / Duration
708
- greatestWholeUnit(m0, m1) {
709
- let n = this.diffWholeYears(m0, m1);
710
- if (n !== null) {
711
- return { unit: 'year', value: n };
712
- }
713
- n = this.diffWholeMonths(m0, m1);
714
- if (n !== null) {
715
- return { unit: 'month', value: n };
716
- }
717
- n = diffWholeWeeks(m0, m1);
718
- if (n !== null) {
719
- return { unit: 'week', value: n };
720
- }
721
- n = diffWholeDays(m0, m1);
722
- if (n !== null) {
723
- return { unit: 'day', value: n };
724
- }
725
- n = diffHours(m0, m1);
726
- if (isInt(n)) {
727
- return { unit: 'hour', value: n };
728
- }
729
- n = diffMinutes(m0, m1);
730
- if (isInt(n)) {
731
- return { unit: 'minute', value: n };
732
- }
733
- n = diffSeconds(m0, m1);
734
- if (isInt(n)) {
735
- return { unit: 'second', value: n };
736
- }
737
- return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
738
- }
739
- countDurationsBetween(m0, m1, d) {
740
- // TODO: can use greatestWholeUnit
741
- let diff;
742
- if (d.years) {
743
- diff = this.diffWholeYears(m0, m1);
744
- if (diff !== null) {
745
- return diff / asRoughYears(d);
746
- }
747
- }
748
- if (d.months) {
749
- diff = this.diffWholeMonths(m0, m1);
750
- if (diff !== null) {
751
- return diff / asRoughMonths(d);
752
- }
753
- }
754
- if (d.days) {
755
- diff = diffWholeDays(m0, m1);
756
- if (diff !== null) {
757
- return diff / asRoughDays(d);
758
- }
759
- }
760
- return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
761
- }
762
- // Start-Of
763
- // these DON'T return zoned-dates. only UTC start-of dates
764
- startOf(m, unit) {
765
- if (unit === 'year') {
766
- return this.startOfYear(m);
767
- }
768
- if (unit === 'month') {
769
- return this.startOfMonth(m);
770
- }
771
- if (unit === 'week') {
772
- return this.startOfWeek(m);
773
- }
774
- if (unit === 'day') {
775
- return startOfDay(m);
776
- }
777
- if (unit === 'hour') {
778
- return startOfHour(m);
779
- }
780
- if (unit === 'minute') {
781
- return startOfMinute(m);
782
- }
783
- if (unit === 'second') {
784
- return startOfSecond(m);
785
- }
786
- return null;
787
- }
788
- startOfYear(m) {
789
- return this.calendarSystem.arrayToMarker([
790
- this.calendarSystem.getMarkerYear(m),
791
- ]);
792
- }
793
- startOfMonth(m) {
794
- return this.calendarSystem.arrayToMarker([
795
- this.calendarSystem.getMarkerYear(m),
796
- this.calendarSystem.getMarkerMonth(m),
797
- ]);
798
- }
799
- startOfWeek(m) {
800
- return this.calendarSystem.arrayToMarker([
801
- this.calendarSystem.getMarkerYear(m),
802
- this.calendarSystem.getMarkerMonth(m),
803
- m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7),
804
- ]);
805
- }
806
- // Week Number
807
- computeWeekNumber(marker) {
808
- if (this.weekNumberFunc) {
809
- return this.weekNumberFunc(this.toDate(marker));
810
- }
811
- return weekOfYear(marker, this.weekDow, this.weekDoy);
812
- }
813
- // TODO: choke on timeZoneName: long
814
- format(marker, formatter, dateOptions = {}) {
815
- return formatter.format({
816
- marker,
817
- timeZoneOffset: dateOptions.forcedTzo != null ?
818
- dateOptions.forcedTzo :
819
- this.offsetForMarker(marker),
820
- }, this);
821
- }
822
- // Unlike format(), returns plain string!
823
- formatRange(start, end, formatter, dateOptions = {}) {
824
- if (dateOptions.isEndExclusive) {
825
- end = addMs(end, -1);
826
- }
827
- return formatter.formatRange({
828
- marker: start,
829
- timeZoneOffset: dateOptions.forcedStartTzo != null ?
830
- dateOptions.forcedStartTzo :
831
- this.offsetForMarker(start),
832
- }, {
833
- marker: end,
834
- timeZoneOffset: dateOptions.forcedEndTzo != null ?
835
- dateOptions.forcedEndTzo :
836
- this.offsetForMarker(end),
837
- }, this, dateOptions.defaultSeparator);
838
- }
839
- /*
840
- DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
841
- might as well use buildIsoString or some other util directly
842
- */
843
- formatIso(marker, extraOptions = {}) {
844
- let timeZoneOffset = null;
845
- if (!extraOptions.omitTimeZoneOffset) {
846
- if (extraOptions.forcedTzo != null) {
847
- timeZoneOffset = extraOptions.forcedTzo;
848
- }
849
- else {
850
- timeZoneOffset = this.offsetForMarker(marker);
851
- }
852
- }
853
- return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
854
- }
855
- // TimeZone
856
- timestampToMarker(ms) {
857
- if (this.timeZone === 'local') {
858
- return arrayToUtcDate(dateToLocalArray(new Date(ms)));
859
- }
860
- if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
861
- return new Date(ms);
862
- }
863
- return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
864
- }
865
- offsetForMarker(m) {
866
- if (this.timeZone === 'local') {
867
- return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
868
- }
869
- if (this.timeZone === 'UTC') {
870
- return 0;
871
- }
872
- if (this.namedTimeZoneImpl) {
873
- return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
874
- }
875
- return null;
876
- }
877
- // Conversion
878
- toDate(m, forcedTzo) {
879
- if (this.timeZone === 'local') {
880
- return arrayToLocalDate(dateToUtcArray(m));
881
- }
882
- if (this.timeZone === 'UTC') {
883
- return new Date(m.valueOf()); // make sure it's a copy
884
- }
885
- if (!this.namedTimeZoneImpl) {
886
- return new Date(m.valueOf() - (forcedTzo || 0));
887
- }
888
- return new Date(m.valueOf() -
889
- this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);
890
- }
891
- }
892
-
893
- /*
894
- TODO: fix the terminology of "formatter" vs "formatting func"
895
- */
896
- /*
897
- At the time of instantiation, this object does not know which cmd-formatting system it will use.
898
- It receives this at the time of formatting, as a setting.
899
- */
900
- class CmdFormatter {
901
- constructor(cmdStr) {
902
- this.cmdStr = cmdStr;
903
- }
904
- format(date, context, betterDefaultSeparator) {
905
- const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
906
- // array of parts?
907
- if (typeof res === 'object') {
908
- return [joinDateTimeFormatParts(res), res];
909
- }
910
- // otherwise, just a string
911
- return [res, [{ type: 'literal', value: res }]];
912
- }
913
- // Unlike format(), returns plain string!
914
- formatRange(start, end, context, betterDefaultSeparator) {
915
- const res = context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
916
- // array of parts?
917
- if (typeof res === 'object') {
918
- return joinDateTimeFormatParts(res);
919
- }
920
- // otherwise, just a string
921
- return res;
922
- }
923
- }
924
-
925
- class FuncFormatter {
926
- constructor(func) {
927
- this.func = func;
928
- }
929
- format(date, context, betterDefaultSeparator) {
930
- const str = this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
931
- return [
932
- str,
933
- // HACK. In future versions, allow func-formatters to return parts?
934
- [{ type: 'literal', value: str }],
935
- ];
936
- }
937
- // Unlike format(), returns plain string!
938
- formatRange(start, end, context, betterDefaultSeparator) {
939
- return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
940
- }
941
- }
942
-
943
- class NamedTimeZoneImpl {
944
- constructor(timeZoneName) {
945
- this.timeZoneName = timeZoneName;
946
- }
947
- }
948
-
949
- exports.CmdFormatter = CmdFormatter;
950
- exports.DateEnv = DateEnv;
951
- exports.FuncFormatter = FuncFormatter;
952
- exports.NamedTimeZoneImpl = NamedTimeZoneImpl;
953
- exports.addDays = addDays;
954
- exports.addDurations = addDurations;
955
- exports.addMs = addMs;
956
- exports.addWeeks = addWeeks;
957
- exports.arrayToLocalDate = arrayToLocalDate;
958
- exports.arrayToUtcDate = arrayToUtcDate;
959
- exports.asCleanDays = asCleanDays;
960
- exports.asRoughDays = asRoughDays;
961
- exports.asRoughHours = asRoughHours;
962
- exports.asRoughMinutes = asRoughMinutes;
963
- exports.asRoughMonths = asRoughMonths;
964
- exports.asRoughMs = asRoughMs;
965
- exports.asRoughSeconds = asRoughSeconds;
966
- exports.asRoughYears = asRoughYears;
967
- exports.buildIsoString = buildIsoString;
968
- exports.constrainMarkerToRange = constrainMarkerToRange;
969
- exports.createCalendarSystem = createCalendarSystem;
970
- exports.createDuration = createDuration;
971
- exports.createVerboseFormattingArg = createVerboseFormattingArg;
972
- exports.dateToLocalArray = dateToLocalArray;
973
- exports.dateToUtcArray = dateToUtcArray;
974
- exports.diffDayAndTime = diffDayAndTime;
975
- exports.diffDays = diffDays;
976
- exports.diffHours = diffHours;
977
- exports.diffMinutes = diffMinutes;
978
- exports.diffSeconds = diffSeconds;
979
- exports.diffWeeks = diffWeeks;
980
- exports.diffWholeDays = diffWholeDays;
981
- exports.diffWholeWeeks = diffWholeWeeks;
982
- exports.durationsEqual = durationsEqual;
983
- exports.expandZonedMarker = expandZonedMarker;
984
- exports.formatDayString = formatDayString;
985
- exports.formatIsoMonthStr = formatIsoMonthStr;
986
- exports.formatIsoTimeString = formatIsoTimeString;
987
- exports.formatTimeZoneOffset = formatTimeZoneOffset;
988
- exports.greatestDurationDenominator = greatestDurationDenominator;
989
- exports.intersectRanges = intersectRanges;
990
- exports.invertRanges = invertRanges;
991
- exports.isInt = isInt;
992
- exports.isValidDate = isValidDate;
993
- exports.joinDateTimeFormatParts = joinDateTimeFormatParts;
994
- exports.multiplyDuration = multiplyDuration;
995
- exports.padStart = padStart;
996
- exports.parse = parse;
997
- exports.parseRange = parseRange;
998
- exports.rangeContainsMarker = rangeContainsMarker;
999
- exports.rangeContainsRange = rangeContainsRange;
1000
- exports.rangesEqual = rangesEqual;
1001
- exports.rangesIntersect = rangesIntersect;
1002
- exports.registerCalendarSystem = registerCalendarSystem;
1003
- exports.startOfDay = startOfDay;
1004
- exports.startOfHour = startOfHour;
1005
- exports.startOfMinute = startOfMinute;
1006
- exports.startOfSecond = startOfSecond;
1007
- exports.subtractDurations = subtractDurations;
1008
- exports.timeAsMs = timeAsMs;
1009
- exports.trimEnd = trimEnd;
1010
- exports.weekOfYear = weekOfYear;
1011
- exports.wholeDivideDurations = wholeDivideDurations;