Даты в CMF Cotonti. Обзор
Рассмотриваем запись (ввод и преобразование), хранение (в базе данных) и вывод дат на сайте (форматирование и представление для пользователя).
Даты в CMF Cotonti: Запись, Хранение и Вывод (Представление)
Введение в работу с датами в Cotonti
Уважаемые начинающие разработчики и администраторы сайтов на базе Cotonti! В этой документации мы подробно разберем, как система управления контентом (CMF) Cotonti обрабатывает даты и время. Это важная тема, поскольку правильная работа с датами обеспечивает точность отображения информации, корректный учет часовых поясов пользователей и избежание ошибок при импорте или экспорте данных. Мы начнем с конкретных примеров из исходного кода и базы данных, а затем перейдем к общим принципам. Это поможет вам понять картину шаг за шагом: от ввода даты в систему до ее представления на экране. Мы рассмотрим запись (ввод и преобразование), хранение (в базе данных) и вывод (форматирование для пользователя). Особое внимание уделим примерам, чтобы вы могли увидеть, как даты выглядят на каждом этапе в различных ситуациях.
Cotonti использует стандартные подходы PHP для работы с датами, но с учетом специфики веб-приложений: даты хранятся в универсальном формате для легкости расчетов, а вывод адаптируется под язык и часовой пояс. Это делает систему гибкой для международных проектов. Давайте разберем процесс по частям.
Запись дат: Ввод и преобразование в систему
Запись дат в Cotonti начинается с момента, когда пользователь или администратор вводит информацию, например, при создании страницы или события. Система не хранит даты в текстовом виде (как "2023-12-31"), а преобразует их в числовой формат — UNIX timestamp. Это целое число, представляющее секунды, прошедшие с 1 января 1970 года (эпоха UNIX). Такое преобразование происходит с помощью функций вроде cot_date2stamp, которая анализирует строку даты и возвращает timestamp или null, если дата недействительна.
Например, представьте, что вы создаете новую страницу в модуле "Pages". В форме вы указываете дату начала как "2026-02-28 12:00:00". Функция cot_date2stamp преобразует это в timestamp: примерно 1709208000 (это зависит от часового пояса, но для UTC это будет именно так). Если дата пустая или равна "0000-00-00", функция вернет null, чтобы избежать ошибок. В SQL-запросах для вставки данных, как в примере установки модуля, используются выражения вроде UNIX_TIMESTAMP(), которое автоматически генерирует текущий timestamp, например 1709208000 для текущего момента.
В ситуациях с импортом данных из внешних источников, таких как CSV-файлы, даты также должны быть преобразованы. Если в файле дата указана как "2026-02-28", система применит cot_date2stamp с указанным форматом (по умолчанию MySQL-формат "Y-m-d"). Результат — timestamp, готовый для хранения. Если формат другой, например "28.02.2026", нужно явно указать формат в функции, чтобы избежать ошибок парсинга.
Хранение дат: В базе данных
В Cotonti даты хранятся в таблицах базы данных как целые числа (тип int UNSIGNED), что обеспечивает компактность и скорость расчетов. Взгляните на структуру таблицы cot_pages: поля page_date, page_begin, page_expire — все они int UNSIGNED NOT NULL DEFAULT '0'. Это значит, что по умолчанию они равны 0, что соответствует 1 января 1970 года 00:00:00 UTC. Но 0 используется редко, так как реальные даты обычно положительные числа от миллионов до миллиардов.
Например, в INSERT-запросе для cot_pages вы видите значения вроде 1639236600 (это 12 декабря 2021 года около 00:10:00 UTC), 1699716120 (11 ноября 2023 года около 12:42:00 UTC) и 1704948992 (11 января 2024 года около 08:56:32 UTC). Эти числа — это timestamps, полученные из реальных дат. Хранение в таком виде позволяет легко сравнивать даты (например, page_begin < page_expire), сортировать записи по времени и выполнять арифметические операции, как добавление часов для учета часовых поясов.
В других таблицах, таких как cot_auth или cot_structure, даты могут не использоваться напрямую, но если они есть, принцип тот же. Важно: база данных MySQL позволяет хранить 0 или положительные числа, но не отрицательные (из-за UNSIGNED), так что даты до 1970 года хранятся с осторожностью или в другом формате.
Вывод дат: Представление пользователю
Вывод дат — это финальный этап, где числовой timestamp преобразуется в читаемый текст. Cotonti использует функцию cot_date, которая аналогична PHP date(), но с локализацией и учетом часового пояса пользователя. Функция cot_getUserTimeZone возвращает объект DateTimeZone на основе настроек пользователя или дефолтного (обычно UTC).
Например, timestamp 1709208000 (28 февраля 2026 года 12:00:00 UTC) при выводе с форматом "Y-m-d H:i:s" и учетом пояса пользователя (+3 часа, Москва) станет "2026-02-28 15:00:00". Если использовать локализованный формат из $Ldt, то для русского языка это может быть "28 февраля 2026 г., 15:00". Функция заменяет английские названия дней и месяцев на локализованные, как "Monday" на "Понедельник".
В шаблонах Cotonti даты часто выводятся с помощью тегов вроде {PAGE_BEGIN|cot_date('d F Y')}, где timestamp из базы преобразуется на лету.
Примеры дат на всех этапах и в различных ситуациях
Чтобы вы полностью разобрались, давайте посвятим значительную часть обзора примерам. Мы возьмем реальные сценарии из Cotonti и пройдем путь от ввода до вывода. Это поможет увидеть, как даты меняются в зависимости от контекста.
Пример 1: Создание страницы с датой начала события. Ввод: Пользователь в форме указывает "2026-02-28" (формат Y-m-d). Преобразование: cot_date2stamp("2026-02-28", "Y-m-d") возвращает 1709208000 (timestamp для 00:00:00 UTC). Хранение: В таблице cot_pages поле page_begin = 1709208000. Вывод: cot_date("d.m.Y", 1709208000, true) с учетом пояса +3 часа дает "28.02.2026". Если без пояса — "28.02.2026" в UTC. В шаблоне: "Событие начинается 28 февраля 2026 года".
Пример 2: Импорт события из CSV с полной датой и временем. Ввод в CSV: "2023-11-11 12:42:00" (формат Y-m-d H:i:s). Преобразование: cot_date2stamp("2023-11-11 12:42:00") = 1699716120. Хранение: page_expire = 1699716120 в cot_pages. Вывод: cot_date("F j, Y, g:i a", 1699716120) для английского — "November 11, 2023, 12:42 pm". Для русского: "11 ноября 2023, 12:42" после локализации.
Пример 3: Текущая дата при установке системы. Ввод: Автоматически через UNIX_TIMESTAMP() в SQL. Преобразование: Не нужно, SQL возвращает timestamp, например 1704948992 (11 января 2024, 08:56:32 UTC). Хранение: page_date = 1704948992. Вывод: cot_date("Y-m-d", 1704948992, false) = "2024-01-11". С поясом пользователя (-5 часов, Нью-Йорк): "2024-01-10" (если время сдвигается назад).
Пример 4: Дата до эпохи UNIX (историческое событие). Ввод: "1960-01-01". Преобразование: cot_date2stamp("1960-01-01") = -315360000 (отрицательное, но Cotonti избегает, так как поля UNSIGNED). Рекомендуется хранить как положительное или в строковом поле. Хранение: Если принудительно, page_begin = 0 (минимум). Вывод: cot_date("Y-m-d", 0) = "1970-01-01". Для старых дат лучше использовать отдельные поля.
Пример 5: Нулевая или пустая дата. Ввод: "" (пустая строка) или "0000-00-00". Преобразование: cot_date2stamp возвращает null. Хранение: page_expire = 0 (дефолт). Вывод: cot_date("d F Y", 0) = "01 января 1970". Но часто в шаблонах проверяют if > 0, чтобы показать "Не указано".
Пример 6: Событие с окончанием через день. Ввод: Начало "2026-02-28 10:00:00" → 1709200800; Окончание рассчитывается +86400 секунд → 1709287200. Хранение: page_begin = 1709200800, page_expire = 1709287200. Вывод: "С 28.02.2026 10:00 по 01.03.2026 10:00" после форматирования.
Пример 7: Учет пояса в многоязычном сайте. Ввод: Timestamp 1639236600 (12 декабря 2021, 00:10:00 UTC). Хранение: Как есть. Вывод: Для пользователя в +3: cot_date("H:i d.m.Y") = "03:10 12.12.2021". Для +0: "00:10 12.12.2021". Локализация: "03:10 12 декабря 2021".
Пример 8: Парсинг нестандартного формата. Ввод: "28 февраля 2026" (русский формат). Преобразование: cot_date2stamp("28 февраля 2026", "d F Y") = 1709208000 (нужно указать формат). Хранение и вывод: Как в примере 1.
Пример 9: Расчет разницы дат. Хранение: page_begin = 1709208000, page_date = 1704948992. Расчет: $diff = page_begin - page_date; // примерно 4259008 секунд (около 49 дней). Вывод: "До события осталось " . floor($diff / 86400) . " дней".
Пример 10: Дата в системной категории. В SQL установки: page_date = UNIX_TIMESTAMP() → например 1709208000. Хранение: В cot_pages. Вывод: В админке как "2026-02-28".
Эти примеры охватывают типичные ситуации: от простого ввода до расчетов. Вы можете протестировать их в своей установке Cotonti, чтобы увидеть результаты.
Почему в базе данных нельзя хранить записи вида '0000-00-00', '0000-00-00 00:00:00', '0000-00-00 00:00'
В Cotonti поля для дат — это int, а не datetime или date в MySQL. Хранение строк вроде '0000-00-00' невозможно, так как тип int ожидает числа. Даже если поле было бы datetime, такие значения вызывают проблемы: MySQL в строгом режиме (SQL_MODE=STRICT) отвергает их как недействительные даты, приводя к ошибкам вставки. Кроме того, они не соответствуют стандартам ISO 8601 и могут нарушать сортировку или расчеты (например, datediff вернет неверные результаты). Cotonti использует null или 0 для "неизвестной" даты, что безопаснее и позволяет избежать крахов скриптов при преобразованиях.
Почему при импорте статей или товаров в Cotonti из CSV/Excel нельзя использовать записи вида '0000-00-00', '0000-00-00 00:00:00', '0000-00-00 00:00'
При импорте из CSV или Excel даты читаются как строки, но Cotonti ожидает их преобразования в timestamp. Строки вроде '0000-00-00' в cot_date2stamp возвращают null, что приводит к хранению 0, искажая данные (вместо "не указано" получится 1970-01-01). Excel может интерпретировать такие строки как текст, а не даты, вызывая ошибки парсинга. В больших импортах это приводит к потере данных или сбоям скриптов. Кроме того, если импорт через SQL, MySQL отвергнет такие значения в int-полях, вызвав ошибку "Out of range value". Лучше преобразовывать заранее в числа.
Рекомендации по формированию дат из '0000-00-00' в формат UNIX timestamp и конвертации
Если у вас данные с '0000-00-00' (или подобными), преобразуйте их в timestamp вроде 1639236600 для импорта в Cotonti. Поскольку такие строки означают "не указано", используйте 0 как замену — это просто и соответствует дефолту полей. Для конвертации: в PHP примените cot_date2stamp('0000-00-00') → null, затем if null, set 0. В Excel формула: =ЕСЛИ(A1="0000-00-00";0;ДАТАЗНАЧ(A1)-ДАТА(1970;1;1)*86400), где A1 — ячейка с датой (это даст timestamp). Обратно: из timestamp в строку используйте cot_stamp2date(1639236600) → '2021-12-12'. Для батч-конвертации в CSV используйте скрипт PHP: читайте файл, применяйте cot_date2stamp, записывайте числа. Если дата реальна, как '2021-12-12', конвертируйте в 1639236600; для '0000-00-00' — в 0. Это упрощает импорт: в CSV пишите числа напрямую в колонки вроде page_begin. Тестируйте на малых файлах, чтобы избежать потерь.
Комментарии (0)
Автор контента
Оффлайн
Sodium Carbonate
Последняя авторизация: 19.07.2026 01:13
- Страница размещена: 01.03.2026 01:16
- Последнее обновление: 01.03.2026 01:16