PostgreSQL предлагает несколько встроенных функций для работы с текущими временными значениями. Эти функции полезны для задач вроде автоматического отслеживания времени создания записи, построения отчетов на основе текущей даты или проверки, произошло ли событие в заданный период. Давайте рассмотрим три основные функции: NOW(), CURRENT_DATE и CURRENT_TIME.
NOW(): получение текущей даты и времени
Функция NOW() возвращает текущую дату и время в формате TIMESTAMP WITH TIME ZONE. Это означает, что результат функции включает точное время с учетом часового пояса сервера.
Пример:
SELECT NOW();
-- Результат: 2025-05-25 14:30:45.761523+03
Обратите внимание, что результат включает:
- дату (
2025-05-25), - время (
14:30:45.761523), - временную зону (
+03).
Если вам не нужна временная зона, вы можете явно преобразовать результат в TIMESTAMP:
SELECT NOW()::TIMESTAMP;
-- Результат: 2025-05-25 14:30:45.761523
CURRENT_DATE: получение текущей даты
Функция CURRENT_DATE возвращает только текущую дату без времени. Тип возвращаемого значения — DATE.
Пример:
SELECT CURRENT_DATE;
-- Результат: 2025-05-25
Это удобно использовать, если вам не нужно учитывать время, например, при расчете возрастов или при группировке данных по дням.
CURRENT_TIME: получение текущего времени
Функция CURRENT_TIME возвращает текущее время в формате TIME WITH TIME ZONE. Если временная зона вам не нужна, вы можете преобразовать результат в TIME.
Пример:
SELECT CURRENT_TIME;
-- Результат: 14:30:45.761523+03
SELECT CURRENT_TIME::TIME;
-- Результат: 14:30:45.761523
Примеры использования функций
Давайте рассмотрим несколько практических примеров, в которых эти функции могут быть полезны.
Автоматическое заполнение времени создания записи
Когда мы добавляем записи в таблицу, часто бывает полезно автоматически сохранять дату и время их создания. В PostgreSQL это можно сделать, указав DEFAULT NOW() при создании таблицы.
Пример создания таблицы:
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW() -- момент создания строки
);
Добавление записи:
INSERT INTO orders (customer_name) VALUES ('Otto Lin');
Посмотрим на содержимое таблицы:
SELECT * FROM orders;
Результат:
| id | customer_name | created_at |
|---|---|---|
| 1 | Otto Lin | 2024-11-25 14:45:12.154678 |
Фильтрация данных по дате
Предположим, у нас есть таблица заказов, и мы хотим выбрать все заказы, созданные сегодня. Используем функцию CURRENT_DATE для фильтрации:
SELECT *
FROM orders
WHERE created_at::DATE = CURRENT_DATE;
Здесь мы используем преобразование created_at::DATE, чтобы отбросить время и оставить только дату.
Различия между NOW() и CURRENT_TIMESTAMP
На первый взгляд, кажется, что NOW() и CURRENT_TIMESTAMP делают одно и то же. Фактически так и есть. Просто функция NOW() пришла из одного стандарта, а CURRENT_TIMESTAMP — из другого.
NOW() — PostgreSQL-функция
Функция NOW() является встроенной функцией PostgreSQL, которая возвращает значение типа TIMESTAMP WITH TIME ZONE (timestamptz). Это текущее время сервера на момент начала выполнения SQL-запроса.
Пример:
SELECT NOW();
CURRENT_TIMESTAMP — стандарт SQL
CURRENT_TIMESTAMP — это выражение, определённое стандартом SQL, и оно также возвращает TIMESTAMP WITH TIME ZONE в PostgreSQL. По сути, PostgreSQL реализует CURRENT_TIMESTAMP как вызов той же функции, что и NOW().
Пример:
SELECT CURRENT_TIMESTAMP;
Сравнение на практике
SELECT NOW(), CURRENT_TIMESTAMP;
Результат:
| now | current_timestamp |
|---|---|
| 2025-05-25 14:30:45+03 | 2025-05-25 14:30:45+03 |
Оба значения совпадают, потому что вычислены в один момент — в начале запроса.
Использование временных функций в условиях фильтрации
Теперь попробуем написать запрос, который выбирает записи, созданные за последние 7 дней. Для этого можно использовать NOW() с арифметическими операциями над датами:
SELECT *
FROM orders
WHERE created_at >= NOW() - INTERVAL '7 days';
Аналогично, если нужно выбрать заказы за текущий месяц, можно использовать функцию DATE_TRUNC(), чтобы обрезать начало и конец месяца:
SELECT *
FROM orders
WHERE created_at >= DATE_TRUNC('month', NOW());
DATE_TRUNC() интересная функция, подробнее я расскажу о ней через пару лекций :P
Практические советы
- Используйте
NOW()илиCURRENT_TIMESTAMP, если вам нужно точное время с учетом временной зоны. - Применяйте
CURRENT_DATE, если для решения вашей задачи достаточно только даты (например, при расчетах возрастов или анализе событий за определенный день). CURRENT_TIMEчаще всего используется для учета времени в отчетах или интерфейсах, где важно показать, сколько времени было потрачено на задачу.
В следующей лекции мы начнем извлекать части дат и времени, используя функции EXTRACT() и AGE(). С их помощью можно, например, легко определить возраст человека или обрабатывать данные по дням, месяцам или годам.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ