@alexstukovnikov/oz-time 1.0.0 → 1.0.2

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.
@@ -0,0 +1,277 @@
1
+ import { normalizeUnit, isFixedUnit, unitToMilliseconds } from './units.js';
2
+ import { OzTime } from '../core/core.js';
3
+
4
+ /**
5
+ * Календарные утилиты для работы с датами, високосными годами
6
+ * и разницей между значениями времени.
7
+ *
8
+ * @module utils/calendar
9
+ */
10
+
11
+ /**
12
+ * Проверяет корректность timestamp.
13
+ *
14
+ * @private
15
+ * @param {number} timestamp - Unix timestamp в миллисекундах.
16
+ * @param {string} name - Имя вызывающей функции.
17
+ * @throws {TypeError} Выбрасывается, если timestamp некорректен.
18
+ * @returns {void}
19
+ */
20
+ function assertValidTimestamp(timestamp, name) {
21
+ if (typeof timestamp !== 'number' || Number.isNaN(timestamp)) {
22
+ throw new TypeError(`${name}: timestamp must be a valid number`);
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Проверяет корректность количества единиц времени.
28
+ *
29
+ * @private
30
+ * @param {number} amount - Количество единиц времени.
31
+ * @param {string} name - Имя вызывающей функции.
32
+ * @throws {TypeError} Выбрасывается, если amount некорректен.
33
+ * @returns {void}
34
+ */
35
+ function assertValidAmount(amount, name) {
36
+ if (typeof amount !== 'number' || Number.isNaN(amount)) {
37
+ throw new TypeError(`${name}: amount must be a valid number`);
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Проверяет, является ли значение экземпляром OzTime.
43
+ *
44
+ * @private
45
+ * @param {*} value - Проверяемое значение.
46
+ * @param {string} name - Имя параметра.
47
+ * @throws {TypeError} Выбрасывается, если значение не является экземпляром OzTime.
48
+ * @returns {void}
49
+ */
50
+ function assertOzTime(value, name) {
51
+ if (!(value instanceof OzTime)) {
52
+ throw new TypeError(`${name} must be OzTime`);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Вычисляет календарную разницу в месяцах между двумя timestamp.
58
+ *
59
+ * @private
60
+ * @param {number} leftTimestamp - Левый timestamp.
61
+ * @param {number} rightTimestamp - Правый timestamp.
62
+ * @returns {number} Разница в месяцах.
63
+ */
64
+ function diffInMonths(leftTimestamp, rightTimestamp) {
65
+ const left = new Date(leftTimestamp);
66
+ const right = new Date(rightTimestamp);
67
+
68
+ let months = (left.getUTCFullYear() - right.getUTCFullYear()) * 12 + (left.getUTCMonth() - right.getUTCMonth());
69
+
70
+ const leftDay = left.getUTCDate();
71
+ const rightDay = right.getUTCDate();
72
+
73
+ if (months > 0 && leftDay < rightDay) {
74
+ months -= 1;
75
+ } else if (months < 0 && leftDay > rightDay) {
76
+ months += 1;
77
+ }
78
+
79
+ return months;
80
+ }
81
+
82
+ /**
83
+ * Вычисляет календарную разницу в годах между двумя timestamp.
84
+ *
85
+ * @private
86
+ * @param {number} leftTimestamp - Левый timestamp.
87
+ * @param {number} rightTimestamp - Правый timestamp.
88
+ * @returns {number} Разница в годах.
89
+ */
90
+ function diffInYears(leftTimestamp, rightTimestamp) {
91
+ const left = new Date(leftTimestamp);
92
+ const right = new Date(rightTimestamp);
93
+
94
+ let years = left.getUTCFullYear() - right.getUTCFullYear();
95
+
96
+ const leftMonth = left.getUTCMonth();
97
+ const rightMonth = right.getUTCMonth();
98
+ const leftDay = left.getUTCDate();
99
+ const rightDay = right.getUTCDate();
100
+
101
+ if (years > 0 && (leftMonth < rightMonth || (leftMonth === rightMonth && leftDay < rightDay))) {
102
+ years -= 1;
103
+ } else if (years < 0 && (leftMonth > rightMonth || (leftMonth === rightMonth && leftDay > rightDay))) {
104
+ years += 1;
105
+ }
106
+
107
+ return years;
108
+ }
109
+
110
+ /**
111
+ * Проверяет, является ли год високосным по григорианскому календарю.
112
+ *
113
+ * @param {number} year - Год.
114
+ * @throws {TypeError} Выбрасывается, если year не является целым числом.
115
+ * @returns {boolean} `true`, если год високосный.
116
+ * @example
117
+ * import { isLeapYear } from '@alexstukovnikov/oz-time';
118
+ *
119
+ * console.log(isLeapYear(2024)); // ожидаемый результат: true
120
+ */
121
+ export function isLeapYear(year) {
122
+ if (!Number.isInteger(year)) {
123
+ throw new TypeError('isLeapYear: year must be an integer');
124
+ }
125
+
126
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
127
+ }
128
+
129
+ /**
130
+ * Возвращает количество дней в указанном месяце указанного года.
131
+ *
132
+ * @param {number} year - Год.
133
+ * @param {number} month - Месяц от 1 до 12.
134
+ * @throws {TypeError} Выбрасывается, если year или month не являются целыми числами.
135
+ * @throws {RangeError} Выбрасывается, если month вне диапазона от 1 до 12.
136
+ * @returns {number} Количество дней в месяце.
137
+ * @example
138
+ * import { daysInMonth } from '@alexstukovnikov/oz-time';
139
+ *
140
+ * console.log(daysInMonth(2024, 2)); // ожидаемый результат: 29
141
+ */
142
+ export function daysInMonth(year, month) {
143
+ if (!Number.isInteger(year) || !Number.isInteger(month)) {
144
+ throw new TypeError('daysInMonth: year and month must be integers');
145
+ }
146
+
147
+ if (month < 1 || month > 12) {
148
+ throw new RangeError('daysInMonth: month must be between 1 and 12');
149
+ }
150
+
151
+ return new Date(Date.UTC(year, month, 0)).getUTCDate();
152
+ }
153
+
154
+ /**
155
+ * Возвращает новый timestamp, увеличенный на указанное количество
156
+ * фиксированных единиц времени.
157
+ *
158
+ * @param {number} timestamp - Unix timestamp в миллисекундах.
159
+ * @param {number} amount - Количество единиц времени.
160
+ * @param {string} unit - Фиксированная единица времени.
161
+ * @throws {TypeError} Выбрасывается, если timestamp или amount некорректны.
162
+ * @throws {Error} Выбрасывается, если unit не является фиксированной единицей.
163
+ * @returns {number} Новый Unix timestamp в миллисекундах.
164
+ * @example
165
+ * import { addByFixedUnit } from './utils/calendar.js';
166
+ *
167
+ * console.log(addByFixedUnit(1716638400000, 1, 'day')); // ожидаемый результат: 1716724800000
168
+ */
169
+ export function addByFixedUnit(timestamp, amount, unit) {
170
+ assertValidTimestamp(timestamp, 'addByFixedUnit');
171
+ assertValidAmount(amount, 'addByFixedUnit');
172
+
173
+ const normalizedUnit = normalizeUnit(unit);
174
+
175
+ if (!isFixedUnit(normalizedUnit)) {
176
+ throw new Error(`addByFixedUnit does not support calendar unit: ${unit}`);
177
+ }
178
+
179
+ return timestamp + amount * unitToMilliseconds(normalizedUnit);
180
+ }
181
+
182
+ /**
183
+ * Возвращает новый timestamp, увеличенный на указанное количество
184
+ * календарных единиц времени.
185
+ *
186
+ * Поддерживаются только `month` и `year`.
187
+ *
188
+ * @param {number} timestamp - Unix timestamp в миллисекундах.
189
+ * @param {number} amount - Количество единиц времени.
190
+ * @param {string} unit - Календарная единица времени.
191
+ * @throws {TypeError} Выбрасывается, если timestamp или amount некорректны.
192
+ * @throws {Error} Выбрасывается, если unit не поддерживается.
193
+ * @returns {number} Новый Unix timestamp в миллисекундах.
194
+ * @example
195
+ * import { addByCalendarUnit } from './utils/calendar.js';
196
+ *
197
+ * console.log(addByCalendarUnit(Date.UTC(2024, 0, 31, 0, 0, 0, 0), 1, 'month')); // ожидаемый результат: 1709164800000
198
+ */
199
+ export function addByCalendarUnit(timestamp, amount, unit) {
200
+ assertValidTimestamp(timestamp, 'addByCalendarUnit');
201
+ assertValidAmount(amount, 'addByCalendarUnit');
202
+
203
+ const normalizedUnit = normalizeUnit(unit);
204
+ const date = new Date(timestamp);
205
+
206
+ if (normalizedUnit === 'month') {
207
+ const originalDay = date.getUTCDate();
208
+
209
+ date.setUTCDate(1);
210
+ date.setUTCMonth(date.getUTCMonth() + amount);
211
+
212
+ const maxDay = daysInMonth(date.getUTCFullYear(), date.getUTCMonth() + 1);
213
+ date.setUTCDate(Math.min(originalDay, maxDay));
214
+
215
+ return date.getTime();
216
+ }
217
+
218
+ if (normalizedUnit === 'year') {
219
+ const originalMonth = date.getUTCMonth();
220
+ const originalDay = date.getUTCDate();
221
+
222
+ date.setUTCDate(1);
223
+ date.setUTCFullYear(date.getUTCFullYear() + amount);
224
+ date.setUTCMonth(originalMonth);
225
+
226
+ const maxDay = daysInMonth(date.getUTCFullYear(), originalMonth + 1);
227
+ date.setUTCDate(Math.min(originalDay, maxDay));
228
+
229
+ return date.getTime();
230
+ }
231
+
232
+ throw new Error(`addByCalendarUnit supports only month and year: ${unit}`);
233
+ }
234
+
235
+ /**
236
+ * Возвращает числовую разницу между двумя экземплярами {@link OzTime}
237
+ * в указанной единице времени.
238
+ *
239
+ * Для фиксированных единиц может возвращать дробное число,
240
+ * для месяцев и лет возвращает целочисленную календарную разницу.
241
+ *
242
+ * @param {OzTime} left - Левое значение.
243
+ * @param {OzTime} right - Правое значение.
244
+ * @param {string} [unit='millisecond'] - Единица времени.
245
+ * @throws {TypeError} Выбрасывается, если хотя бы один аргумент не является экземпляром OzTime.
246
+ * @throws {Error} Выбрасывается, если unit не поддерживается.
247
+ * @returns {number} Разница между двумя значениями времени.
248
+ * @example
249
+ * import { diff } from './utils/calendar.js';
250
+ * import { fromISO } from '@alexstukovnikov/oz-time';
251
+ *
252
+ * const a = fromISO('2024-05-25T14:00:00Z');
253
+ * const b = fromISO('2024-05-25T12:00:00Z');
254
+ * console.log(diff(a, b, 'hour')); // ожидаемый результат: 2
255
+ */
256
+ export function diff(left, right, unit = 'millisecond') {
257
+ assertOzTime(left, 'left');
258
+ assertOzTime(right, 'right');
259
+
260
+ const normalizedUnit = normalizeUnit(unit);
261
+ const leftTimestamp = left.getTimestamp();
262
+ const rightTimestamp = right.getTimestamp();
263
+
264
+ if (isFixedUnit(normalizedUnit)) {
265
+ return (leftTimestamp - rightTimestamp) / unitToMilliseconds(normalizedUnit);
266
+ }
267
+
268
+ if (normalizedUnit === 'month') {
269
+ return diffInMonths(leftTimestamp, rightTimestamp);
270
+ }
271
+
272
+ if (normalizedUnit === 'year') {
273
+ return diffInYears(leftTimestamp, rightTimestamp);
274
+ }
275
+
276
+ throw new Error(`Unsupported unit: ${unit}`);
277
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Утилиты для нормализации и проверки единиц времени.
3
+ *
4
+ * @module utils/units
5
+ */
6
+
7
+ /**
8
+ * Объект соотношений разных названий единиц времени к каноническим названиям.
9
+ *
10
+ * @type {Object.<string, string>}
11
+ */
12
+ const UNIT_ALIASES = {
13
+ millisecond: 'millisecond',
14
+ milliseconds: 'millisecond',
15
+ ms: 'millisecond',
16
+
17
+ second: 'second',
18
+ seconds: 'second',
19
+ s: 'second',
20
+
21
+ minute: 'minute',
22
+ minutes: 'minute',
23
+ m: 'minute',
24
+
25
+ hour: 'hour',
26
+ hours: 'hour',
27
+ h: 'hour',
28
+
29
+ day: 'day',
30
+ days: 'day',
31
+ d: 'day',
32
+
33
+ month: 'month',
34
+ months: 'month',
35
+
36
+ year: 'year',
37
+ years: 'year',
38
+ y: 'year',
39
+ };
40
+
41
+ /**
42
+ * Точное количество миллисекунд для фиксированных единиц времени.
43
+ *
44
+ * @type {Object.<string, number>}
45
+ */
46
+ export const FIXED_UNIT_TO_MS = {
47
+ millisecond: 1,
48
+ second: 1000,
49
+ minute: 60 * 1000,
50
+ hour: 60 * 60 * 1000,
51
+ day: 24 * 60 * 60 * 1000,
52
+ };
53
+
54
+ /**
55
+ * Массив поддерживаемых календарных единиц времени.
56
+ *
57
+ * @type {string[]}
58
+ */
59
+ export const CALENDAR_UNITS = ['month', 'year'];
60
+
61
+ /**
62
+ * Нормализует единицу времени к каноническому виду.
63
+ *
64
+ * @param {string} unit - Единица времени.
65
+ * @throws {TypeError} Выбрасывается, если unit пустой или не является строкой.
66
+ * @throws {Error} Выбрасывается, если unit не поддерживается.
67
+ * @returns {string} Каноническое название единицы времени.
68
+ * @example
69
+ * import { normalizeUnit } from './utils/units.js';
70
+ *
71
+ * console.log(normalizeUnit('hours')); // ожидаемый результат: hour
72
+ */
73
+ export function normalizeUnit(unit) {
74
+ if (typeof unit !== 'string' || unit.trim() === '') {
75
+ throw new TypeError('normalizeUnit: unit must be a non-empty string');
76
+ }
77
+
78
+ const normalized = unit.toLowerCase().trim();
79
+ const canonical = UNIT_ALIASES[normalized];
80
+
81
+ if (!canonical) {
82
+ throw new Error(`Unsupported unit: ${unit}`);
83
+ }
84
+
85
+ return canonical;
86
+ }
87
+
88
+ /**
89
+ * Проверяет, является ли единица фиксированной.
90
+ *
91
+ * @param {string} unit - Единица времени.
92
+ * @returns {boolean} `true`, если единица является фиксированной.
93
+ * @example
94
+ * import { isFixedUnit } from './utils/units.js';
95
+ *
96
+ * console.log(isFixedUnit('minute')); // ожидаемый результат: true
97
+ */
98
+ export function isFixedUnit(unit) {
99
+ return normalizeUnit(unit) in FIXED_UNIT_TO_MS;
100
+ }
101
+
102
+ /**
103
+ * Проверяет, является ли единица календарной.
104
+ *
105
+ * @param {string} unit - Единица времени.
106
+ * @returns {boolean} `true`, если единица является календарной.
107
+ * @example
108
+ * import { isCalendarUnit } from './utils/units.js';
109
+ *
110
+ * console.log(isCalendarUnit('month')); // ожидаемый результат: true
111
+ */
112
+ export function isCalendarUnit(unit) {
113
+ return CALENDAR_UNITS.includes(normalizeUnit(unit));
114
+ }
115
+
116
+ /**
117
+ * Возвращает точное количество миллисекунд в одной фиксированной единице времени.
118
+ *
119
+ * @param {string} unit - Фиксированная единица времени.
120
+ * @throws {Error} Выбрасывается, если unit нельзя точно перевести в миллисекунды.
121
+ * @returns {number} Количество миллисекунд в одной единице времени.
122
+ * @example
123
+ * import { unitToMilliseconds } from './utils/units.js';
124
+ *
125
+ * console.log(unitToMilliseconds('hour')); // ожидаемый результат: 3600000
126
+ */
127
+ export function unitToMilliseconds(unit) {
128
+ const normalizedUnit = normalizeUnit(unit);
129
+
130
+ if (!(normalizedUnit in FIXED_UNIT_TO_MS)) {
131
+ throw new Error(`Unit cannot be converted to milliseconds exactly: ${unit}`);
132
+ }
133
+
134
+ return FIXED_UNIT_TO_MS[normalizedUnit];
135
+ }
package/dist/oz-time.cjs DELETED
@@ -1 +0,0 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={millisecond:`millisecond`,milliseconds:`millisecond`,ms:`millisecond`,second:`second`,seconds:`second`,s:`second`,minute:`minute`,minutes:`minute`,m:`minute`,hour:`hour`,hours:`hour`,h:`hour`,day:`day`,days:`day`,d:`day`,month:`month`,months:`month`,year:`year`,years:`year`,y:`year`},t={millisecond:1,second:1e3,minute:60*1e3,hour:3600*1e3,day:1440*60*1e3},n=[`month`,`year`];function r(t){if(typeof t!=`string`||t.trim()===``)throw TypeError(`normalizeUnit: unit must be a non-empty string`);let n=e[t.toLowerCase().trim()];if(!n)throw Error(`Unsupported unit: ${t}`);return n}function i(e){return r(e)in t}function a(e){return n.includes(r(e))}function o(e){let n=r(e);if(!(n in t))throw Error(`Unit cannot be converted to milliseconds exactly: ${e}`);return t[n]}function s(e,t){if(typeof e!=`number`||Number.isNaN(e))throw TypeError(`${t}: timestamp must be a valid number`)}function c(e,t){if(typeof e!=`number`||Number.isNaN(e))throw TypeError(`${t}: amount must be a valid number`)}function l(e,t){if(!(e instanceof B))throw TypeError(`${t} must be OzTime`)}function u(e,t){let n=new Date(e),r=new Date(t),i=(n.getUTCFullYear()-r.getUTCFullYear())*12+(n.getUTCMonth()-r.getUTCMonth()),a=n.getUTCDate(),o=r.getUTCDate();return i>0&&a<o?--i:i<0&&a>o&&(i+=1),i}function d(e,t){let n=new Date(e),r=new Date(t),i=n.getUTCFullYear()-r.getUTCFullYear(),a=n.getUTCMonth(),o=r.getUTCMonth(),s=n.getUTCDate(),c=r.getUTCDate();return i>0&&(a<o||a===o&&s<c)?--i:i<0&&(a>o||a===o&&s>c)&&(i+=1),i}function f(e){if(!Number.isInteger(e))throw TypeError(`isLeapYear: year must be an integer`);return e%4==0&&(e%100!=0||e%400==0)}function p(e,t){if(!Number.isInteger(e)||!Number.isInteger(t))throw TypeError(`daysInMonth: year and month must be integers`);if(t<1||t>12)throw RangeError(`daysInMonth: month must be between 1 and 12`);return new Date(Date.UTC(e,t,0)).getUTCDate()}function m(e,t,n){s(e,`addByFixedUnit`),c(t,`addByFixedUnit`);let a=r(n);if(!i(a))throw Error(`addByFixedUnit does not support calendar unit: ${n}`);return e+t*o(a)}function h(e,t,n){s(e,`addByCalendarUnit`),c(t,`addByCalendarUnit`);let i=r(n),a=new Date(e);if(i===`month`){let e=a.getUTCDate();a.setUTCDate(1),a.setUTCMonth(a.getUTCMonth()+t);let n=p(a.getUTCFullYear(),a.getUTCMonth()+1);return a.setUTCDate(Math.min(e,n)),a.getTime()}if(i===`year`){let e=a.getUTCMonth(),n=a.getUTCDate();a.setUTCDate(1),a.setUTCFullYear(a.getUTCFullYear()+t),a.setUTCMonth(e);let r=p(a.getUTCFullYear(),e+1);return a.setUTCDate(Math.min(n,r)),a.getTime()}throw Error(`addByCalendarUnit supports only month and year: ${n}`)}function g(e,t,n=`millisecond`){l(e,`left`),l(t,`right`);let a=r(n),s=e.getTimestamp(),c=t.getTimestamp();if(i(a))return(s-c)/o(a);if(a===`month`)return u(s,c);if(a===`year`)return d(s,c);throw Error(`Unsupported unit: ${n}`)}function _(e,t){if(!(e instanceof B))throw TypeError(`${t} must be OzTime`)}function v(e){if(typeof e!=`number`||Number.isNaN(e))throw TypeError(`amount must be a valid number`)}function y(e,t,n){_(e,`time`),v(t);let o=r(n),s=e.getTimestamp(),c;return i(o)?c=m(s,t,o):a(o)&&(c=h(s,t,o)),new B(c,e.getTimezone(),e.getLocale())}function b(e,t,n){return _(e,`time`),v(t),y(e,-t,n)}function x(e){if(!(e instanceof B))throw TypeError(`format: first argument must be OzTime`)}function S(e,t=2){return String(e).padStart(t,`0`)}function C(e,t){let n=new Intl.DateTimeFormat(t,{timeZone:e.getTimezone(),year:`numeric`,month:`numeric`,day:`numeric`,hour:`numeric`,minute:`2-digit`,second:`2-digit`,hour12:!1}).formatToParts(new Date(e.getTimestamp()));return Object.fromEntries(n.map(e=>[e.type,e.value]))}function w(e,t,n){return new Intl.DateTimeFormat(t,{timeZone:e.getTimezone(),month:n}).format(new Date(e.getTimestamp()))}function T(e,t,n){return new Intl.DateTimeFormat(t,{timeZone:e.getTimezone(),weekday:n}).format(new Date(e.getTimestamp()))}function E(e,t,n){if(x(e),typeof t!=`string`||t.trim()===``)throw TypeError(`format: template must be a non-empty string`);let r=n??e.getLocale(),i=C(e,r),a=Number(i.year),o=Number(i.month),s=Number(i.day),c=Number(i.hour),l=Number(i.minute),u=Number(i.second),d=new Date(e.getTimestamp()).getUTCMilliseconds(),f=c%12,p=f===0?12:f,m=c>=12?`PM`:`AM`,h={YYYY:String(a),YY:String(a).slice(-2),MMMM:w(e,r,`long`),MMM:w(e,r,`short`),MM:S(o),M:String(o),dddd:T(e,r,`long`),ddd:T(e,r,`short`),DD:S(s),D:String(s),HH:S(c),H:String(c),hh:S(p),h:String(p),mm:S(l),ss:S(u),SSS:S(d,3),A:m};return t.replace(/YYYY|MMMM|MMM|MM|M|dddd|ddd|DD|D|HH|H|hh|h|mm|ss|SSS|YY|A/g,e=>h[e]??e)}function D(e,t){if(!(e instanceof B))throw TypeError(`${t} must be OzTime`)}function O(e,t){let n=r(t),i=new Date(e);switch(n){case`millisecond`:return i.getTime();case`second`:i.setUTCMilliseconds(0);break;case`minute`:i.setUTCSeconds(0,0);break;case`hour`:i.setUTCMinutes(0,0,0);break;case`day`:i.setUTCHours(0,0,0,0);break;case`month`:i.setUTCHours(0,0,0,0),i.setUTCDate(1);break;case`year`:i.setUTCHours(0,0,0,0),i.setUTCDate(1),i.setUTCMonth(0);break;default:throw Error(`Unsupported unit for truncateToUnit: ${t}`)}return i.getTime()}function k(e,t,n=`millisecond`){return D(e,`a`),D(t,`b`),O(e.getTimestamp(),n)===O(t.getTimestamp(),n)}function A(e,t,n=`millisecond`){return D(e,`a`),D(t,`b`),O(e.getTimestamp(),n)<O(t.getTimestamp(),n)}function j(e,t,n=`millisecond`){return D(e,`a`),D(t,`b`),O(e.getTimestamp(),n)>O(t.getTimestamp(),n)}function M(e,t,n,r=`millisecond`,i=`[]`){D(e,`target`),D(t,`left`),D(n,`right`);let a=O(e.getTimestamp(),r),o=O(t.getTimestamp(),r),s=O(n.getTimestamp(),r),c=Math.min(o,s),l=Math.max(o,s);switch(i){case`[]`:return a>=c&&a<=l;case`[)`:return a>=c&&a<l;case`(]`:return a>c&&a<=l;case`()`:return a>c&&a<l;default:throw Error(`Invalid inclusivity value: ${i}`)}}function N(e){if(typeof e!=`string`||e.trim()===``)throw TypeError(`setTimezone: timezone must be a non-empty string`);if(!Intl.supportedValuesOf(`timeZone`).includes(e))throw Error(`Unsupported timezone: ${e}`)}function P(e,t){let n=new Date(e),r=new Intl.DateTimeFormat(`en-US`,{timeZone:t,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hour12:!1}).formatToParts(n),i=Object.fromEntries(r.map(e=>[e.type,e.value])),a=Number(i.year),o=Number(i.month),s=Number(i.day),c=Number(i.hour),l=Number(i.minute),u=Number(i.second);return(Date.UTC(a,o-1,s,c,l,u)-e)/6e4}function F(e,t){if(!(e instanceof B))throw TypeError(`tz: first argument must be OzTime`);return N(t),new B(e.getTimestamp(),t,e.getLocale())}function I(e){if(!(e instanceof B))throw TypeError(`getTimezoneOffset: argument must be OzTime`);return P(e.getTimestamp(),e.getTimezone())}function L(e){if(typeof e!=`number`||Number.isNaN(e))throw TypeError(`OzTime: timestamp must be a valid number`)}function R(e){if(typeof e!=`string`||e.trim()===``)throw TypeError(`OzTime: timezone must be a non-empty string`)}function z(e){if(typeof e!=`string`||e.trim()===``)throw TypeError(`OzTime: locale must be a non-empty string`)}var B=class{constructor(e,t=`UTC`,n=`en-US`){L(e),R(t),z(n),this._timestamp=e,this._timezone=t,this._locale=n}getTimestamp(){return this._timestamp}getTimezone(){return this._timezone}getLocale(){return this._locale}toTimestamp(){return this._timestamp}toISOString(){return new Date(this._timestamp).toISOString()}add(e,t){return y(this,e,t)}subtract(e,t){return b(this,e,t)}format(e,t){return E(this,e,t)}isSame(e,t=`millisecond`){return k(this,e,t)}isBefore(e,t=`millisecond`){return A(this,e,t)}isAfter(e,t=`millisecond`){return j(this,e,t)}isBetween(e,t,n=`millisecond`,r=`[]`){return M(this,e,t,n,r)}setTimezone(e){return F(this,e)}getTimezoneOffset(){return I(this)}diff(e,t=`millisecond`){return g(this,e,t)}};function V(e){if(typeof e!=`number`||Number.isNaN(e))throw TypeError(`fromTimestamp: timestamp must be a valid number`)}function H(e){if(!(e instanceof Date)||Number.isNaN(e.getTime()))throw TypeError(`fromDate: date must be a valid Date`)}function U(e,t){if(!Number.isInteger(e))throw TypeError(`${t} must be an integer`)}function W(e=`UTC`,t=`en-US`){return new B(Date.now(),e,t)}function G(e,t=`UTC`,n=`en-US`){return V(e),new B(e,t,n)}function K(e,t=`UTC`,n=`en-US`){return H(e),new B(e.getTime(),t,n)}function q(e,t=`UTC`,n=`en-US`){if(typeof e!=`string`||e.trim()===``)throw TypeError(`fromISO: isoString must be a non-empty string`);let r=Date.parse(e);if(Number.isNaN(r))throw Error(`Invalid ISO date string: ${e}`);return new B(r,t,n)}function J(e,t,n,r=0,i=0,a=0,o=0,s=`UTC`,c=`en-US`){if(U(e,`year`),U(t,`month`),U(n,`day`),U(r,`hour`),U(i,`minute`),U(a,`second`),U(o,`millisecond`),t<1||t>12)throw RangeError(`month must be between 1 and 12`);if(r<0||r>23)throw RangeError(`hour must be between 0 and 23`);if(i<0||i>59)throw RangeError(`minute must be between 0 and 59`);if(a<0||a>59)throw RangeError(`second must be between 0 and 59`);if(o<0||o>999)throw RangeError(`millisecond must be between 0 and 999`);let l=p(e,t);if(n<1||n>l)throw RangeError(`day must be between 1 and ${l} for ${e}-${t}`);return new B(Date.UTC(e,t-1,n,r,i,a,o),s,c)}function Y(e,t){if(!(e instanceof B))throw TypeError(`${t} must be OzTime`)}var X=class e{constructor(e,t){if(Y(e,`start`),Y(t,`end`),e.getTimestamp()>t.getTimestamp())throw RangeError(`Interval: start must be before or equal to end`);this._start=e,this._end=t}getStart(){return this._start}getEnd(){return this._end}contains(e){Y(e,`moment`);let t=e.getTimestamp();return t>=this._start.getTimestamp()&&t<=this._end.getTimestamp()}overlaps(t){if(!(t instanceof e))throw TypeError(`other must be Interval`);let n=this._start.getTimestamp(),r=this._end.getTimestamp(),i=t.getStart().getTimestamp();return n<=t.getEnd().getTimestamp()&&i<=r}duration(e=`millisecond`){let t=r(e);if(!i(t))throw Error(`Interval.duration supports only fixed units: ${e}`);return(this._end.getTimestamp()-this._start.getTimestamp())/o(t)}};function Z(e,t){return new X(e,t)}function Q(e){if(typeof e!=`number`||Number.isNaN(e))throw TypeError(`amount must be a valid number`)}var $=class e{constructor(e){if(typeof e!=`number`||Number.isNaN(e))throw TypeError(`Duration: milliseconds must be a valid number`);this._milliseconds=e}asMilliseconds(){return this._milliseconds}asSeconds(){return this._milliseconds/o(`second`)}asMinutes(){return this._milliseconds/o(`minute`)}asHours(){return this._milliseconds/o(`hour`)}asDays(){return this._milliseconds/o(`day`)}add(t){if(!(t instanceof e))throw TypeError(`Duration.add: other must be Duration`);return new e(this._milliseconds+t._milliseconds)}};function ee(e,t){Q(e);let n=r(t);if(!i(n))throw Error(`duration supports only fixed units: ${t}`);return new $(e*o(n))}exports.Duration=$,exports.Interval=X,exports.OzTime=B,exports.add=y,exports.daysInMonth=p,exports.duration=ee,exports.format=E,exports.fromComponents=J,exports.fromDate=K,exports.fromISO=q,exports.fromTimestamp=G,exports.getTimezoneOffset=I,exports.interval=Z,exports.isAfter=j,exports.isBefore=A,exports.isBetween=M,exports.isLeapYear=f,exports.isSame=k,exports.now=W,exports.setTimezone=F,exports.subtract=b;