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

DateTime

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

Синтаксис:

DateTime([timezone])

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

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

Speed

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

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

Usage Remarks

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

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

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

Вы можете явно установить часовой пояс для колонок типа 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;
-- Parse DateTime
-- - from string,
-- - from integer interpreted as number of seconds since 1970-01-01.
INSERT INTO dt VALUES ('2019-01-01 00:00:00', 1), (1546300800, 2);

SELECT * FROM dt;
┌───────────timestamp─┬─event_id─┐
│ 2019-01-01 00:00:00 │        1 │
│ 2019-01-01 03:00:00 │        2 │
└─────────────────────┴──────────┘
  • При вставке даты и времени в виде целого числа оно рассматривается как 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 года (через минуту после полуночи). Так что после окончания 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.
  • Часы перемещаются назад ("Fall Back"), вызывая начальное перекрытие на один час.
  • Часы перемещаются вперед ("Spring Forward"), вызывая разрыв в час.

По умолчанию 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