Получение дня недели по дате в PHP: от простых функций до локализации
Получение дня недели из даты в PHP: обзор методов
В PHP существует несколько способов получить день недели из даты. Выбор подходящего варианта зависит от версии интерпретатора, необходимости локализации, производительности и стиля программирования. Рассмотрим наиболее популярные решения с примерами и разбором возможных проблем.
Основной рекомендуемый способ: класс DateTime
Объектно-ориентированный подход с использованием DateTime и метода format() является самым гибким и безопасным. Он поддерживает часовые пояса, произвольные манипуляции с датами и работает корректно на любых системах.
<?php
$date = new DateTime('2025-03-20');
echo $date->format('l'); // Thursday (полное имя на английском)
echo $date->format('D'); // Thu (сокращенное)
echo $date->format('N'); // 4 (1-7, по стандарту ISO, понедельник = 1)
echo $date->format('w'); // 4 (0-6, воскресенье = 0, суббота = 6)
?>
Php форматирование даты (php: форматирование даты)
Для получения числового дня недели чаще всего используют N (ISO 8601) или w (американский стандарт). Выбор зависит от бизнес-логики: в России и Европе предпочтительнее ISO (понедельник = 1).
Как получить день недели из строки с помощью date() и strtotime()?
Классический процедурный подход. Функция strtotime() преобразует текстовое представление даты в Unix-метку, а date() форматирует её.
<?php
$timestamp = strtotime('2025-03-20');
echo date('l', $timestamp); // Thursday
echo date('N', $timestamp); // 4
?>
Php дата день недели (php: получить день недели из даты)
Цель использования: быстрые однострочные решения в скриптах, где не требуется манипуляция с датами. Случаи: простой вывод, проверка дня недели в древних проектах.
Проблемы:
- Ограничение диапазона 1901-2038 на 32-битных системах (Unix-метка 32 бит).
- Необходимость дважды вызывать strtotime при изменении даты.
- Сложность с часовыми поясами (date использует серверную временную зону).
Как получить массив компонентов даты, включая день недели, через getdate()?
Функция getdate() возвращает ассоциативный массив с полями: wday (числовой день недели 0-6), weekday (полное название на английском), yday (день года) и другие.
<?php
$info = getdate(strtotime('2025-03-20'));
echo $info['wday']; // 4
echo $info['weekday']; // Thursday
?>
Php изменение даты (php: изменение даты (модификация))
Цель: удобство, когда нужно одновременно получить несколько характеристик даты. Часто используется в отладке или при генерации календарей.
Как получить день недели на русском языке с помощью устаревшей strftime()?
Функция strftime() позволяла форматировать дату с учётом локали. Она объявлена устаревшей в PHP 8.1, но всё ещё встречается в старых проектах.
<?php
setlocale(LC_TIME, 'ru_RU.UTF-8');
echo strftime('%A', strtotime('2025-03-20')); // четверг
?>
Php дата числом (php: получить дату в числовом формате)
Проблемы: функция удалена в PHP 9.0; требуется наличие локали на сервере; результат зависит от настроек системы.
Как получить локализованное название дня недели на современном PHP (IntlDateFormatter)?
Если нужно имя дня на определённом языке (русский, немецкий и т.д.), используйте расширение intl и класс IntlDateFormatter.
<?php
$fmt = new IntlDateFormatter('ru_RU', IntlDateFormatter::NONE, IntlDateFormatter::NONE, null, null, 'EEEE');
echo $fmt->format(new DateTime('2025-03-20')); // четверг
?>
создание даты php (php: создание объекта даты)
Цель: интернационализация приложений, поддержка нескольких языков без ручных массивов переводов. Необходимо установленное расширение intl.
Как вычислить день недели математически (алгоритм Зеллера)?
Ручное вычисление может быть полезным, когда недоступны встроенные функции (например, в микроконтроллерах или при парсинге очень старых дат).
<?php
function dayOfWeek($dateStr) {
$parts = explode('-', $dateStr);
$year = (int)$parts[0];
$month = (int)$parts[1];
$day = (int)$parts[2];
if ($month < 3) { $month += 12; $year--; }
$k = $year % 100;
$j = floor($year / 100);
$h = ($day + floor(13*($month+1)/5) + $k + floor($k/4) + floor($j/4) - 2*$j) % 7;
// 0=суббота, 1=воскресенье, ..., 6=пятница (по Зеллеру)
$days = ['Sat','Sun','Mon','Tue','Wed','Thu','Fri'];
return $days[$h];
}
echo dayOfWeek('2025-03-20'); // Thu
?>
Цель: образовательная или работа в средах без PHP-функций работы с датами.
Как получить день недели с помощью библиотеки Carbon?
Популярное расширение DateTime, упрощающее работу с датами.
<?php
require 'vendor/autoload.php';
use Carbon\Carbon;
$dt = Carbon::parse('2025-03-20');
echo $dt->dayOfWeek; // 4 (понедельник=0, воскресенье=6)
echo $dt->dayName; // Thursday
echo $dt->shortDayName; // Thu
?>
Цель: быстрая разработка, читаемый код, дополнительные методы (diffForHumans, startOfWeek и т.п.).
Типичные проблемы и ошибки
- Путаница форматов w и N: w возвращает 0 для воскресенья, N возвращает 7. Неправильный выбор приводит к логическим ошибкам (например, проверка выходных).
- Влияние часового пояса: Если не указана временная зона, DateTime может интерпретировать дату как '2025-03-20 00:00:00' в серверном timezone. При смене зоны день может сместиться. Всегда явно задавайте часовой пояс (например, new DateTimeZone('Europe/Moscow')).
- Отсутствие локали при использовании strftime(): Если локаль не установлена, strftime вернёт английское название. На сервере может не быть нужной локали (например, 'ru_RU.UTF-8'), что вызовет ошибку или пустую строку.
- Доверие к несуществующим датам: Передача '2025-02-30' приведёт к ошибке или unexpected result. Всегда проверяйте входящие данные.
- Устаревшие функции: Использование strftime() в новых проектах вызовет предупреждения и перестанет работать в PHP 9.0.
- Производительность: Создание нового объекта DateTime внутри цикла может замедлить скрипт. Для массовых вычислений используйте метки времени или Singleton-объект.
Расширенные примеры получения дня недели
Пример 1: Получение дня недели из Unix timestamp с учётом часового пояса
<?php
$timestamp = 1742428800; // 2025-03-20 00:00:00 UTC
$date = new DateTime('@' . $timestamp);
$date->setTimezone(new DateTimeZone('Europe/Moscow'));
echo $date->format('l'); // Thursday
?>
Результат:
Thursday
Пример 2: Локализованное название дня с IntlDateFormatter и временем
<?php
$date = new DateTime('2025-03-20 15:30:00', new DateTimeZone('Europe/Moscow'));
$fmt = new IntlDateFormatter('ru_RU', IntlDateFormatter::FULL, IntlDateFormatter::SHORT, 'Europe/Moscow', IntlDateFormatter::GREGORIAN, 'EEEE');
echo $fmt->format($date); // четверг
?>
четверг
Пример 3: Проверка, является ли дата выходным днём
<?php
function isWeekend($dateStr) {
$date = new DateTime($dateStr);
$day = (int)$date->format('N'); // 1-7
return $day >= 6;
}
var_dump(isWeekend('2025-03-20')); // false (четверг)
var_dump(isWeekend('2025-03-22')); // true (суббота)
?>
bool(false) bool(true)
Пример 4: Получение дня недели в нескольких локалях
<?php
$date = new DateTime('2025-03-20');
$locales = ['en_US', 'ru_RU', 'de_DE', 'fr_FR'];
foreach ($locales as $locale) {
$fmt = new IntlDateFormatter($locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, null, null, 'EEEE');
echo $locale . ': ' . $fmt->format($date) . PHP_EOL;
}
?>
en_US: Thursday ru_RU: четверг de_DE: Donnerstag fr_FR: jeudi
Пример 5: Использование Carbon для получения и манипуляции днём недели
<?php
// Требуется composer require nesbot/carbon
use Carbon\Carbon;
$dt = Carbon::parse('2025-03-20');
echo 'День недели (0-6): ' . $dt->dayOfWeek . PHP_EOL; // 4
echo 'Полное имя: ' . $dt->dayName . PHP_EOL; // Thursday
echo 'Короткое имя: ' . $dt->shortDayName . PHP_EOL; // Thu
echo 'Является выходным: ' . ($dt->isWeekend() ? 'Да' : 'Нет') . PHP_EOL;
?>
День недели (0-6): 4 Полное имя: Thursday Короткое имя: Thu Является выходным: Нет
Пример 6: Вычисление следующего понедельника с помощью DateTime
<?php
$date = new DateTime('2025-03-22'); // суббота
$nextMonday = clone $date;
$dayOfWeek = (int)$date->format('N'); // 6 (суббота)
$daysToAdd = (8 - $dayOfWeek) % 7;
if ($daysToAdd === 0) $daysToAdd = 7;
$nextMonday->modify("+$daysToAdd days");
echo $nextMonday->format('Y-m-d l'); // 2025-03-24 Monday
?>
2025-03-24 Monday
Пример 7: Получение дня недели из строки с произвольным форматом (через createFromFormat)
<?php
$date = DateTime::createFromFormat('d/m/Y', '20/03/2025');
echo $date->format('l'); // Thursday
?>
Thursday