Перейти к основному содержимому
Перейти к основному содержимому

datetime

description: 'Документация для типа данных DateTime в ClickHouse, который хранит временные метки с точностью до секунд' sidebar_label: 'DateTime' sidebar_position: 16 slug: /sql-reference/data-types/datetime title: 'DateTime'



# DateTime

Позволяет хранить мгновение времени, которое может быть выражено как календарная дата и время суток.

Синтаксис:

```sql
DateTime([timezone])

Поддерживаемый диапазон значений: [1970-01-01 00:00:00, 2106-02-07 06:28:15].

Разрешение: 1 секунда.

Speed

Тип данных Date быстрее, чем DateTime при большинстве условиях.

Тип Date требует 2 байта хранения, в то время как DateTime требует 4. Однако, когда база данных сжимает данные, это различие увеличивается. Это увеличение обусловлено тем, что минуты и секунды в DateTime менее сжимаемы. Фильтрация и агрегация Date вместо DateTime также быстрее.

Usage Remarks

Момент времени сохраняется как Unix временная метка, независимо от часового пояса или перехода на летнее/зимнее время. Часовой пояс влияет на то, как значения типа DateTime отображаются в текстовом формате и как значения, указанные в виде строк, парсятся ('2020-01-01 05:00:01').

Часовой пояс агностичная Unix временная метка хранится в таблицах, а часовой пояс используется для преобразования ее в текстовый формат или обратно во время импорта/экспорта данных, или для выполнения календарных расчетов над значениями (пример: функции toDate, toHour и т.д.). Часовой пояс не хранится в строках таблицы (или в наборе результатов), но хранится в метаданных колонки.

Список поддерживаемых часовых поясов можно найти в IANA Time Zone Database и также можно запросить с помощью SELECT * FROM system.time_zones. Список также доступен на Wikipedia.

Вы можете явно установить часовой пояс для колонок типа DateTime при создании таблицы. Пример: DateTime('UTC'). Если часовой пояс не установлен, ClickHouse использует значение параметра timezone в настройках сервера или настройки операционной системы на момент запуска сервера ClickHouse.

clickhouse-client применяет часовой пояс сервера по умолчанию, если часовой пояс не установлен явно при инициализации типа данных. Чтобы использовать часовой пояс клиента, запустите clickhouse-client с параметром --use_client_time_zone.

ClickHouse выводит значения в зависимости от значения настройки date_time_output_format. По умолчанию текстовый формат YYYY-MM-DD hh:mm:ss. Кроме того, вы можете изменить вывод с помощью функции formatDateTime.

При вставке данных в ClickHouse вы можете использовать различные форматы строк даты и времени, в зависимости от значения настройки date_time_input_format.

Examples

1. Создание таблицы с колонкой типа DateTime и вставка в нее данных:

CREATE TABLE dt
(
    `timestamp` DateTime('Asia/Istanbul'),
    `event_id` UInt8
)
ENGINE = TinyLog;
-- Парсинг DateTime
-- - из строки,
-- - из целого числа, интерпретируемого как количество секунд с 1970-01-01.
INSERT INTO dt VALUES ('2019-01-01 00:00:00', 1), (1546300800, 3);

SELECT * FROM dt;
┌───────────timestamp─┬─event_id─┐
│ 2019-01-01 00:00:00 │        2 │
│ 2019-01-01 03:00:00 │        1 │
└─────────────────────┴──────────┘
  • При вставке временной метки как целого числа, оно рассматривается как Unix Timestamp (UTC). 1546300800 представляет собой '2019-01-01 00:00:00' по UTC. Однако, поскольку колонка timestamp имеет указанный часовой пояс Asia/Istanbul (UTC+3), при выводе в виде строки значение будет показано как '2019-01-01 03:00:00'.
  • При вставке строкового значения как временной метки, оно рассматривается как находящееся в часовом поясе колонки. '2019-01-01 00:00:00' будет считаться находящимся в часовом поясе Asia/Istanbul и сохранится как 1546290000.

2. Фильтрация по значениям DateTime

SELECT * FROM dt WHERE timestamp = toDateTime('2019-01-01 00:00:00', 'Asia/Istanbul')
┌───────────timestamp─┬─event_id─┐
│ 2019-01-01 00:00:00 │        1 │
└─────────────────────┴──────────┘

Значения колонки DateTime могут фильтроваться с использованием строкового значения в предикате WHERE. Оно будет автоматически преобразовано в DateTime:

SELECT * FROM dt WHERE timestamp = '2019-01-01 00:00:00'
┌───────────timestamp─┬─event_id─┐
│ 2019-01-01 00:00:00 │        1 │
└─────────────────────┴──────────┘

3. Получение часового пояса для колонки типа DateTime:

SELECT toDateTime(now(), 'Asia/Istanbul') AS column, toTypeName(column) AS x
┌──────────────column─┬─x─────────────────────────┐
│ 2019-10-16 04:12:04 │ DateTime('Asia/Istanbul') │
└─────────────────────┴───────────────────────────┘

4. Преобразование часового пояса

SELECT
toDateTime(timestamp, 'Europe/London') as lon_time,
toDateTime(timestamp, 'Asia/Istanbul') as mos_time
FROM dt
┌───────────lon_time──┬────────────mos_time─┐
│ 2019-01-01 00:00:00 │ 2019-01-01 03:00:00 │
│ 2018-12-31 21:00:00 │ 2019-01-01 00:00:00 │
└─────────────────────┴─────────────────────┘

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

Limitations on time zones support

Некоторые часовые пояса могут быть не полностью поддержаны. Есть несколько случаев:

Если смещение от UTC не является кратным 15 минутам, расчет часов и минут может быть неправильным. Например, часовой пояс в Монровии, Либерия имеет смещение UTC -0:44:30 до 7 января 1972 года. Если вы выполняете расчеты по историческому времени в часовом поясе Монровии, функции обработки времени могут давать неправильные результаты. Результаты после 7 января 1972 года тем не менее будут правильными.

Если переход времени (из-за перехода на летнее/зимнее время или по другим причинам) был выполнен в момент времени, кратный 15 минутам, вы также можете получить неправильные результаты в этот конкретный день.

Неконтролируемые календарные даты. Например, в Хэппи-Вэлли — Гус-Бэй время было переведено на один час назад в 00:01:00 7 ноября 2010 года (за минуту после пол midnight). Таким образом, после окончания 6 ноября люди наблюдали целую одну минуту 7 ноября, затем время было изменено обратно на 23:01 6 ноября, и после еще 59 минут 7 ноября снова начался. ClickHouse (пока что) не поддерживает подобные забавы. В течение этих дней результаты функций обработки времени могут быть немного некорректными.

Похожая проблема существует для антарктической станции Кейси в 2010 году. Они изменили время на три часа назад 5 марта в 02:00. Если вы работаете на антарктической станции, не бойтесь использовать ClickHouse. Просто убедитесь, что вы установили часовой пояс на UTC или будьте осведомлены о неточностях.

Смещения времени на несколько дней. Некоторые тихоокеанские острова изменили свое смещение часового пояса с UTC+14 на UTC-12. Это нормально, но некорректности могут возникнуть, если вы делаете расчеты с их часовым поясом для исторических временных точек в дни перехода.

Handling Daylight Saving Time (DST)

Тип DateTime в ClickHouse с часовыми поясами может проявлять неожиданное поведение во время переходов на летнее/зимнее время (DST), особенно когда:

  • date_time_output_format установлен в simple.
  • Часы отстают ("падение назад"), вызывая одновременность в один час.
  • Часы продвигаются вперед ("весеннее продвижение"), вызывая часовой пробел.

По умолчанию ClickHouse всегда выбирает более раннее в совместимости время и может интерпретировать несуществующее время во время продвижений вперед.

Например, рассмотрим следующий переход от перехода на летнее время (DST) к стандартному времени.

  • 29 октября 2023 года в 02:00:00 часы отстают до 01:00:00 (BST → GMT).
  • Час 01:00:00 – 01:59:59 появляется дважды (один раз в BST и один раз в GMT).
  • ClickHouse всегда выбирает первое вхождение (BST), что вызывает неожиданные результаты при добавлении временных интервалов.
SELECT '2023-10-29 01:30:00'::DateTime('Europe/London') AS time, time + toIntervalHour(1) AS one_hour_later

┌────────────────time─┬──────one_hour_later─┐
│ 2023-10-29 01:30:00 │ 2023-10-29 01:30:00 │
└─────────────────────┴─────────────────────┘

Аналогично, во время перехода от стандартного времени к переходу на летнее время, час может казаться пропущенным.

Например:

  • 26 марта 2023 года в 00:59:59 часы прыгают вперед к 02:00:00 (GMT → BST).
  • Час 01:00:0001:59:59 не существует.
SELECT '2023-03-26 01:30:00'::DateTime('Europe/London') AS time, time + toIntervalHour(1) AS one_hour_later

┌────────────────time─┬──────one_hour_later─┐
│ 2023-03-26 00:30:00 │ 2023-03-26 02:30:00 │
└─────────────────────┴─────────────────────┘

В этом случае ClickHouse переводит несуществующее время 2023-03-26 01:30:00 обратно на 2023-03-26 00:30:00.

See Also