diff --git a/events.js b/events.js index 5803054..d09e18a 100644 --- a/events.js +++ b/events.js @@ -21,5 +21,5 @@ window.SPECIAL_EVENTS = [ { cobie: '330d.d4ae', label: 'Zusammentag', unit: 'cosmocycle', interval: 1 }, { cobie: '11de.0c52', label: 'Anna', unit: 'cosmocycle', interval: 1 }, { cobie: '467f.ae61', label: 'Iris', unit: 'cosmocycle', interval: 1 }, - { cobie: '6854.7a75', label: 'Sleep', unit: 'second', interval: 86400, duration: 28800, showMega: false } + { cobie: '6854.7a75', label: 'Night', unit: 'second', interval: 86400, duration: 28800, showMega: false, shiftWithTimezone: true } ]; diff --git a/script.js b/script.js index a0fc9b0..432aa1c 100644 --- a/script.js +++ b/script.js @@ -44,6 +44,24 @@ let updateInterval; let lastRenderedEonstrip = null; let currentDetailCob = null; +function getTimezoneOffsetSeconds(date) { + if (currentTimezone === 'UTC') return 0; + if (currentTimezone === 'TAI') return getTAIOffsetAt(date); + const dtf = new Intl.DateTimeFormat('en-US', { + timeZone: currentTimezone, + year: 'numeric', month: '2-digit', day: '2-digit', + hour: '2-digit', minute: '2-digit', second: '2-digit', + hour12: false + }); + const parts = dtf.formatToParts(date).reduce((acc, p) => { + if (p.type !== 'literal') acc[p.type] = parseInt(p.value, 10); + return acc; + }, {}); + const utcTime = Date.UTC(parts.year, parts.month - 1, parts.day, + parts.hour, parts.minute, parts.second); + return (utcTime - date.getTime()) / 1000; +} + function formatSafeDate(rawDate, cobSeconds, intlOptions) { if (rawDate instanceof Date && !isNaN(rawDate.getTime())) { // Date is valid: optionally shift for TAI vs UTC, then format: @@ -607,9 +625,11 @@ function updateCalendar() { const cellEnd = cellCob + COBIE_UNITS.eonstrip; window.SPECIAL_EVENTS.forEach(ev => { if (ev.showMega === false) return; - const startCob = parseCobiets(ev.start || ev.cobie); - if (startCob === null) return; - const endCob = ev.end ? parseCobiets(ev.end) : Number.POSITIVE_INFINITY; + const baseStart = parseCobiets(ev.start || ev.cobie); + if (baseStart === null) return; + const tzShift = ev.shiftWithTimezone ? getTimezoneOffsetSeconds(fromCobiets(baseStart)) : 0; + const startCob = baseStart - tzShift; + const endCob = ev.end ? parseCobiets(ev.end) - tzShift : Number.POSITIVE_INFINITY; const unitVal = COBIE_UNITS[ev.unit] || COBIE_UNITS.cosmocycle; const interval = (ev.interval || 1) * unitVal; let duration = 0; @@ -714,9 +734,11 @@ function showEonstripDetail(index, startCob) { const end = startCob + COBIE_UNITS.eonstrip; window.SPECIAL_EVENTS.forEach(ev => { if (ev.showDetail === false) return; - const startCobEv = parseCobiets(ev.start || ev.cobie); - if (startCobEv === null) return; - const endCobEv = ev.end ? parseCobiets(ev.end) : Number.POSITIVE_INFINITY; + const baseStart = parseCobiets(ev.start || ev.cobie); + if (baseStart === null) return; + const tzShift = ev.shiftWithTimezone ? getTimezoneOffsetSeconds(fromCobiets(baseStart)) : 0; + const startCobEv = baseStart - tzShift; + const endCobEv = ev.end ? parseCobiets(ev.end) - tzShift : Number.POSITIVE_INFINITY; const unitVal = COBIE_UNITS[ev.unit] || COBIE_UNITS.cosmocycle; const interval = (ev.interval || 1) * unitVal; let duration = 0;