// Отображаем время в фиксированном поясе +3 (МСК) независимо от пояса браузера. const APP_TZ_OFFSET_MIN = 3 * 60; const p2 = (n: number) => String(n).padStart(2, "0"); // iso — корректный момент (бэкенд отдаёт UTC со смещением). Сдвигаем в +3 // и форматируем по UTC-частям, чтобы получить «настенное» время МСК. function shifted(iso: string): Date { return new Date(new Date(iso).getTime() + APP_TZ_OFFSET_MIN * 60_000); } // Склонение существительного при числе: plural(3, "игрок", "игрока", "игроков"). export function plural(n: number, one: string, few: string, many: string): string { const m10 = n % 10; const m100 = n % 100; if (m10 === 1 && m100 !== 11) return one; if (m10 >= 2 && m10 <= 4 && (m100 < 12 || m100 > 14)) return few; return many; } export function formatDuration(minutes: number | null | undefined): string { if (minutes == null) return "—"; const h = Math.floor(minutes / 60); const m = minutes % 60; if (h && m) return `≈ ${h} ч ${m} мин`; if (h) return `≈ ${h} ч`; return `≈ ${m} мин`; } export function formatTime(iso: string | null | undefined): string { if (!iso) return "—"; const d = shifted(iso); if (Number.isNaN(d.getTime())) return iso; return `${p2(d.getUTCDate())}.${p2(d.getUTCMonth() + 1)} ${p2(d.getUTCHours())}:${p2(d.getUTCMinutes())}`; } // «Дата игры» приходит date-only строкой (YYYY-MM-DD) — просто переставляем части, // без сдвига пояса (бэкенд уже посчитал дату в поясе приложения). export function formatDate(iso: string | null | undefined): string { if (!iso) return "—"; const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso); return m ? `${m[3]}.${m[2]}.${m[1]}` : iso; } export function formatDateTime(iso: string | null | undefined): string { if (!iso) return "—"; const d = shifted(iso); if (Number.isNaN(d.getTime())) return iso; return `${p2(d.getUTCDate())}.${p2(d.getUTCMonth() + 1)}.${d.getUTCFullYear()} ${p2(d.getUTCHours())}:${p2(d.getUTCMinutes())}`; }