// Paris timezone helpers + simulated/live clock state. // // State is module-level (singleton) so all components share the same // `simDate` / `isLive` without prop drilling. import { ref, computed } from 'vue' export const TZ = 'Europe/Paris' export function parisComponents(d) { const parts = new Intl.DateTimeFormat('fr-FR', { timeZone: TZ, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, }).formatToParts(d) const get = (t) => parseInt(parts.find((x) => x.type === t).value, 10) return { year: get('year'), month: get('month'), day: get('day'), hour: get('hour'), minute: get('minute'), second: get('second'), } } export function parisDateStr(d) { const p = parisComponents(d) const pad = (n) => String(n).padStart(2, '0') return `${p.year}-${pad(p.month)}-${pad(p.day)}` } export function toInputStr(d) { const p = parisComponents(d) const pad = (n) => String(n).padStart(2, '0') return `${p.year}-${pad(p.month)}-${pad(p.day)}T${pad(p.hour)}:${pad(p.minute)}:${pad(p.second)}` } export function getParisOffsetMs(d) { const fmt = (tz) => new Intl.DateTimeFormat('en-GB', { timeZone: tz, hour: '2-digit', minute: '2-digit', hour12: false, }).format(d) const [uh, um] = fmt('UTC').split(':').map(Number) const [ph, pm] = fmt(TZ).split(':').map(Number) return ((ph * 60 + pm) - (uh * 60 + um)) * 60000 } export function parisStrToDate(val) { const naive = new Date(val + 'Z') return new Date(naive.getTime() - getParisOffsetMs(naive)) } // --- Shared singleton state --- const simDate = ref(null) const isLive = ref(true) function getNow() { return isLive.value ? new Date() : simDate.value } function setSimulated(date) { simDate.value = date isLive.value = false } function goLive() { simDate.value = null isLive.value = true } export function useClockState() { return { simDate: computed(() => simDate.value), isLive: computed(() => isLive.value), getNow, setSimulated, goLive, } }