/** * Date / time форматирование для UI мессенджера. * * Все функции принимают **unix-seconds** (совместимо с `Message.timestamp`, * который тоже в секундах). Для ms-таймштампов делаем нормализацию внутри. */ // ─── Русские месяцы (genitive для "17 июня 2025") ──────────────────────────── const RU_MONTHS_GEN = [ 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря', ]; function sameDay(a: Date, b: Date): boolean { return ( a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate() ); } /** * Day-bucket label для сепараторов внутри чата. * "Сегодня" / "Вчера" / "17 июня 2025" * * @param ts unix-seconds */ export function dateBucket(ts: number): string { const d = new Date(ts * 1000); const now = new Date(); const yday = new Date(); yday.setDate(now.getDate() - 1); if (sameDay(d, now)) return 'Сегодня'; if (sameDay(d, yday)) return 'Вчера'; return `${d.getDate()} ${RU_MONTHS_GEN[d.getMonth()]} ${d.getFullYear()}`; } /** * Короткое relative-time под углом bubble ("29m", "14m", "3h", "2d", "12:40"). * * @param ts unix-seconds */ export function relTime(ts: number): string { const now = Date.now(); const diff = now - ts * 1000; if (diff < 60_000) return 'now'; if (diff < 3_600_000) return `${Math.floor(diff / 60_000)}m`; if (diff < 24 * 3_600_000) return `${Math.floor(diff / 3_600_000)}h`; if (diff < 7 * 24 * 3_600_000) return `${Math.floor(diff / (24 * 3_600_000))}d`; const d = new Date(ts * 1000); return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`; } /** * Похоже на relTime, но принимает как unix-seconds, так и unix-ms. * Используется в chat-list tiles (там timestamp бывает в ms от addedAt). */ export function formatWhen(ts: number): string { // Heuristic: > 1e12 → уже в ms, иначе seconds. const sec = ts > 1e12 ? Math.floor(ts / 1000) : ts; return relTime(sec); } /** "HH:MM" — одна и та же локаль, без дня. */ export function formatHM(ts: number): string { const d = new Date(ts * 1000); return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`; }