Перед разработкой приложения Smart Timetable мы изучили очень много расписаний из разных стран и постарались сделать приложение удобным, гибким, легко настраиваемым. У нас большая аудитория: школьники, студенты, преподаватели, родители. Давайте посмотрим, что нам удалось выяснить и как мы это реализовали.
Одна неделя или еженедельное расписание
Классический распорядок занятий в школе, когда предметы повторяются каждую неделю. Необходимо выбрать день недели (понедельник, вторник, ...), указать время начала и конца занятия, и ваш предмет будет повторяться от недели к неделе.
![Расписание на одну неделю Расписание на одну неделю](https://habrastorage.org/getpro/habr/upload_files/62c/48f/c43/62c48fc433766a7a77e229b7c0840277.png)
Реализация такого расписания очень простая. Мы знаем индекс дня недели, на который назначен урок, и сверяем его с датой, которую просматривает пользователь. Например, понедельник имеет индекс "1", вторник "2" и так далее.
![Выбор дня недели для занятия Выбор дня недели для занятия](https://habrastorage.org/getpro/habr/upload_files/897/9c4/63c/8979c463c821ef4e3ff8458e3e4bfea7.png)
Предположим, что пользователь хочет узнать расписание на 5 сентября 2022 года. Любой современный язык программирования позволяет складывать и вычитать даты, получать месяц, год, день недели из даты и много другое.
Индекс дня недели для 5 сентября 2022 года равен "1". Значит все занятия, которые хранятся в базе данных с индексом дня "1" будут отображаться в эту дату.
Расписание на две и более недели
Такое расписание часто можно встретить в ВУЗах, когда предметы повторяются не каждую неделю, а чередуются с интервалом N недель. Недели могут называются по-разному: А/В, четная/нечетная, верхняя/нижняя, числитель/знаменатель, встречались и красная/синяя =))
В приложении Smart Timetable можно указать от 2-х до 4-х недель. Если понадобится большее количество, то мы изменим интерфейс для настройки недель через +/-, но об этом нас никто из пользователей не просил. Можем предположить, что этого функционала вполне достаточно.
![Расписание на две недели Расписание на две недели](https://habrastorage.org/getpro/habr/upload_files/f6b/0fc/4b9/f6b0fc4b9880129e4a1303bcdc1f3950.png)
Начало недели и текущая неделя нужны для того, чтобы корректно считать смену недель. В момент выбора текущей недели мы сохраняем дату, когда текущая неделя была выбрана, и от неё отталкиваемся при подсчёте недель.
Также важно давать пользователям возможность называть недели так, как им хочется. В приложении есть такая возможность. По умолчанию недели называются "Неделя 1", "Неделя 2" и т. д.
![Названия недель Названия недель](https://habrastorage.org/getpro/habr/upload_files/976/ab0/0a3/976ab00a3d2cbc7d53c7edc2a9ff75fa.png)
Для понимания, какие уроки показывать, теперь нам нужно хранить не только индекс дня, но и индекс недели. При добавлении занятия пользователь выбирает день недели и неделю. Названия недель берутся из настроек выше.
![Выбор недели и дня Выбор недели и дня](https://habrastorage.org/getpro/habr/upload_files/c56/b38/1f7/c56b381f7e0f513870cb9ade736eed40.png)
Другая или кастомная неделя
В странах СНГ такое расписание нам не встречалось, но вот в США и Канаде достаточно частое явление. Оно называется "shift schedule" или "скользящий график". Внутри нашей команды мы называем такой график "кастомная неделя". Как работает такое расписание?
Например, у нас 6-дневная учебная неделя со скользящим графиком. Это значит, что расписание повторяется каждые 6 дней, но выходные и праздничные дни не участвуют в подсчёте дней. Покажем это в виде таблицы.
Понедельник, 5 сентября | День 1 |
Вторник, 6 сентября | День 2 |
Среда, 7 сентября | Нерабочий день |
Четверг, 8 сентября | День 3 |
Пятница, 9 сентября | День 4 |
Суббота, 10 сентября | Выходной |
Воскресенье, 11 сентября | Выходной |
Понедельник, 12 сентября | День 5 |
Вторник, 13 сентября | День 6 |
Среда, 14 сентября | День 1 |
Для того, чтобы корректно отображать расписание, нам нужно знать индекс дня недели для занятий, аналогично тому, как если бы у нас было 1-недельное расписание. Но в случае 1-недельного расписания индекс дня мог быть от 0 (воскресенье) до 6 (суббота), а в случае кастомной недели мы имеем переменное количество дней, от 2 до 99.
![Гибкая настройка расписания Гибкая настройка расписания](https://habrastorage.org/getpro/habr/upload_files/1a3/489/b64/1a3489b64c0df59d98d5b40f7c937cc8.png)
Также нам нужно знать дату первого дня такой недели. От этой даты мы будем считать индекс дня выбранной пользователем даты, пропуская выходные и праздничные дни.
![Нерабочие дни кастомной недели Нерабочие дни кастомной недели](https://habrastorage.org/getpro/habr/upload_files/44f/5de/4a8/44f5de4a802714d38ab8c949d55115ce.png)
Иногда пользователи не понимают смысл кастомной недели. Выбирают цикл расписания 7 дней и называют их именами реальных дней недели: понедельник, вторник, среда и т.д. Так тоже можно, но стоит добавить хотя бы один нерабочий день, как сразу все последующие дни недели не будут соответствовать действительности.
И когда нам пишут в поддержку с вопросами по такому расписанию, мы помогаем пользователям перейти на обычный 1-недельный график, если это то, что им в действительности было нужно.
Повторение занятия, но не расписания
Что делать, если расписание у вас 1-недельное, но какие-то занятия повторяются с другим интервалом? Есть решение!
![Интервальное повторение занятий Интервальное повторение занятий](https://habrastorage.org/getpro/habr/upload_files/0b9/f05/486/0b9f054863caf51a9b42391574b1d05f.png)
Можно указать любой интервал от 1 до 99 дней, с которым ваше занятие будет повторяться. Здесь стоит обратить внимание на то, что такие занятия выпадают из обычного цикла расписания. Будь то 1, 2, 3, 4-х недельное или кастомное расписание, ваше занятие имеет свои настройки и повторяется так, как вы указали.
Занятие без повторений
Когда вам нужно добавить событие без повторений, например, встреча выпускников, занятие с репетитором, вы можете выбрать режим повторения "Нет". И тогда ваше занятие отобразится только в выбранную дату.
![Занятие без повторений Занятие без повторений](https://habrastorage.org/getpro/habr/upload_files/127/103/1e5/1271031e5ad7d703116a907208cda547.png)
Такое занятие, так же как и интервальное, выпадает из общего цикла расписания, поскольку имеет свои собственные настройки.
Учитель отменил занятие?
Такое бывает, но не удалять же нам занятие полностью из расписания. Для таких случаев есть функция однократного удаления.
![Опции удаления занятия Опции удаления занятия](https://habrastorage.org/getpro/habr/upload_files/a3c/5e8/7c0/a3c5e87c0f9f85a0c6e3250ca8edea98.png)
Когда занятие удаляется однократно, в нём хранится список дат, в которые занятие должно быть пропущено. Этот список вы можете увидеть при просмотре занятия в другой день. И даже можете вернуть обратно отменённое занятие.
![Список дат с отменой занятия Список дат с отменой занятия](https://habrastorage.org/getpro/habr/upload_files/48c/231/6a0/48c2316a0327cc56280da7478874c5e8.png)
Массовое добавление или копирование занятий
Пользователь может выбрать только один день для добавления занятия. Но ведь хочется добавить занятия везде и сразу. На эту тему мы долго дискутировали и продолжаем дискутировать с командой. Если дать выбор нескольких дней, то возникает вопрос выбора времени урока на каждый выбранный день.
Наша основная аудитория - это школьники и студенты. А у них почти никогда не бывает одинаковых предметов в одно и то же время. Например, редко бывает так, что Математика происходит первым уроком несколько дней в неделю. А если дать выбор времени на каждый день, то интерфейс окажется перегруженным.
![](https://habrastorage.org/getpro/habr/upload_files/50e/981/40a/50e98140afe8946b17d1382b4cd42440.png)
Копирование занятий является более гибким инструментом. Позволяет решить вопрос массового добавления уроков на несколько дней в разное время. Для каждой копии вы можете указать тип повторения: по дням недели, с интервалом, или вообще без повторения, и выбрать время урока.
Как сделать замену урока?
Это часто задаваемый вопрос. Реализовать замену урока через одно действие, без того, чтобы усложнить жизнь пользователю, у нас пока не получается. Мы всегда выбираем путь наименьшего сопротивления в вопросах дизайна и пользовательского интерфейса. Поэтому самым простым решением будет совершить два действия:
Однократно удалить занятие в нужный день
Добавить или скопировать занятие в этот же день, но без повторения
Итог
Расписание хоть и выглядит простым, но не всегда таким является. Мы, в приложении Smart Timetable, стараемся развивать простые инструменты для управления вашими занятиями и, в будущем, заданиями.
На данный момент задания реализованы по образу и подобию занятий, но это не всегда удобно, особенно если хочется видеть все задания списком. Мы работаем над этим.
Будем рады обратной связи ?