Метка: DateTime

  • Форматирование даты в PHP: «31 января 2025 г.» и работа с DateTimeImmutable

    1. Форматирование даты в «31 января 2025 г.»

    Есть несколько способов вывести дату в таком формате:

    Способ 1: IntlDateFormatter (рекомендуется)

    $date = new DateTimeImmutable('2025-01-31');
    $formatter = new IntlDateFormatter(
    	'ru_RU',
    	IntlDateFormatter::LONG,
    	IntlDateFormatter::NONE,
    	null,
    	null,
    	'd MMMM Y г.'
    );
    echo $formatter->format($date); // "31 января 2025 г.
    

    Способ 2: Вручную через массив месяцев

    $date = new DateTimeImmutable('2025-01-31');
    $months = [
    	1 => 'января', 2 => 'февраля', 3 => 'марта', 4 => 'апреля',
    	5 => 'мая', 6 => 'июня', 7 => 'июля', 8 => 'августа',
    	9 => 'сентября', 10 => 'октября', 11 => 'ноября', 12 => 'декабря'
    ];
    $day = $date->format('j');
    $month = $months[(int)$date->format('n')];
    $year = $date->format('Y');
    
    echo "$day $month $year г."; // "31 января 2025 г."
    

    2. Почему DateTimeImmutable, а не DateTime?

    Основные отличия:

    DateTimeDateTimeImmutable
    Изменяемый (мутабельный)Неизменяемый (иммутабельный)
    Методы (modify()add()sub()) меняют сам объектМетоды возвращают новый объект, не изменяя исходный
    Может привести к неожиданным изменениям в кодеПредсказуемость и безопасность

    Пример проблемы с DateTime:

    $date = new DateTime('2025-01-31');
    $newDate = $date->modify('+1 day');
    
    echo $date->format('Y-m-d'); // 2025-02-01 (оригинальный объект изменился!)
    echo $newDate->format('Y-m-d'); // 2025-02-01
    

    Пример с DateTimeImmutable:

    $date = new DateTimeImmutable('2025-01-31');
    $newDate = $date->modify('+1 day');
    
    echo $date->format('Y-m-d'); // 2025-01-31 (оригинал не изменился)
    echo $newDate->format('Y-m-d'); // 2025-02-01
    

    Когда использовать DateTimeImmutable?

    • Работа с API (чтобы избежать случайных изменений даты).
    • Многопоточные приложения (иммутабельность исключает race condition).
    • Сложная бизнес-логика, где важно сохранять исходные значения.

    Вывод

    1. Для форматирования дат в «31 января 2025 г.» лучше использовать IntlDateFormatter.
    2. DateTimeImmutable безопаснее, потому что не изменяет исходный объект.
    3. Выбор между DateTime и DateTimeImmutable зависит от задачи: если нужны гарантии неизменности — используйте Immutable.