// Labels for the chart's times. Intraday times are New York wall-clock seconds read as UTC (see plan.ts), // so formatting them in UTC shows New York time, daylight saving included. Dates are YYYY-MM-DD. const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] type AnyTime = number | string | { year: number; month: number; day: number } function parts(time: AnyTime) { if (typeof time === 'number') { const d = new Date(time * 1000) return { y: d.getUTCFullYear(), m: d.getUTCMonth(), d: d.getUTCDate(), hh: d.getUTCHours(), mm: d.getUTCMinutes(), hasTime: true } } if (typeof time === 'string') { const [y, m, d] = time.split('-').map(Number) return { y, m: m - 1, d, hh: 0, mm: 0, hasTime: false } } return { y: time.year, m: time.month - 1, d: time.day, hh: 0, mm: 0, hasTime: false } } const pad = (n: number) => String(n).padStart(2, '0') /** The crosshair's label: "Wed Oct 15 '26 09:30 ET" intraday, "Oct 15 '26" for a day. */ export function crosshairLabel(time: unknown): string { const p = parts(time as AnyTime) const date = `${MONTHS[p.m]} ${p.d} '${String(p.y).slice(2)}` if (!p.hasTime) return date const weekday = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][new Date(Date.UTC(p.y, p.m, p.d)).getUTCDay()] return `${weekday} ${date} ${pad(p.hh)}:${pad(p.mm)} ET` } /** A tick on the time axis. markType is lightweight-charts' TickMarkType: 0 year, 1 month, 2 day, 3 and 4 time. */ export function tickLabel(time: unknown, markType: number): string { const p = parts(time as AnyTime) if (markType === 0) return String(p.y) if (markType === 1) return MONTHS[p.m] if (markType === 2 || !p.hasTime) return `${MONTHS[p.m]} ${p.d}` return `${pad(p.hh)}:${pad(p.mm)}` }