В последнее время, мне не так часто приходится сталкиваться с интересными задачками в программировании. Львиную долю занимают только рутинные таски по работе, а как известно, клиенты редко подкидывают занимательные задачи, да и в процессе работы не всегда получается насладиться программированием, и тем более описать этот опыт в статьях. Но сегодня мне попалась довольно интересная «головоломка» — генерация календаря на месяц, решением которой я хочу поделиться в статье.
Генерация календаря на месяц. Условие задачи
Условие задачи заключается в реализации вывода календаря для любого месяца и года. При чем, выводить нужно рядами по одной недели, чтобы на выходе получился полноценный календарь. Поскольку первый день месяца не всегда выпадает на понедельник, нужно сделать проверку и в таких случаях заполнять пустые ячейки календаря прочерками. Тоже самое с последней неделей – необходимо дополнить пустые ячейки прочерками. Так же нужно дописывать ноль для цифр от 1 до 9. И чтобы было еще интереснее, нужно постараться оформить код максимально просто, без лишних циклов и условий.
Функция генерации календаря на php
У меня получилось написать скрипт с использованием одного цикла и пары условий, возможно, есть решения еще проще. Если вы знаете, как можно еще упростить код, то присылайте свои варианты.
Ниже приведен код функции с подробными комментариями:
/** * Получение календаря на месяц * @var int $month - номер месяца * @var int $year - год * * @return string */ function get_month($month, $year){ // получение количества дней в месяце и номер дня недели $rows = explode(', ', date('t, w', mktime(0, 0, 0, $month, 1, $year))); $rows[1] = (int)trim($rows[1]) - 1; if ($rows[1] < 0) $rows[1] = 6; // считаем количество мест в календаре $all_places = (ceil(($rows[0] + $rows[1]) / 7) * 7 - ($rows[0] + $rows[1])) + ($rows[0] + $rows[1]); // составление календаря $str = ""; for($i = 1; $i <= $all_places; $i++){ if( ($i <= $rows[1]) OR $i > ($rows[0] + $rows[1])){ $str .= "__ "; // прочерки для пустых мест }else{ $str .= str_pad(($i - $rows[1]), 2, '0', STR_PAD_LEFT) . " "; } if(($i % 7) == 0){ $str = trim($str); // убираем лишние пробелы в конце if($i < $all_places){ $str .= PHP_EOL; // в конце каждой недели перенос строки } } } return $str; }
И примеры использования:
// вывод календаря на февраль 2018 в браузере $str = get_month(2, 2018); // для вывода в браузере вместо переноса строки <br> $str = str_replace(PHP_EOL, "<br>", $str); echo $str;
// запись календаря на февраль 2018 в файл output.txt $str = get_month(2, 2018); $fp = fopen('output.txt', 'w+'); fwrite($fp, $str); fclose($fp);
Послесловие
Валерий Шиян, спасибо тебе за идею статьи. Если у вас тоже есть идеи или предложения по статьям, можете писать на почту, во ВКонтакте или в комментариях.
Классная реализация, спасибо !