Калькулятор дней
Запрос седьмой:
Мне нравится автоматизация рутинных задач. Давай сделаем сервис, который позволит рассчитать разницу между датами. У пользователя должна быть возможность выбрать дату начала и конца события. Отдельно галочками можно указать, учитывать ли начальную и конечную дату. В результатах вывести информацию об изначальном запросе (с какой по какую дату производился подсчет), а ниже показать число дней; число рабочих дней; количество недель, количество месяцев, количество лет между указанными датами. Сделай современный интерфейс, с красивыми блоками, используй градиент. Цветовая палитра: #F266CD; #010E26; #63F287; #D3F263
Вы можете сразу перейти по ссылке и посмотреть результат.
Отличный выбор! Я сделаю интерфейс с современным дизайном и аккуратной структурой. Он будет включать:
-
Поля для выбора дат.
-
Чекбоксы для учета граничных дат.
-
Красивые карточки с результатами (дни, рабочие дни, недели, месяцы, годы).
-
Градиентный фон с твоими цветами.
Сейчас создам HTML + CSS + jаvascript для фронта, а затем PHP-скрипт для вычислений. Начнем с интерфейса!
index.html
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Калькулятор разницы дат</title>
<style>
body {
background: linear-gradient(135deg, #F266CD, #010E26);
font-family: sans-serif;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.container {
background: #D3F263;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
width: 90%;
max-width: 400px;
text-align: left;
color: #010E26;
}
label {
display: block;
margin: 10px 0 5px;
}
input[type="date"],
button {
width: 100%;
padding: 8px;
border: 1px solid #010E26;
border-radius: 4px;
box-sizing: border-box;
}
button {
background: #63F287;
border: none;
cursor: pointer;
margin-top: 15px;
font-size: 16px;
}
.result {
margin-top: 15px;
padding: 10px;
background: #F266CD;
border-radius: 4px;
color: #fff;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<h2>Калькулятор разницы дат</h2>
<label for="start-date">Дата начала:</label>
<input type="date" id="start-date">
<label for="end-date">Дата окончания:</label>
<input type="date" id="end-date">
<label><input type="checkbox" id="include-start"> Учитывать начальную дату</label>
<label><input type="checkbox" id="include-end"> Учитывать конечную дату</label>
<button onclick="calculateDifference()">Рассчитать</button>
<div class="result" id="result"></div>
</div>
<script>
function calculateDifference() {
const start = document.getElementById('start-date').value;
const end = document.getElementById('end-date').value;
const includeStart = document.getElementById('include-start').checked;
const includeEnd = document.getElementById('include-end').checked;
if (!start || !end) {
document.getElementById('result').innerText = 'Выберите корректные даты';
return;
}
const params = new URLSearchParams({ start, end, includeStart, includeEnd });
fetch('calculate.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString()
})
.then(res => res.json())
.then(data => {
if (data.error) {
document.getElementById('result').innerText = data.error;
return;
}
document.getElementById('result').innerHTML = `
<p>Запрос: ${data.start} - ${data.end}</p>
<p>Дней: ${data.days}</p>
<p>Рабочих дней: ${data.workdays}</p>
<p>Недель: ${data.weeks}</p>
<p>Месяцев: ${data.months}</p>
<p>Лет: ${data.years}</p>
`;
})
.catch(() => {
document.getElementById('result').innerText = 'Ошибка запроса';
});
}
</script>
</body>
</html>
calculate.php
<?php
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['error' => 'Неверный метод запроса']);
exit;
}
$start = $_POST['start'] ?? null;
$end = $_POST['end'] ?? null;
$includeStart = isset($_POST['includeStart']) ? filter_var($_POST['includeStart'], FILTER_VALIDATE_BOOLEAN) : false;
$includeEnd = isset($_POST['includeEnd']) ? filter_var($_POST['includeEnd'], FILTER_VALIDATE_BOOLEAN) : false;
if (!$start || !$end) {
echo json_encode(['error' => 'Отсутствуют параметры даты']);
exit;
}
try {
$startDate = new DateTime($start);
$endDate = new DateTime($end);
} catch (Exception $e) {
echo json_encode(['error' => 'Неверный формат даты']);
exit;
}
// Если даты перепутаны, меняем их местами
if ($startDate > $endDate) {
$temp = $startDate;
$startDate = $endDate;
$endDate = $temp;
}
// Если даты одинаковые
if ($startDate->format('Y-m-d') === $endDate->format('Y-m-d')) {
$totalDays = ($includeStart || $includeEnd) ? 1 : 0;
$workdays = ($startDate->format('N') < 6 && ($includeStart || $includeEnd)) ? 1 : 0;
} else {
// Перебираем каждый день в интервале
$totalDays = 0;
$workdays = 0;
$current = clone $startDate;
while ($current <= $endDate) {
$currentStr = $current->format('Y-m-d');
$isStart = ($currentStr === $startDate->format('Y-m-d'));
$isEnd = ($currentStr === $endDate->format('Y-m-d'));
$includeDay = true;
if ($isStart && !$includeStart) {
$includeDay = false;
}
if ($isEnd && !$includeEnd) {
$includeDay = false;
}
if ($includeDay) {
$totalDays++;
if ($current->format('N') < 6) { // 1 - понедельник, 7 - воскресенье
$workdays++;
}
}
$current->modify('+1 day');
}
}
// Количество недель (целых)
$weeks = $totalDays > 0 ? floor($totalDays / 7) : 0;
// Разница месяцев и лет по DateTime::diff
$diff = $startDate->diff($endDate);
$years = $diff->y;
$months = $years * 12 + $diff->m;
$response = [
'start' => $startDate->format('Y-m-d'),
'end' => $endDate->format('Y-m-d'),
'days' => $totalDays,
'workdays' => $workdays,
'weeks' => $weeks,
'months' => $months,
'years' => $years
];
echo json_encode($response);
Объяснение:
-
index.html:
– Минималистичный дизайн с упрощённым стилем.
– При нажатии кнопки данные отправляются через fetch() вcalculate.php
с параметрами: даты и чекбоксы. -
calculate.php:
– Проверяется корректность метода и параметров.
– Если даты перепутаны, они меняются местами.
– При равных датах учитывается выбор включать их.
– Для разных дат происходит перебор дней с учётом чекбоксов, что позволяет правильно посчитать общее число дней и рабочих (понедельник–пятница).
– Дополнительно вычисляются недели (целых), месяцы и годы по стандартному diff.
Попробуй разместить оба файла на своём хостинге, и сервис должен заработать. Если возникнут вопросы или потребуются доработки, пиши!