const MOSCOW_TIMEZONE = 'Europe/Moscow'; const WEEKDAYS = ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']; const MONTHS = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']; function getMoscowDateString() { const formatter = new Intl.DateTimeFormat('en-CA', { timeZone: MOSCOW_TIMEZONE, year: 'numeric', month: '2-digit', day: '2-digit' }); return formatter.format(new Date()); } function parseISODate(value) { const [year, month, day] = value.split('-').map(Number); return new Date(year, month - 1, day); } function formatISODate(date) { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; } function addDays(dateStr, days) { const date = parseISODate(dateStr); date.setDate(date.getDate() + days); return formatISODate(date); } function formatDate(dateStr) { const date = parseISODate(dateStr); return `${WEEKDAYS[(date.getDay() + 6) % 7]}, ${date.getDate()} ${MONTHS[date.getMonth()]}`; } function calculateEndTime(startTime, durationMin) { const [hour, minute] = startTime.split(':').map(Number); const totalMinutes = hour * 60 + minute + durationMin; const endHour = Math.floor(totalMinutes / 60); const endMinute = totalMinutes % 60; return `${String(endHour).padStart(2, '0')}:${String(endMinute).padStart(2, '0')}`; } function renderDay(container, titleEl, dateStr, items, options = {}) { let titleText = formatDate(dateStr); if (options.today) { titleText = `Сегодня, ${titleText.toLowerCase()}`; } else if (options.tomorrow) { titleText = `Завтра, ${titleText.toLowerCase()}`; } titleEl.textContent = titleText; const tasks = items.filter((item) => item.kind === 'task'); const events = items .filter((item) => item.kind === 'event') .sort((a, b) => a.start_time.localeCompare(b.start_time)); if (!tasks.length && !events.length) { container.innerHTML = '
'; return; } const tasksHtml = tasks.length ? `