popov . dev

Main

Library

Articles

Работа с датой и...

Работа с датой и временем в PHP

Невозможно стать разработчиком без знаний о манипуляциях с датой и временем. Хотите вы того или нет, но вы должны понимать временные метки, часовые пояса, UTC и стандарт ISO 8601. Ниже я расскажу об основах, начиная с теории, а затем переходя к практическим примерам.

1970–01–01 00:00:00

Временная метка Unix - это представление времени в формате big int в процессе разработки. Это количество секунд, прошедшее с 00:00:00 1 января 1970 года. Также вы можете найти, что она также называется Эпохой или временем POSIX. Итак, вот пример:

/* Наша дата */
'Monday, July 15, 2024 12:00:00 AM'

/* Unix timestamp  */
1721001600

Такой подход позволяет нам максимально просто стандартизировать дату и время. Кроме того, целые числа очень удобны для сравнения.

Часовые пояса

UTC (Coordinated Universal Time в переводе означает "Всемирное координированное время") - это стандарт времени и основная точка отсчета для часовых поясов по всему миру. Нулевая точка смещения часовых поясов. UTC не соответствует переходу на летнее время.

Часовой пояс - это местное время, измененное с UTC в зависимости от географического положения. Количество часовых поясов увеличивается от Лондона к востоку. Например, в Лондоне время UTC+01:00, а в Екатеринбурге - UTC+05:00.

Вы можете установить часовой пояс по умолчанию для проекта, используя функцию date_default_time_zone(). Список часовых поясов приведен на сайте документации PHP.

date_default_timezone_set('America/Los_Angeles');
echo date('H:i:s') . PHP_EOL;
// 00:00:00

date_default_timezone_set('Asia/Yekaterinburg');
echo date('H:i:s') . PHP_EOL;
// 12:00:00

Позаботьтесь о часовых поясах в PHP, базе данных и сервере. Также учитывайте влияние перехода на летнее время на вашу разработку. Это может быть непросто, когда у вас есть несколько ежедневных процессов, связанных с выполнением сроков.

Функции PHP

// получить текущий unix timestamp
time();

// преобразование строки со временем и датой в unix timestamp
strtotime('Monday, July 15, 2024 12:00:00 AM');
// 1721001600

Date() — основная функция php. Основная, потому что это самый простой способ преобразовать дату и время в требуемый формат. Далее я опишу класс DateTime, но это уже другой случай.

date(
    'Y-m-d H:i:s', // Формат MySQL DATETIME
    strtotime('Monday, July 15, 2024 12:00:00 AM')
); // 2024-07-15 12:00:00

Эта функция преобразует int timestamp в форматированную строку. Более подробная информация здесь и доступные форматы здесь. На самом деле вы можете создать любой формат, какой пожелаете, просто выясните, что представляет собой каждый символ.

Форматы

Полные дата и время: Y-m-d H:i:s. Это базовый формат, который используется практически повсеместно для представления даты и времени. Так что, если вам нужна только дата, вы можете выбрать Y-m-d, если вам нужно время используйте H:i:s.

echo date('Y-m-d H:i:s');
// 2024-07-14 15:30:45

12-часовой формат с AM/PM: h:i:s A

echo date('h:i:s A');
// 03:30:45 PM

Дата ISO 8601: c

echo date('c');
// 2024-07-14T15:30:45+05:00

Американский формат дат m/d/Y может немного сбивать с толку, поскольку он используется только в Соединенных Штатах. Сначала указывается месяц, затем день и затем год.

echo date('m/d/Y');
// 07/15/2024

Более подробно можно узнать о мировых форматах в статье из Википедии.

Класс DateTime

Лучше официальной документации PHP не объяснить, рекомендую ознакомиться со специальной статьей: Представление даты и времени. Этот класс является мощным инструментом для работы с датой и временем.

С его помощью вы можете менять часовой пояс, устанавливать интервалы, анализировать различные (более сложные, чем может обработать strtotime) форматы даты и времени, сравнивать объекты datetime.

$nextDate = new DateTime('2024-07-15');
$endDate = new DateTime('2024-07-19');

// weekday это интервал с Mon - Fri (Пн - Пт)
$interval = DateInterval::createFromDateString('1 weekday');

// сравнение 2х  объектов datetime
while ($nextDate < $endDate) {
    // добавляем интервал и изменяем $nextDate
    $nextDate->add($interval);

    // тот же принцип, что и у функции date()
    echo $nextDate->format('Y-m-d') . PHP_EOL;
}

// Вывод:
// 2024-07-16
// 2024-07-17
// 2024-07-18
// 2024-07-19

Carbon/Carbon

Это базовая библиотека для представления даты и времени в самых популярных фреймворках, таких как Laravel и Symfony. Вы можете установить ее в проекты, которые не используют фреймворк. Composer по-прежнему требуется. Документация: https://carbon.nesbot.com/docs/.

Тот же пример, что и выше, но теперь с использованием библиотеки Carbon. В этом формате код намного удобнее для чтения.

use Carbon\Carbon;

$nextDate = Carbon::parse('2024-02-07');
$endDate = Carbon::parse('2024-02-14');

while ($nextDate->lessThan($endDate)) {
    $nextDate->addDay();

    // Пропуск выходных
    if (!$nextDate->isWeekend()) {
        echo $nextDate->format('Y-m-d') . PHP_EOL;
    }
}

// Вывод:
// 2024-02-08
// 2024-02-09 (Пропущен так как это выходной)
// 2024-02-10 (Аналогично)
// 2024-02-11
// 2024-02-12
// 2024-02-13
// 2024-02-14

Методы работы с базами данных

Существует 2 типа хранения времени в базах данных: с указанием часового пояса и без него. Рассмотрим примеры типов данных MySQL.

DATETIME:

  • Представляет дату и время без какой-либо привязки к часовому поясу.
  • Диапазон: с 1000-01-01 00:00:00 до 9999-12-31 23:59:59. Это строка вместо даты и времени.

TIMESTAMP:

  • Хранит данные в формате UTC.
  • Диапазон значений: с 1970-01-01 00:00:01 по 2038-01-19 03:14:07 (UTC) для 32-разрядных систем. Unix Timestamp
  • Идеально подходит для хранения моментов времени (created_at, processed_at, finished_at, ...).

Такие же типы существуют и в других базах данных. Как, например, в PostgreSQL: TIMESTAMP и TIMESTAMP WITH TIME ZONE

Timestamp как boolean

На практике вы могли бы создать поле базы данных с именем started_at. Это поле может иметь значение null, что означает, что в нем хранятся дата и время запуска определенного процесса, а также указывается, действительно ли процесс запущен (если поле не равно null). Такие поля распространены в таких фреймворках, как Laravel, например, при реализации мягкого удаления с помощью поля deleted_at.

REST API

Почти все уважающие себя API используют формат ISO 8601. Пример: 2024-02-14T00:00:01Z. Также придерживайтесь часового пояса UTC, чтобы избежать путаницы с часовыми поясами.

$date = new DateTime('Monday, July 15, 2024 12:00:00 AM');
echo $date->format(DateTime::ISO8601) . PHP_EOL;
// 2024-07-15T00:00:00+0000

Я надеюсь, что эти основные сведения окажутся для вас полезными. Будьте внимательны и не забывайте использовать часовой пояс UTC!

Comments

In order to leave your opinion, you need to register on the website