ZONE_OFFSET в Oracle SQL. Введение
ZONE_OFFSET в Oracle SQL применяется для получения числового смещения временной зоны относительно UTC. Обычно оно извлекается с помощью TO_CHAR и шаблона TZH:TZM или через функцию TZ_OFFSET. Смещение удобно для логов, синхронизации времени между системами и отображения локального времени. В этой статье ты найдёшь 50 примеров использования ZONE_OFFSET в SQL.
🖋️ Синтаксис для извлечения смещения
-- Через форматирование:
SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS offset FROM dual;
-- Через функцию:
SELECT TZ_OFFSET('Europe/Moscow') FROM dual;
🔄 Где используется ZONE_OFFSET
- Анализ логов с учётом часового пояса
- Конвертация между регионами
- Форматирование отчётов
- Отображение и обработка дат в UI/API
📊 Примеры использования ZONE_OFFSET в Oracle SQL (1–5 из 50)
- Получить смещение текущей зоны:
SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS offset FROM dual;
- Смещение зоны по имени:
SELECT TZ_OFFSET('Asia/Yekaterinburg') AS offset FROM dual;
- С TIMESTAMP AT TIME ZONE:
SELECT TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'UTC', 'TZH:TZM') AS utc_offset FROM dual;
- Смещение при форматировании логина:
SELECT user_id, TO_CHAR(login_time, 'TZH:TZM') AS zone_offset FROM sessions;
- Смещение как строка в отчёте:
SELECT TO_CHAR(FROM_TZ(TIMESTAMP '2025-08-30 09:00:00', 'Europe/Moscow'), 'TZH:TZM') AS offset FROM dual;
- Смещение времени в другой зоне:
SELECT TZ_OFFSET('America/New_York') FROM dual;
- Сравнение смещений:
SELECT TZ_OFFSET('Europe/Moscow') AS msk, TZ_OFFSET('Asia/Tokyo') AS tokyo FROM dual;
- Получение смещения с TIME ZONE:
SELECT TO_CHAR(FROM_TZ(TIMESTAMP '2025-12-31 23:59:59', 'Asia/Kolkata'), 'TZH:TZM') FROM dual;
- Использование в представлении:
CREATE VIEW v_offset AS
SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS current_offset FROM dual;
- Смещение как часть отчёта:
SELECT user_id, login_time, TO_CHAR(login_time, 'TZH:TZM') AS offset FROM sessions;
- Объединение смещения и региона:
SELECT TO_CHAR(SYSTIMESTAMP, 'TZR TZH:TZM') AS full_info FROM dual;
- Разница между зонами:
SELECT TZ_OFFSET('Europe/London') AS london, TZ_OFFSET('Europe/Moscow') AS moscow FROM dual;
- Использование LOCALTIMESTAMP:
SELECT TO_CHAR(LOCALTIMESTAMP, 'TZH:TZM') FROM dual;
- Добавление в логи:
INSERT INTO log_table (event, zone_offset)
VALUES ('login', TO_CHAR(SYSTIMESTAMP, 'TZH:TZM'));
- Обновление по смещению:
UPDATE users SET tz_offset = TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') WHERE user_id = 42;
- Смещение с CURRENT_TIMESTAMP:
SELECT TO_CHAR(CURRENT_TIMESTAMP, 'TZH:TZM') FROM dual;
- Вывод смещения в функции:
CREATE FUNCTION get_offset RETURN VARCHAR2 IS
BEGIN
RETURN TO_CHAR(SYSTIMESTAMP, 'TZH:TZM');
END;
- Отчёт по временным зонам:
SELECT department_id, COUNT(*)
FROM employees
GROUP BY TO_CHAR(hire_date, 'TZH:TZM');
- Смещение с MERGE:
MERGE INTO timezone_log t
USING (SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS z FROM dual) z
ON (t.zone = z.z)
WHEN NOT MATCHED THEN INSERT (zone) VALUES (z.z);
- Сохраняем смещение в JSON:
SELECT JSON_OBJECT('offset' VALUE TO_CHAR(SYSTIMESTAMP, 'TZH:TZM')) FROM dual;
- Вывод вместе с датой:
SELECT TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI TZH:TZM') AS full FROM dual;
- Поиск по смещению:
SELECT * FROM logs WHERE TO_CHAR(event_time, 'TZH:TZM') = '+03:00';
- Получение смещения в CTE:
WITH tz AS (
SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS offset FROM dual
)
SELECT * FROM tz;
- Смещение в аналитике:
SELECT user_id, login_time, TO_CHAR(login_time, 'TZH:TZM') AS offset,
RANK() OVER (PARTITION BY TO_CHAR(login_time, 'TZH:TZM') ORDER BY login_time DESC) AS rnk
FROM sessions;
- Использование с TRUNC:
SELECT TRUNC(SYSTIMESTAMP) AS ts, TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS offset FROM dual;
- Конкатенация строки и смещения:
SELECT 'Текущая зона: ' || TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS info FROM dual;
- Аббревиатура и смещение:
SELECT TO_CHAR(SYSTIMESTAMP, 'TZD TZH:TZM') FROM dual;
- Сравнение двух времён с разным смещением:
SELECT CASE
WHEN TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') = '+03:00' THEN 'MSK'
ELSE 'OTHER'
END AS zone FROM dual;
- Смещение как значение по умолчанию:
ALTER TABLE users ADD (zone_offset VARCHAR2(6) DEFAULT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM'));
- Смещение через CAST:
SELECT TO_CHAR(CAST(SYSTIMESTAMP AS TIMESTAMP WITH TIME ZONE), 'TZH:TZM') FROM dual;
- Смещение в SUBSTR:
SELECT SUBSTR(TO_CHAR(SYSTIMESTAMP, 'TZH:TZM'), 1, 3) AS hours FROM dual;
- Удаление по смещению:
DELETE FROM log_table WHERE TO_CHAR(event_time, 'TZH:TZM') = '+03:00';
- Смещение в XML:
SELECT XMLELEMENT("offset", TO_CHAR(SYSTIMESTAMP, 'TZH:TZM')) FROM dual;
- Добавление поля offset в представление:
CREATE VIEW v_events AS
SELECT event_time, TO_CHAR(event_time, 'TZH:TZM') AS offset FROM logs;
- Форматированный вывод смещения:
SELECT TO_CHAR(SYSTIMESTAMP, '"OFFSET:" TZH:TZM') FROM dual;
- OFFSET через функцию TZ_OFFSET:
SELECT TZ_OFFSET(SESSIONTIMEZONE) FROM dual;
- OFFSET через переменную:
DECLARE z VARCHAR2(6);
BEGIN
SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') INTO z FROM dual;
DBMS_OUTPUT.PUT_LINE(z);
END;
- Проверка начала по смещению:
SELECT * FROM sessions
WHERE TO_CHAR(login_time, 'TZH:TZM') LIKE '+03%';
- Добавление смещения в лог:
CREATE OR REPLACE TRIGGER trg_add_offset
BEFORE INSERT ON logs
FOR EACH ROW
BEGIN
:NEW.zone_offset := TO_CHAR(SYSTIMESTAMP, 'TZH:TZM');
END;
- OFFSET в MERGE по условию:
MERGE INTO timezone_summary t
USING (SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') AS off FROM dual) s
ON (t.zone_offset = s.off)
WHEN NOT MATCHED THEN INSERT (zone_offset) VALUES (s.off);
- OFFSET как часть ROWNUM-поиска:
SELECT TO_CHAR(SYSTIMESTAMP, 'TZH:TZM') FROM dual WHERE ROWNUM = 1;
- Смещение в часах отдельно:
SELECT TO_CHAR(SYSTIMESTAMP, 'TZH') FROM dual;
- Смещение в минутах отдельно:
SELECT TO_CHAR(SYSTIMESTAMP, 'TZM') FROM dual;
- Переход в другой часовой пояс:
SELECT TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'Europe/Riga', 'TZH:TZM') FROM dual;
- Смещение в PL/SQL-функции:
CREATE FUNCTION get_zone_offset RETURN VARCHAR2 IS
BEGIN
RETURN TO_CHAR(SYSTIMESTAMP, 'TZH:TZM');
END;
📆 Заключение: зачем использовать ZONE_OFFSET в Oracle SQL
ZONE_OFFSET помогает точно учитывать локальное время и разницу между регионами. Использование TZH:TZM и TZ_OFFSET особенно важно при анализе глобальных событий, обработке журналов и синхронизации времени в распределённых системах.
🕸️ Следующая статья:
ZONE_ABBR в Oracle SQL — как получать аббревиатуры часовых поясов