// Неделя ближайшей обжарки по минскому времени: обжарка по четвергам, доставка в пятницу. // Сегодня четверг — обжарка сегодня, иначе следующий четверг. export type WeekDay = { letter: string; /** число месяца */ date: number; /** YYYY-MM-DD */ iso: string; }; export type RoastWeek = { /** пн…вс недели обжарки */ days: WeekDay[]; roast: WeekDay; delivery: WeekDay; }; const LETTERS = ['ПН', 'ВТ', 'СР', 'ЧТ', 'ПТ', 'СБ', 'ВС'] as const; const DAY_MS = 86_400_000; /** Календарная дата в Минске как полночь UTC того же числа — удобно складывать дни. */ function minskDay(now: Date): Date { const parts = new Intl.DateTimeFormat('en-CA', { timeZone: 'Europe/Minsk', year: 'numeric', month: '2-digit', day: '2-digit', }).formatToParts(now); const get = (type: string) => Number(parts.find((p) => p.type === type)?.value); return new Date(Date.UTC(get('year'), get('month') - 1, get('day'))); } function toDay(d: Date, index: number): WeekDay { return { letter: LETTERS[index] ?? '', date: d.getUTCDate(), iso: d.toISOString().slice(0, 10) }; } export function getRoastWeek(now: Date = new Date()): RoastWeek { const today = minskDay(now); const weekday = (today.getUTCDay() + 6) % 7; // пн = 0 const untilThursday = (3 - weekday + 7) % 7; const roast = new Date(today.getTime() + untilThursday * DAY_MS); const monday = new Date(roast.getTime() - 3 * DAY_MS); const day = (i: number) => toDay(new Date(monday.getTime() + i * DAY_MS), i); return { days: LETTERS.map((_, i) => day(i)), roast: day(3), delivery: day(4) }; } /** «22.10» */ export function formatShortDate(day: WeekDay): string { const [, month, date] = day.iso.split('-'); return `${date}.${month}`; }