Сначала назовите временную сущность
publishedAt — произошедший момент, deadline — будущий момент, preferredTrainingTime — местное время пользователя, weeklyRule — правило повторения. Одного DATETIME недостаточно, чтобы выразить все варианты.
Фактические события хранятся в UTC и форматируются в timezone пользователя. Для будущего расписания может понадобиться исходный IANA zone id, потому что политические правила смещения меняются.
Преобразование времени
DateTimeImmutable уменьшает скрытые эффекты
modify и setTimezone возвращают новый объект, поэтому исходное значение не меняется через общую ссылку. Однако строковый parser принимает множество форм: на внешней границе используйте заданный формат и проверяйте ошибки разбора.
DateInterval описывает календарное или временное смещение согласно формату. Один месяц не равен фиксированным 30 дням. Для длительности тренировки проще целое число секунд, а не календарный interval.
DST ломает арифметику настенных часов
В некоторых зонах местное время повторяется при переводе часов назад или не существует при переходе вперёд. Тестируйте оба перехода, даже если основная аудитория находится в зоне без сезонного перевода: пользователь может путешествовать.
Расписание «каждый понедельник в 18:00» вычисляется в заданной зоне для каждой даты, а не прибавлением 7×24 часов к UTC-моменту бесконечно. Иначе локальный час сдвинется после DST.
База и приложение договариваются
Подключение MySQL получает известную timezone и код проверяет форму колонок. TIMESTAMP и DATETIME имеют разные диапазоны и преобразования; выбор фиксируется в схеме и тестах.
Не смешивайте текущую timezone процесса с timezone пользователя. Clock даёт now, а formatter получает явный DateTimeZone. Журнал сохраняет ISO 8601 и достаточно точности для корреляции событий.
Лабораторная работа
Смоделируйте напоминание о тренировке в локальное время пользователя и опубликованный instant. Добавьте тест перехода DST для Europe/Berlin и обычный сценарий Europe/Moscow.
Закрепите материал
Отметка, заметка, чек-лист и ответы остаются в localStorage этого браузера и не отправляются в аналитику.
Перелинковка со справочником
Проверка актуальности
- php-fig.orghttps://www.php-fig.org/psr/psr-20/Первичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
- dev.mysql.comhttps://dev.mysql.com/doc/refman/8.4/en/Первичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
Текст и схемы созданы для этого самоучителя без воспроизведения страниц, иллюстраций и листингов приложенной книги. Проверено: .