nhb-toolbox
Version:
A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.
799 lines (798 loc) • 28.1 kB
JavaScript
var _a;
import { isNumber, isString } from '../guards/primitives.js';
import { DAYS, INTERNALS, MONTHS, MS_PER_DAY } from './constants.js';
import { isLeapYear } from './guards.js';
import { _dateArgsToDate, _formatDate, _hasChronosProperties, _normalizeOffset, _resolveNativeTzName, } from './helpers.js';
import { extractMinutesFromUTC, getNativeTimeZoneId } from './utils.js';
export class Chronos {
#date;
#offset;
#ORIGIN;
static #plugins = new Set();
static [INTERNALS] = {
internalDate(instance) {
return instance.#date;
},
offset(instance) {
return instance.#offset;
},
withOrigin(instance, method, offset, tzName, tzId, tzTracker) {
return instance.#withOrigin(method, offset, tzName, tzId, tzTracker);
},
toNewDate(instance, value) {
return instance.#toNewDate(value);
},
cast(date) {
return _a.#cast(date);
},
};
origin;
native;
utcOffset;
timeZoneName;
timeZoneId;
$tzTracker;
constructor(valueOrYear, month, date, hours, minutes, seconds, ms) {
if (isNumber(valueOrYear) && isNumber(month)) {
this.#date = new Date(valueOrYear, month - 1, date ?? 1, hours ?? 0, minutes ?? 0, seconds ?? 0, ms ?? 0);
this.native = this.#date;
}
else {
this.#date = this.#toNewDate(valueOrYear);
this.native = this.#date;
}
this.#ORIGIN = 'root';
this.origin = this.#ORIGIN;
this.#offset = `UTC${this.getUTCOffset()}`;
this.utcOffset = this.#offset;
this.timeZoneName = this.$getNativeTimeZoneName();
this.timeZoneId = this.$getNativeTimeZoneId();
}
*[Symbol.iterator]() {
yield ['year', this.year];
yield ['month', this.month];
yield ['isoMonth', this.isoMonth];
yield ['date', this.date];
yield ['weekDay', this.weekDay];
yield ['isoWeekDay', this.isoWeekDay];
yield ['hour', this.hour];
yield ['minute', this.minute];
yield ['second', this.second];
yield ['millisecond', this.millisecond];
yield ['timestamp', this.getTimeStamp()];
yield ['unix', this.unix];
}
[Symbol.toPrimitive](hint) {
if (hint === 'number')
return this.getTimeStamp();
return this.toLocalISOString();
}
[Symbol.replace](string, replacement) {
return string.replace(this.#removeUTCFromISO(), replacement);
}
[Symbol.search](string) {
return string.indexOf(this.#removeUTCFromISO());
}
[Symbol.split](string) {
return string.split(this.#removeUTCFromISO());
}
[Symbol.match](string) {
const [datePart, timePart] = this.toLocalISOString().split('.')[0].split('T');
const fuzzyDate = datePart.replace(/-/g, '[-/]?');
const fuzzyTime = timePart?.replace(/:/g, '[:.]?');
const pattern = timePart ? `${fuzzyDate}(?:[T ]?${fuzzyTime})?` : fuzzyDate;
return string.match(new RegExp(pattern));
}
get [Symbol.toStringTag]() {
return this.toLocalISOString();
}
get [Symbol.isConcatSpreadable]() {
return true;
}
$getNativeTimeZoneName(tzId) {
const $tzId = tzId || getNativeTimeZoneId();
return _resolveNativeTzName($tzId, 'long', this.#date) ?? $tzId;
}
$getNativeTimeZoneId() {
return getNativeTimeZoneId();
}
get #timestamp() {
return this.#date.getTime();
}
#toNewDate(value) {
const date = value instanceof _a ? value.toDate() : _dateArgsToDate(value);
if (Number.isNaN(date.getTime())) {
throw new TypeError('Provided date is invalid!');
}
return date;
}
#withOrigin(origin, offset, tzName, tzId, tzTracker) {
const instance = new _a(this.#date);
instance.#ORIGIN = origin;
instance.origin = origin;
if (offset) {
instance.#offset = offset;
instance.utcOffset = offset;
}
if (tzName)
instance.timeZoneName = tzName;
if (tzId)
instance.timeZoneId = tzId;
if (tzTracker)
instance.$tzTracker = tzTracker;
instance.native = instance.toDate();
return instance;
}
#cloneStates(instance, origin) {
return instance.#withOrigin(origin, this.#offset, this.timeZoneName, this.timeZoneId, this.$tzTracker);
}
#format(format, useUTC = false) {
const $date = this.#date;
const $utcDate = this.toDate();
const _getUnitValue = (suffix) => {
return useUTC ? $utcDate[`getUTC${suffix}`]() : $date[`get${suffix}`]();
};
const y = _getUnitValue('FullYear'), mo = _getUnitValue('Month'), d = _getUnitValue('Day'), dt = _getUnitValue('Date'), h = _getUnitValue('Hours'), m = _getUnitValue('Minutes'), s = _getUnitValue('Seconds'), ms = _getUnitValue('Milliseconds');
const offset = useUTC ? 'Z' : this.getTimeZoneOffset();
return _formatDate(format, y, mo, d, dt, h, m, s, ms, offset);
}
#removeUTCFromISO(local = true) {
const search = /\.\d+(Z|[+-]\d{2}:\d{2})?$/;
return local
? this.toLocalISOString().replace(search, '')
: this.toISOString().replace(search, '');
}
get year() {
return this.#date.getFullYear();
}
get month() {
return this.#date.getMonth();
}
get date() {
return this.#date.getDate();
}
get weekDay() {
return this.#date.getDay();
}
get hour() {
return this.#date.getHours();
}
get minute() {
return this.#date.getMinutes();
}
get second() {
return this.#date.getSeconds();
}
get millisecond() {
return this.#date.getMilliseconds();
}
get isoWeekDay() {
const day = this.weekDay;
return day === 0 ? 7 : day;
}
get isoMonth() {
return (this.month + 1);
}
get unix() {
return Math.floor(this.getTimeStamp() / 1000);
}
get timestamp() {
return this.getTimeStamp();
}
get lastDateOfMonth() {
return this.daysInMonth();
}
inspect() {
return `[Chronos ${this.toLocalISOString()}]`;
}
toJSON() {
return this.toLocalISOString();
}
valueOf() {
return this.getTimeStamp();
}
clone() {
return new _a(this.#date).#withOrigin(this.#ORIGIN, this.#offset, this.timeZoneName, this.timeZoneId, this.$tzTracker);
}
toDate() {
const targetOffset = extractMinutesFromUTC(this.#offset);
const systemOffset = this.getUTCOffsetMinutes();
const adjustmentMs = (targetOffset - systemOffset) * 60_000;
return new Date(this.#timestamp - adjustmentMs);
}
toString() {
return this.#format('dd mmm DD YYYY HH:mm:ss ')
.concat(this.#offset.replace('UTC', 'GMT').replace(':', ''))
.concat(` (${this.timeZoneName})`);
}
toLocalISOString() {
return this.#format('YYYY-MM-DDTHH:mm:ss.mssZZ');
}
toISOString() {
return this.toDate().toISOString();
}
toLocaleString(locales, options) {
return this.#date.toLocaleString(locales, options);
}
getTimeStamp() {
return this.toDate().getTime();
}
format(format, useUTC = false) {
return this.#format(format || 'dd, mmm DD, YYYY HH:mm:ss', useUTC);
}
formatStrict(format, useUTC = false) {
return this.#format(format || 'dd, mmm DD, YYYY HH:mm:ss', useUTC);
}
formatUTC(format = 'dd, mmm DD, YYYY HH:mm:ss:mss') {
return this.#format(format, true);
}
addSeconds(seconds) {
return this.#cloneStates(this.add(seconds, 'second'), 'addSeconds');
}
addMinutes(minutes) {
return this.#cloneStates(this.add(minutes, 'minute'), 'addMinutes');
}
addHours(hours) {
return this.#cloneStates(this.add(hours, 'hour'), 'addHours');
}
addDays(days) {
return this.#cloneStates(this.add(days, 'day'), 'addDays');
}
addWeeks(weeks) {
return this.#cloneStates(this.add(weeks, 'week'), 'addWeeks');
}
addMonths(months) {
return this.#cloneStates(this.add(months, 'month'), 'addMonths');
}
addYears(years) {
return this.#cloneStates(this.add(years, 'year'), 'addYears');
}
isLeapYear(year) {
return isLeapYear(year ?? this.year);
}
isEqual(other) {
return this.#timestamp === _a.#cast(other).#timestamp;
}
isEqualOrBefore(other) {
return this.#timestamp <= _a.#cast(other).#timestamp;
}
isEqualOrAfter(other) {
return this.#timestamp >= _a.#cast(other).#timestamp;
}
isSame(other, unit, weekStartsOn = 0) {
return (this.startOf(unit, weekStartsOn).#timestamp ===
_a.#cast(other).startOf(unit, weekStartsOn).#timestamp);
}
isBefore(other, unit, weekStartsOn = 0) {
return (this.startOf(unit, weekStartsOn).#timestamp <
_a.#cast(other).startOf(unit, weekStartsOn).#timestamp);
}
isAfter(other, unit, weekStartsOn = 0) {
return (this.startOf(unit, weekStartsOn).#timestamp >
_a.#cast(other).startOf(unit, weekStartsOn).#timestamp);
}
isSameOrBefore(other, unit, weekStartsOn = 0) {
return (this.isSame(other, unit, weekStartsOn) || this.isBefore(other, unit, weekStartsOn));
}
isSameOrAfter(other, unit, weekStartsOn = 0) {
return (this.isSame(other, unit, weekStartsOn) || this.isAfter(other, unit, weekStartsOn));
}
isBetween(start, end, inclusive = '()') {
const s = _a.#cast(start).getTimeStamp();
const e = _a.#cast(end).getTimeStamp();
const t = this.getTimeStamp();
switch (inclusive) {
case '[]':
return t >= s && t <= e;
case '[)':
return t >= s && t < e;
case '(]':
return t > s && t <= e;
case '()':
return t > s && t < e;
default:
return false;
}
}
isDST() {
const year = this.year;
const jan = new Date(year, 0, 1).getTimezoneOffset();
const jul = new Date(year, 6, 1).getTimezoneOffset();
return this.#date.getTimezoneOffset() < Math.max(jan, jul);
}
isFirstDayOfMonth() {
return this.isSame(this.firstDayOfMonth(), 'day');
}
isLastDayOfMonth() {
return this.isSame(this.lastDayOfMonth(), 'day');
}
firstDayOfMonth() {
const firstDate = new Date(this.year, this.month, 1);
return this.#cloneStates(new _a(firstDate), 'firstDayOfMonth');
}
lastDayOfMonth() {
const lastDate = new Date(this.year, this.month + 1, 0);
return this.#cloneStates(new _a(lastDate), 'lastDayOfMonth');
}
startOf(unit, weekStartsOn = 0) {
const d = new Date(this.#date);
switch (unit) {
case 'year':
d.setMonth(0, 1);
d.setHours(0, 0, 0, 0);
break;
case 'month':
d.setDate(1);
d.setHours(0, 0, 0, 0);
break;
case 'week': {
const day = d.getDay();
const diff = (day - weekStartsOn + 7) % 7;
d.setDate(d.getDate() - diff);
d.setHours(0, 0, 0, 0);
break;
}
case 'day':
d.setHours(0, 0, 0, 0);
break;
case 'hour':
d.setMinutes(0, 0, 0);
break;
case 'minute':
d.setSeconds(0, 0);
break;
case 'second':
d.setMilliseconds(0);
break;
case 'millisecond':
break;
}
return this.#cloneStates(new _a(d), 'startOf');
}
endOf(unit, weekStartsOn = 0) {
const instance = this.startOf(unit, weekStartsOn).add(1, unit).add(-1, 'millisecond');
return this.#cloneStates(instance, 'endOf');
}
add(number, unit) {
const d = new Date(this.#date);
switch (unit) {
case 'millisecond':
d.setMilliseconds(d.getMilliseconds() + number);
break;
case 'second':
d.setSeconds(d.getSeconds() + number);
break;
case 'minute':
d.setMinutes(d.getMinutes() + number);
break;
case 'hour':
d.setHours(d.getHours() + number);
break;
case 'day':
d.setDate(d.getDate() + number);
break;
case 'week':
d.setDate(d.getDate() + number * 7);
break;
case 'month':
d.setMonth(d.getMonth() + number);
break;
case 'year':
d.setFullYear(d.getFullYear() + number);
break;
}
return this.#cloneStates(new _a(d), 'add');
}
subtract(number, unit) {
return this.#cloneStates(this.add(-number, unit), 'subtract');
}
get(unit) {
switch (unit) {
case 'year':
return this.year;
case 'month':
return this.isoMonth;
case 'day':
return this.date;
case 'week':
return this.getWeek();
case 'hour':
return this.hour;
case 'minute':
return this.minute;
case 'second':
return this.second;
case 'millisecond':
return this.millisecond;
}
}
set(unit, value) {
const d = new Date(this.#date);
switch (unit) {
case 'year':
d.setFullYear(value);
break;
case 'month':
d.setMonth(value - 1);
break;
case 'day':
d.setDate(value);
break;
case 'week':
return this.setWeek(value);
case 'hour':
d.setHours(value);
break;
case 'minute':
d.setMinutes(value);
break;
case 'second':
d.setSeconds(value);
break;
case 'millisecond':
d.setMilliseconds(value);
break;
}
return this.#cloneStates(new _a(d), 'set');
}
diff(other, unit) {
const time = _a.#cast(other);
const msDiff = this.#timestamp - time.#timestamp;
switch (unit) {
case 'millisecond':
return msDiff;
case 'second':
return msDiff / 1e3;
case 'minute':
return msDiff / 6e4;
case 'hour':
return msDiff / 3.6e6;
case 'day':
return msDiff / 8.64e7;
case 'week':
return msDiff / 6.048e8;
case 'month': {
const yearDiff = this.year - time.year;
const monthDiff = this.month - time.month;
const totalMonthDiff = yearDiff * 12 + monthDiff;
const dayDiff = this.date - time.date;
return totalMonthDiff + dayDiff / this.daysInMonth();
}
case 'year':
return this.diff(time, 'month') / 12;
}
}
calendar(baseDate) {
const base = baseDate ? _a.#cast(baseDate) : new _a();
const input = this.startOf('day');
const comparison = base.startOf('day');
const diff = input.diff(comparison, 'day');
const timeStr = this.toDate().toLocaleString('en', {
hour: 'numeric',
minute: '2-digit',
});
if (diff === 0)
return `Today at ${timeStr}`;
if (diff === 1)
return `Tomorrow at ${timeStr}`;
if (diff === -1)
return `Yesterday at ${timeStr}`;
return this.toDate().toLocaleString('en', {
month: 'long',
day: '2-digit',
year: 'numeric',
weekday: 'long',
hour: 'numeric',
minute: '2-digit',
});
}
fromNowShort() {
const now = new _a();
const diffInSeconds = this.diff(now, 'second');
const abs = Math.abs(diffInSeconds);
const prefix = diffInSeconds >= 0 ? 'in ' : '';
const suffix = diffInSeconds < 0 ? ' ago' : '';
if (abs < 60) {
return `${prefix}${Math.floor(abs)}s${suffix}`;
}
else if (abs < 3600) {
return `${prefix}${Math.floor(abs / 60)}m${suffix}`;
}
else if (abs < 86400) {
return `${prefix}${Math.floor(abs / 3600)}h${suffix}`;
}
else if (abs < 2592000) {
return `${prefix}${Math.floor(abs / 86400)}d${suffix}`;
}
else if (abs < 31536000) {
return `${prefix}${Math.floor(abs / 2592000)}mo${suffix}`;
}
else {
return `${prefix}${Math.floor(abs / 31536000)}y${suffix}`;
}
}
setWeek(week) {
const d = new Date(this.#date);
const year = d.getFullYear();
const jan4 = new Date(year, 0, 4);
const dayOfWeek = jan4.getDay() || 7;
const weekStart = new Date(jan4);
weekStart.setDate(jan4.getDate() - (dayOfWeek - 1));
weekStart.setDate(weekStart.getDate() + (week - 1) * 7);
d.setFullYear(weekStart.getFullYear());
d.setMonth(weekStart.getMonth());
d.setDate(weekStart.getDate());
return this.#cloneStates(new _a(d), 'setWeek');
}
getWeek() {
const target = this.startOf('week', 1).add(3, 'day');
const firstThursday = new _a(target.year, 1, 4)
.startOf('week', 1)
.add(3, 'day');
return (target.diff(firstThursday, 'week') + 1);
}
getWeekOfYear(weekStartsOn = 0) {
const startOfFirstWeek = this.startOf('year').startOf('week', weekStartsOn);
const week = this.startOf('week', weekStartsOn).diff(startOfFirstWeek, 'week');
return (week + 1);
}
getWeekYear(weekStartsOn = 0) {
const d = this.startOf('week', weekStartsOn).add(3, 'day');
return d.year;
}
getDayOfYear() {
const diff = this.startOf('day').diff(this.startOf('year'), 'day');
return (diff + 1);
}
daysInMonth() {
return new Date(this.year, this.month + 1, 0).getDate();
}
toObject() {
return Object.fromEntries([...this]);
}
toArray() {
return Object.values(this.toObject());
}
toQuarter() {
const month = this.#date.getMonth();
return (Math.floor(month / 3) + 1);
}
getUTCOffset() {
const offset = -this.#date.getTimezoneOffset();
const sign = offset >= 0 ? '+' : '-';
const pad = (n) => String(Math.floor(Math.abs(n))).padStart(2, '0');
return `${sign}${pad(offset / 60)}:${pad(offset % 60)}`;
}
getTimeZoneOffset() {
return this.#offset.replace('UTC', '');
}
getUTCOffsetMinutes() {
return -this.#date.getTimezoneOffset();
}
getTimeZoneOffsetMinutes() {
return extractMinutesFromUTC(this.#offset);
}
toUTC() {
const offset = this.getTimeZoneOffsetMinutes();
const utc = new Date(this.#timestamp - offset * 60 * 1000);
return new _a(utc).#withOrigin('toUTC', 'UTC+00:00', 'Greenwich Mean Time', 'UTC');
}
toLocal() {
const offset = this.getTimeZoneOffsetMinutes() - this.getUTCOffsetMinutes();
const localTime = new Date(this.#timestamp - offset * 60 * 1000);
return new _a(localTime).#withOrigin('toLocal');
}
day(index) {
return DAYS[index ?? this.weekDay];
}
monthName(index) {
return MONTHS[index ?? this.month];
}
static parse(dateStr, format) {
const tokenPatterns = {
YYYY: '(?<YYYY>\\d{4})',
YY: '(?<YY>\\d{2})',
MM: '(?<MM>\\d{2})',
M: '(?<M>\\d{1,2})',
DD: '(?<DD>\\d{2})',
D: '(?<D>\\d{1,2})',
HH: '(?<HH>\\d{2})',
H: '(?<H>\\d{1,2})',
mm: '(?<mm>\\d{2})',
m: '(?<m>\\d{1,2})',
ss: '(?<ss>\\d{2})',
s: '(?<s>\\d{1,2})',
mss: '(?<mss>\\d{3})',
ms: '(?<ms>\\d{1,3})',
};
const tokenToComponent = {
YYYY: 'year',
YY: 'year',
MM: 'month',
M: 'month',
DD: 'date',
D: 'date',
HH: 'hour',
H: 'hour',
mm: 'minute',
m: 'minute',
ss: 'second',
s: 'second',
mss: 'millisecond',
ms: 'millisecond',
};
const tokenRegExp = new RegExp(Object.keys(tokenPatterns)
.sort((a, b) => b.length - a.length)
.join('|'), 'g');
const regexStr = format
?.trim()
?.replace(tokenRegExp, (token) => tokenPatterns[token] ?? token)
?.replace(/\s+/g, '\\s*');
const match = new RegExp(`^${regexStr}\\s*$`).exec(dateStr.trim());
if (!match?.groups) {
throw new Error('Invalid date format!');
}
const parts = {};
for (const [token, value] of Object.entries(match.groups)) {
const key = tokenToComponent[token];
if (key) {
let num = Number(value);
if (token === 'YY') {
num += num < 100 ? 2000 : 0;
}
parts[key] = num;
}
}
return new _a(parts?.year ?? 1970, parts?.month ?? 1, parts?.date ?? 1, parts?.hour ?? 0, parts?.minute ?? 0, parts?.second ?? 0, parts?.millisecond ?? 0).#withOrigin('parse');
}
static with(options) {
const now = new _a();
const { year, month, date, hour, minute, second, millisecond } = options ?? {};
const nextLDoM = () => {
return now
.startOf('month')
.set('year', year ?? now.year)
.set('month', month ?? now.isoMonth).lastDateOfMonth;
};
return new _a(year ?? now.year, month ?? now.isoMonth, date
? date
: now.isLastDayOfMonth() && now.date >= nextLDoM()
? nextLDoM()
: now.date, hour ?? now.hour, minute ?? now.minute, second ?? now.second, millisecond ?? now.millisecond).#withOrigin('with');
}
static today(options) {
const { format = 'dd, mmm DD, YYYY HH:mm:ss', useUTC = false } = options || {};
return new _a().#format(format, useUTC);
}
static yesterday() {
const today = new Date();
const yesterday = today.setDate(today.getDate() - 1);
return new _a(yesterday).#withOrigin('yesterday');
}
static tomorrow() {
const today = new Date();
const yesterday = today.setDate(today.getDate() + 1);
return new _a(yesterday).#withOrigin('tomorrow');
}
static now() {
return Date.now();
}
static utc(dateLike) {
const chronos = new _a(dateLike);
const offset = chronos.getTimeZoneOffsetMinutes();
const utc = new Date(chronos.#timestamp - offset * 60 * 1000);
return new _a(utc).#withOrigin('utc', 'UTC+00:00', 'Greenwich Mean Time', 'UTC');
}
static formatTimePart(time, format) {
const timeWithDate = `${new _a().#format('YYYY-MM-DD')}T${_normalizeOffset(time)}`;
return new _a(timeWithDate).#format(format || 'hh:mm:ss a');
}
static getDatesForDay(day, options) {
let startDate = new _a(), endDate = startDate.addWeeks(4);
const { format = 'local', roundDate = false } = options ?? {};
if (options) {
if ('from' in options || 'to' in options) {
if (options?.from)
startDate = _a.#cast(options?.from);
if (options?.to)
endDate = _a.#cast(options?.to);
}
else if ('span' in options || 'unit' in options) {
const { span = 4, unit = 'week' } = options ?? {};
endDate = startDate.add(span, unit);
}
}
if (roundDate) {
startDate = startDate.startOf('day');
endDate = endDate.startOf('day');
}
const result = [];
const step = (startDate.isBefore(endDate, 'day') ? 1 : -1) * MS_PER_DAY;
const totalDays = Math.abs(endDate.diff(startDate, 'day'));
const currentTime = startDate.#timestamp;
let firstOffset = 0;
while (new Date(currentTime + firstOffset * step).getDay() !== DAYS.indexOf(day)) {
firstOffset++;
}
for (let i = firstOffset; i <= totalDays; i += 7) {
const ts = currentTime + i * step;
const chr = new _a(ts).#withOrigin('clone', startDate.#offset, startDate.timeZoneName, startDate.timeZoneId, startDate.$tzTracker);
result.push(format === 'local' ? chr.toLocalISOString() : chr.toISOString());
}
return result;
}
static min(...dates) {
let winner = _a.#cast(dates[0]);
for (const d of dates) {
const c = _a.#cast(d);
if (c.getTimeStamp() < winner.getTimeStamp()) {
winner = c;
}
}
return winner.#cloneStates(winner, winner.#ORIGIN !== 'root' ? winner.#ORIGIN : 'min');
}
static max(...dates) {
let winner = _a.#cast(dates[0]);
for (const d of dates) {
const c = _a.#cast(d);
if (c.getTimeStamp() > winner.getTimeStamp()) {
winner = c;
}
}
return winner.#cloneStates(winner, winner.#ORIGIN !== 'root' ? winner.#ORIGIN : 'max');
}
static isLeapYear(date) {
let year;
if (isNumber(date)) {
if (date > 0 && date <= 9999) {
year = date;
}
else {
year = new Date(date).getFullYear();
}
}
else {
year = _a.#cast(date).year;
}
return isLeapYear(year);
}
static isValidDate(value) {
return value instanceof Date;
}
static isDateString(value) {
return isString(value) && !Number.isNaN(Date.parse(value));
}
static isValidChronos(value) {
return value instanceof _a;
}
static isReconstructable(value) {
return _hasChronosProperties(value);
}
static reconstruct(value) {
if (!_hasChronosProperties(value)) {
throw new TypeError('Invalid input for reconstruction!');
}
const { native, origin, utcOffset, timeZoneName, timeZoneId, $tzTracker } = value;
const offsetMins = extractMinutesFromUTC(utcOffset);
const chr = new _a(native);
const diffMins = chr.getTimeZoneOffsetMinutes() - offsetMins;
const target = chr.utcOffset === utcOffset ? chr : chr.add(-diffMins, 'minute');
return target.#withOrigin(origin, utcOffset, timeZoneName, timeZoneId, $tzTracker);
}
static use(plugin) {
if (!_a.#plugins.has(plugin)) {
_a.#plugins.add(plugin);
plugin(_a);
}
}
static register(plugin) {
_a.use(plugin);
}
static #cast(date) {
return date instanceof _a ? date : new _a(date);
}
}
_a = Chronos;
export { chronos, chronosjs, chronosts, chronus, chronusjs, chronusts } from './chronos-fn.js';
export { INTERNALS } from './constants.js';
export { Chronos as Chronus };