DateTime
允许存储一个瞬间,该瞬间可以表示为日历日期和一天中的时间。
语法:
支持的值范围:[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 时间戳 存储,不考虑时区或夏令时。时区影响 DateTime
类型的值在文本格式中的显示方式,以及作为字符串指定的值如何解析(例如:'2020-01-01 05:00:01')。
时间无关的 Unix 时间戳存储在表中,时区用于在数据导入/导出或在值上进行日历计算时将其转换为文本格式或反向转换(示例:toDate
,toHour
函数等)。时区不存储在表的行中(或结果集中),而是存储在列元数据中。
支持的时区列表可以在 IANA 时区数据库 中找到,也可以通过 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
类型列的表并向其中插入数据:
- 当以整数插入日期时间时,它被视为 Unix 时间戳 (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
值进行过滤
DateTime
列的值可以使用 WHERE
谓词中的字符串值进行过滤。它将自动转换为 DateTime
:
3. 获取 DateTime
类型列的时区:
4. 时区转换
由于时区转换仅更改元数据,因此该操作没有计算成本。
Limitations on time zones support
有些时区可能不完全支持。以下是几种情况:
如果与 UTC 的偏移量不是 15 分钟的倍数,则小时和分钟的计算可能不正确。例如,利比里亚的蒙罗维亚在 1972 年 1 月 7 日之前的时区偏移为 UTC -0:44:30。如果您在蒙罗维亚时区对历史时间进行计算,时间处理函数可能会给出不正确的结果。然而,1972 年 1 月 7 日之后的结果将是正确的。
如果时间转换(由于夏令时或其他原因)在不是 15 分钟倍数的时间点进行,您在该特定日子也可能会得到不正确的结果。
非单调的日历日期。例如,在快乐谷 - 鳕鱼湾,时间在 2010 年 11 月 7 日 00:01:00 向后转了一小时(午夜后一分钟)。因此,在 11 月 6 日结束后,人们目睹了 11 月 7 日整整一分钟,然后时间回到 11 月 6 日 23:01,在再过 59 分钟后,11 月 7 日再次开始。ClickHouse 目前不支持这种情况。在这些日子里,时间处理函数的结果可能会略有不正确。
类似的问题出现在 2010 年的凯西南极站。他们在 3 月 5 日 02:00 时将时间回拨了三个小时。如果您在南极站工作,请不要害怕使用 ClickHouse。只需确保将时区设置为 UTC 或了解不准确之处。
多天的时间偏移。一些太平洋岛屿将其时区偏移从 UTC+14 更改为 UTC-12。这没问题,但在转换日期的历史时间点计算时,可能会出现一些不准确的情况。
Handling daylight saving time (DST)
ClickHouse 的 DateTime 类型与时区在夏令时 (DST) 转换期间可能会表现出意外行为,特别是在以下情况下:
date_time_output_format
设置为simple
。- 时钟向后移动(“调回”),造成一小时重叠。
- 时钟向前移动(“调前”),造成一小时间隔。
默认情况下,ClickHouse 始终选择重叠时间的较早发生,可能会在向前移动时解释不存在的时间。
例如,考虑从夏令时 (DST) 转换到标准时间的以下情况。
- 在2023年10月29日,在 02:00:00,时钟向后调整到 01:00:00(BST → GMT)。
- 01:00:00 – 01:59:59 小时出现两次(一次在 BST,一次在 GMT)
- ClickHouse 始终选择第一次出现(BST),因此在添加时间间隔时会导致意外结果。
同样,在从标准时间转向夏令时的过程中,可能会有一个小时被跳过。
例如:
- 在 2023 年 3 月 26 日的
00:59:59
,时钟跳转到 02:00:00(GMT → BST)。 - 01:00:00 – 01:59:59 小时不存在。
在这种情况下,ClickHouse 将不存在的时间 2023-03-26 01:30:00
向后移动到 2023-03-26 00:30:00
。