Files
2026-10-29 11:57:29 +01:00

77 lines
2.9 KiB
JavaScript

// Generated, do not edit. sha256:f7c492e9043516674843077cdedb9f9190b5176696652a8825a3e593c111d7ea
import { localeTag } from '../i18n/index.js';
const MIN = 60 * 1000;
const WEEKDAY_NUM = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 };
const _partsFmt = new Map();
function wallParts(tz, instant) {
let f = _partsFmt.get(tz);
if (!f) {
f = new Intl.DateTimeFormat('en-US', {
timeZone: tz, hourCycle: 'h23', weekday: 'short',
year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit',
});
_partsFmt.set(tz, f);
}
const p = {};
for (const part of f.formatToParts(instant)) p[part.type] = part.value;
return { y: +p.year, mo: +p.month, d: +p.day, wd: WEEKDAY_NUM[p.weekday], h: +p.hour % 24, mi: +p.minute };
}
export function wallToInstant(tz, y, mo, d, h, mi) {
const target = Date.UTC(y, mo - 1, d, h, mi);
let t = target;
for (let i = 0; i < 2; i++) {
const w = wallParts(tz, new Date(t));
t += target - Date.UTC(w.y, w.mo - 1, w.d, w.h, w.mi);
}
return new Date(t);
}
const hm = (s) => s.split(':').map(Number);
export function exchangeStatus(ex, now = new Date()) {
const [oh, om] = hm(ex.open);
const [ch, cm] = hm(ex.close);
const today = wallParts(ex.tz, now);
for (let d = 0; d < 8; d++) {
const day = new Date(Date.UTC(today.y, today.mo - 1, today.d + d));
if (!ex.days.includes(day.getUTCDay())) continue;
const y = day.getUTCFullYear(), mo = day.getUTCMonth() + 1, dd = day.getUTCDate();
const opens = wallToInstant(ex.tz, y, mo, dd, oh, om);
const closes = wallToInstant(ex.tz, y, mo, dd, ch, cm);
if (now < opens) return { isOpen: false, openedAt: null, closesAt: null, opensAt: opens };
if (now < closes) return { isOpen: true, openedAt: opens, closesAt: closes, opensAt: null };
}
return { isOpen: false, openedAt: null, closesAt: null, opensAt: null };
}
export function durationParts(ms) {
const minutes = Math.max(1, Math.ceil(ms / MIN));
if (minutes < 60) return { unit: 'min', n: minutes };
if (minutes < 180) return { unit: 'hourMin', n: Math.floor(minutes / 60), m: minutes % 60 };
if (minutes < 24 * 60) return { unit: 'hours', n: Math.round(minutes / 60) };
return { unit: 'days', n: Math.round(minutes / (24 * 60)) };
}
const _clockFmt = new Map();
export function localClock(instant, now = new Date(), tz = undefined) {
const tag = localeTag();
const key = `${tag}|${tz || ''}`;
let f = _clockFmt.get(key);
if (!f) {
f = {
time: new Intl.DateTimeFormat(tag, { timeZone: tz, hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }),
day: new Intl.DateTimeFormat('en-CA', { timeZone: tz, year: 'numeric', month: '2-digit', day: '2-digit' }),
weekday: new Intl.DateTimeFormat(tag, { timeZone: tz, weekday: 'short' }),
};
_clockFmt.set(key, f);
}
return {
time: f.time.format(instant),
otherDay: f.day.format(instant) !== f.day.format(now),
weekday: f.weekday.format(instant),
};
}