转换为 DATE
DATE 类型支持的合法时间上下界:[0000-01-01, 9999-12-31]
FROM String
严格模式
BNF 定义
<datetime> ::= <date> (("T" | " ") <time> <whitespace>* <offset>?)?
| <digit>{14} <fraction>? <whitespace>* <offset>?
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
<date> ::= <year> "-" <month1> "-" <day1>
| <year> <month2> <day2>
<year> ::= <digit>{2} | <digit>{4} ; 1970 为界
<month1> ::= <digit>{1,2} ; 01–12
<day1> ::= <digit>{1,2} ; 01–28/29/30/31 视月份而定
<month2> ::= <digit>{2} ; 01–12
<day2> ::= <digit>{2} ; 01–28/29/30/31 视月份而定
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
<time> ::= <hour1> (":" <minute1> (":" <second1> <fraction>?)?)?
| <hour2> (<minute2> (<second2> <fraction>?)?)?
<hour1> ::= <digit>{1,2} ; 00–23
<minute1> ::= <digit>{1,2} ; 00–59
<second1> ::= <digit>{1,2} ; 00–59
<hour2> ::= <digit>{2} ; 00–23
<minute2> ::= <digit>{2} ; 00–59
<second2> ::= <digit>{2} ; 00–59
<fraction> ::= "." <digit>*
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
<offset> ::= ( "+" | "-" ) <hour-offset> [ ":"? <minute-offset> ]
| <special-tz>
| <long-tz>
<hour-offset> ::= <digit>{1,2} ; 0–14
<minute-offset> ::= <digit>{2} ; 00/30/45
<special-tz> ::= "CST" | "UTC" | "GMT" | "ZULU" | "Z" ; 忽略大小写
<long-tz> ::= ( ^<whitespace> )+ ; e.g. America/New_York
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<area> ::= <alpha>+
<location> ::= (<alpha> | "_")+
<alpha> ::= "A" | … | "Z" | "a" | … | "z"
<whitespace> ::= " " | "\t" | "\n" | "\r" | "\v" | "\f"
规则描述
整体结构
-
日期部分必选;时间部分及时区部分可选。
-
如果出现时间,则日期与时间之间可用大写“T”或空格分隔。
-
如果出现时区,和时间之间可以用任意数量的 ASCII 空白字符分隔。
-
仅接受 ASCII 字符,如果输入串出现非 ASCII 字符,一定无法满足上述 BNF,属于格式错误。
日期部分 <date>
-
允许两类格式:
-
带分隔符:
YYYY-MM-DD
等。 -
连写:
YYYYMMDD
等。
-
-
<year>
:两位或四位数字-
两位年份(00–99):< 70 → 2000+ 两位数;≥ 70 → 1900+ 两位数。
-
四位年份直接使用。
-
-
分隔符仅支持
-
-
<year>
、<month>
、<day>
在有分隔符的格式中均支持不同长度;在连写格式中,<year>
支持 2 或 4 位,其他长度是固定的 2 位。
时间部分 <time>
-
允许两种格式:
-
带分隔符:
HH[:MM[:SS[.fraction]]]
等。 -
连写:
HH[MM[SS[.fraction]]]
等。
-
-
<hour>
:0–23。 -
<minute>
:0–59。 -
<second>
:0–59。 -
<fraction>
:小数点后任意位数字。表示秒的小数部分。最高位对应到 0.1 秒位(百毫秒)。 -
<hour>
、<minute>
、<second>
在有分隔符的格式中均允许 1-2 位,在连写格式中长度是固定的 2 位。 -
可以只出现左起若干个连续的域而省略剩余部分,例如
<hour>
+<minute>
是合法的,而<hour>
+<fraction>
是不合法的。
连续数字格式 <digit>{14}
-
以 4 位-2 位-2 位-2 位-2 位-2 位 分别解释为年、月、日、时、分、秒。
-
之后正常按规则解析可能出现的小数、时区部分
时区部分 <offset>
-
日期与时区之间允许出现任意空白符
-
不区分大小写
-
允许三类:
-
数值偏移:
(+|-)HH[:MM]
或(+|-)HHMM
等。-
<hour-offset>
:0–14,1 位时允许省略前导 0。 -
<minute-offset>
:00, 30 或者 45,可省略“:”。 -
数值偏移的最大范围是
[-14:00, +14:00]
。
-
-
特殊 UTC 标识:
Z
/UTC
/GMT
/CST
/ZULU
。其中各个符号代表的时区偏移为:-
Z
:+00:00 -
UTC
:+00:00 -
GMT
:+00:00 -
CST
:+08:00 -
ZULU
:+00:00
-
-
长格式时区名:IANA 管理的 Timezone Database 包含的所有合法时区名,如
Europe/Paris
,Etc/GMT+2
等,不区分大小写。- 时区名的可用性,详情见于时区文档。
-
空白
<whitespace>
:空格、制表、换行等所有 ASCII 码中空白符号。
解析逻辑
对于 <datetime>
所有输入域全部合法的输入串,Doris 只解读 <date>
部分并使用其结果作为转换后的目标值。对输入按照域的对应赋值到结果的对应部分,例如,以 <year>
的匹配结果设置结果的年部分,以 <month>
的匹配结果设置结果的月部分,以 <day>
的匹配结果设置结果的日部分。
特别地,如果输入日期结果为 0000 年 00 月 00 日,如果 BE CONFIG allow_zero_date
为 true
,则不认为是值域错误,产生结果 0000 年 01 月 01 日。
进位
不发生进位。
错误处理
-
格式错误:不符合上述任一 BNF 分支,立即报错。
-
值域错误:如果
<date>
部分不合法(结果不为一合法公历时间),报错。
例子
假设当前 Doris 时区为东八区(+08:00
),时区对于时间类型解析的影响参见时区文档。
字符串 | Cast as DATE 结果 | Comment |
---|---|---|
2023-07-16T19:20:30.123+08:00 | 2023-07-16 | 带分隔符日期 + “T” + 带秒及毫秒 + 数值偏移 |
2023-07-16T19+08:00 | 2023-07-16 | 连写时间格式,省略分秒。转换至东八区结果不变。 |
2023-07-16T1920+08:00 | 2023-07-16 | 连写时间格式,省略秒。转换至东八区结果不变。 |
70-1-1T00:00:00-0000 | 1970-01-01 | 两位年 + 月日单/双位 + 分隔符 + 偏移连写 |
19991231T235960.5UTC | 1999-12-31 | 连写日期 + “T” + 连写时分秒+分数 + UTC |
2024-02-29 12:00:00 Europe/Paris | 2024-02-29 | 闰年合法日期 + 空格 + 完整时间 + 空格 + 时区名 |
2024-05-01T00:00Asia/Shanghai | 2024-05-01 | 不完整时间 + 时区名 |
20231005T081530Europe/London | 2023-10-05 | 连写日期 + 时区名 |
85-12-25T0000gMt | 1985-12-25 | 大小写混合时区 |
2024-05-01 | 2024-05-01 | 仅日期 |
24-5-1 | 2024-05-01 | 2 位年 + 1 位月 + 1 位日 |
2024-05-01 0:1:2.333 | 2024-05-01 | 连写日期 + “T” + 个位时分秒 + 毫秒 |
2024-05-01 0:1:2. | 2024-05-01 | 连写日期 + “T” + 个位时分秒 + 单独的小数点 |
20240501 01 | 2024-05-01 | 连写日期 + “ ” + 省略分秒 |
20230716 1920Z | 2023-07-16 | 连写日期 + 空格 + 连写时分 + UTC “Z” |
20240501T0000 | 2024-05-01 | 连写日期 + “T” + 连写时间省略秒 |
2024-12-31 23:59:59.9999999 | 2024-12-31 | 带分隔符日期 + 空格 + 带毫秒时间,时间部分被忽略 |
2025/06/15T00:00:00.99999999999999 | 2025-06-15 | 允许任意位小数 |
2020-12-12 13:12:12-03:00 | 2020-12-12 | 不进位 |
0023-01-01T00:00Z | 0023-01-01 | 四位年合法 |
69-12-31 | 1969-12-31 | 两位年 69 → 1969-12-31 |
70-01-01 | 1970-01-01 | 两位年 70 → 1970-01-01 |
230102 | 2023-01-02 | 短年份的 DATE 连写格式 |
19230101 | 1923-01-01 | 长年份的 DATE 连写格式 |
120102030405 | 报错(格式错误) | 缺少 DATE - TIME 分隔符 |
20120102030405.123 +08 | 2012-01-02 | 14 位日期连写格式 + 小数 + 短时区 offset |
120102030405.999 | 报错(格式错误) | 缺少 DATE - TIME 分隔符 |
2020-05-05 12:30:60 | 2020-05-05 | 秒不合法,但不属于 DATE 解读的部分 |
2023-07-16T19.123+08:00 | 报错(格式错误) | 日期出现非连续域(小时+毫秒跳过了分钟、秒) |
2024/05/01 | 报错(格式错误) | 日期分隔符使用“/” |
24012 | 报错(格式错误) | 日期位数不合法 |
2411 123 | 报错(格式错误) | 日期和时间部分位数均不合法 |
2024-05-01 01:030:02 | 报错(格式错误) | 分钟位数不合法 |
10000-01-01 00:00:00 | 报错(格式错误) | 年份位数不合法 |
2024-0131T12:00 | 报错(格式错误) | 月份连写格式中混用分隔 |
2024-05-01@00:00 | 报错(格式错误) | 错误的分隔符 |
20120212051 | 报错(格式错误) | 位数错误 |
2024-05-01T00:00XYZ | 一般来说是:报错(格式错误) | 未知时区缩写(详见时区文档) |
2024-5-1T24:00 | 报错(值域错误) | 小时 24 越界 |
2024-02-30 | 报错(值域错误) | 2 月 30 日不存在 |
2024-05-01T12:60 | 报错(值域错误) | 分钟 60 越界 |
2012-06-30T23:59:60 | 报错(值域错误) | 不允许闰秒 |
2024-05-01T00:00+14:30 | 报错(值域错误) | 时区偏移超出最大范围 |
2024-05-01T00:00+08:25 | 报错(值域错误) | 时区偏移分钟 25 不合法 |
非严格模式
BNF 定义
除严格模式所支持的格式外,支持:
<datetime> ::= <whitespace>* <date> (<delimiter> <time> <whitespace>* <timezone>?)? <whitespace>*
<date> ::= <year> <separator> <month> <separator> <day>
<time> ::= <hour> <separator> <minute> <separator> <second> [<fraction>]
<year> ::= <digit>{4} | <digit>{2}
<month> ::= <digit>{1,2}
<day> ::= <digit>{1,2}
<hour> ::= <digit>{1,2}
<minute> ::= <digit>{1,2}
<second> ::= <digit>{1,2}
<separator> ::= ^(<digit> | <alpha>)
<delimiter> ::= " " | "T"
<fraction> ::= "." <digit>*
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
<offset> ::= ( "+" | "-" ) <hour-offset> [ ":"? <minute-offset> ]
| <special-tz>
| <long-tz>
<hour-offset> ::= <digit>{1,2} ; 0–14
<minute-offset> ::= <digit>{2} ; 00/30/45
<special-tz> ::= "CST" | "UTC" | "GMT" | "ZULU" | "Z" ; 忽略大小写
<long-tz> ::= ( ^<whitespace> )+ ; e.g. America/New_York
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
<whitespace> ::= " " | "\t" | "\n" | "\r" | "\v" | "\f"
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<alpha> ::= "A" | … | "Z" | "a" | … | "z"
自 4.0 起,<year> 部分只支持 2 或 4 位数字输入。对无分隔符的日期或时间输入支持更为严格,仅支持 14 位连续整数格式,在严格模式中支持,在非严格模式中继承自严格模式。
每个域的解析中不再允许因为额外的前导 0 而超过长度,例如 00012
对于 <day> ::= <digit>{1,2}
是非法的。
遇到非预期的空格时,同遇到其他非预期字符一样,解析将会失败,而非使用已解析过的域填充结果。
规则描述
非严格模式下,所有严格模式受支持的格式,均可以解析,除此之外支持按上述 BNF 定义解析。
整体结构
-
日期部分必选;时间部分及时区部分可选。
-
字符串前后可有任意 ASCII 空白字符;日期与时间之间由空格或大写“T”分隔;各个输入域之间可以用任意数字和字母以外的符号分隔;时区可选。
-
仅接受 ASCII 字符,如果输入串出现非 ASCII 字符,一定无法满足上述 BNF,属于格式错误。
日期部分 <date>
与时间部分 <time>
-
<separator>
:任意数字和字母以外的符号; -
<year>
:2 位或 4 位数字。-
两位年份(00–99):< 70 → 2000+ 两位数;≥ 70 → 1900+ 两位数。
-
四位年份直接使用。
-
-
<fraction>
(可选):小数点后任意位数字。 -
其他数字域:1 或 2 位数字。
时区部分 <timezone>
(同严格模式)
-
日期与时区之间允许出现任意空白符
-
不区分大小写
-
允许三类:
-
数值偏移:
(+|-)HH[:MM]
或(+|-)HHMM
-
<hour-offset>
:0–14,1 位时允许省略前导 0。 -
<minute-offset>
:00, 30 或者 45,可省略“:”。 -
数值偏移的最大范围是
[-14:00, +14:00]
。
-
-
特殊 UTC 标识:
Z
/UTC
/GMT
/CST
/ZULU
。其中各个符号代表的时区偏移为:-
Z
:+00:00 -
UTC
:+00:00 -
GMT
:+00:00 -
CST
:+08:00 -
ZULU
:+00:00
-
-
长格式时区名:IANA 管理的 Timezone Database 包含的所有合法时区名,如
Europe/Paris
,Etc/GMT+2
等,不区分大小写。- 时区名的可用性,详情见于时区文档。
-
空白
<whitespace>
:空格、制表、换行等所有 ASCII 码中空白符号。
解析逻辑
对于 <datetime>
所有输入域全部合法的输入串,Doris 只解读 <date>
部分并使用其结果作为转换后的目标值。对输入按照域的对应赋值到结果的对应部分,例如,以 <year>
的匹配结果设置结果的年部分,以 <month>
的匹配结果设置结果的月部分,以 <day>
的匹配结果设置结果的日部分。
特别地,如果输入日期结果为 0000 年 00 月 00 日,如果 BE CONFIG allow_zero_date
为 true
,则不认为是值域错误,产生结果 0000 年 01 月 01 日。
进位
自 4.0 起,DATE 类型解析时,除 <date> 以外的部分不产生进位或任何数值影响。
不发生进位。
错误处理
-
格式错误:不符合上述任一 BNF 分支,返回 NULL。
-
值域错误:如果
<date>
部分不合法(结果不为一合法公历时间),返回 NULL。
自 4.0 起,DATE 类型解析时,除 <date> 以外的部分如果值域错误,不产生影响。
例子
假设当前 Doris 时区为东八区(+08:00
),时区对于时间类型解析的影响参见时区文档。
输入字符串 | Cast as DATE 结果 | Comment |
---|---|---|
2023-7-4T9-5-3.1Z | 2023-07-04 | 前后空白;日期 2023-7-4 (- 分隔,支持一位月日);时间与时区都合规 |
99.12.31 23.59.59+05:30 | 1999-12-31 | . 分隔日期与时间;时区 +05:30 (分钟 30 合法);无“T” |
2000/01/01T00/00/00-230 | 2000-01-01 | / 分隔;时区无冒号且 1 位小时数 -230 |
85 1 1T0 0 0. CST | 1985-01-01 | 空格分隔所有字段;两位年映射 1985 ;小数点后零位;短时区名忽略大小写 |
2024-02-29T23:59:59.999999 UTC | 2024-02-29 | 闰年合法;高精度小数不进位;特定时区名 |
70-01-01T00:00:00+14 | 1970-01-01 | 两位年 1970 ;最大合法偏移 +14 ;无分钟部分 |
0023-1-1T1:2:3. -00:00 | 0023-01-01 | 四位年 0023 ;混合一位/两位时间字段;小数后零位;偏移无符号分钟 |
2025/06/15T00:00:00.0-0 | 2025-06-15 | / 分隔;小数后 1 位;偏移 -0 (等同 -00:00 ) |
2025/06/15T00:00:00.99999999999999 | 2025-06-15 | 任意位小数,忽略 |
2024-02-29T23-59-60ZULU | NULL | 秒越界 |
2024 12 31T121212.123456 America/New_York | NULL | 纯数字时间无分隔符 |
123.123 | NULL | 行为变更:原表示 2012-03-12。现不支持。 |
12121 | NULL | 行为变更:原表示 2012-12-12。现不支持。 |
From Numeric
支持所有数字类型转换为 DATE 类型。
自 4.0 开始,DECIMAL 类型按照其字面数值表示进行转换。不支持 Boolean 类型转换为时间类型。支持解析数字类型输入的小数部分。
严格模式
规则描述
合法格式
对于整数位,将数字从低位到高位,从日期最右端向左填充。以下是合法格式及其对应的填充结果(不含微秒部分):
3 位数字(abc) => 2000 年 0a 月 bc 日
4 位数字(abcd) => 2000 年 ab 月 cd 日
5 位数字(abcde) => 200a 年 bc 月 de 日
6 位数字(abcdef,其中 ab >=70) => 19ab 年 cd 月 ef 日
6 位数字(abcdef,其中 ab < 70) => 20ab 年 cd 月 ef 日
8 位数字(abcdefgh) => abcd 年 ef 月 gh 日
14 位数字(abcdefghijklmn) => abcd 年 ef 月 gh 日
错误处理
当输入按规则解析后不能得到合法的 DATE 值时,报错。
例子
数字 | Cast as DATE 结果 | Comment |
---|---|---|
123.123 | 2000-01-23 | 3 位数字 |
20150102030405 | 2015-01-02 | 14 位数字 |
20150102030405.123456 | 2015-01-02 | 14 位数字,小数合法 |
20151231235959.99999999999 | 2015-12-31 | 14 位数字,小数合法 |
1000 | 报错 | 2000-10-00 中的日不合法 |
-123.123 | 报错 | 负数时间无法得到合法日期 |
非严格模式
除错误处理外,非严格模式的行为同严格模式完全一致。
规则描述
合法格式
对于整数位,将数字从低位到高位,从日期最右端向左填充。以下是合法格式及其对应的填充结果(不含微秒部分):
3 位数字(abc) => 2000 年 0a 月 bc 日
4 位数字(abcd) => 2000 年 ab 月 cd 日
5 位数字(abcde) => 200a 年 bc 月 de 日
6 位数字(abcdef,其中 ab >=70) => 19ab 年 cd 月 ef 日
6 位数字(abcdef,其中 ab < 70) => 20ab 年 cd 月 ef 日
8 位数字(abcdefgh) => abcd 年 ef 月 gh 日
14 位数字(abcdefghijklmn) => abcd 年 ef 月 gh 日
错误处理
当输入按规则解析后不能得到合法的 DATE 值时,返回 NULL。
例子
数字 | Cast as DATE 结果 | Comment |
---|---|---|
123.123 | 2000-01-23 | 3 位数字 |
20150102030405 | 2015-01-02 | 14 位数字 |
20150102030405.123456 | 2015-01-02 | 14 位数字,小数合法 |
20151231235959.99999999999 | 2015-12-31 | 14 位数字,小数合法 |
1000 | NULL | 2000-10-00 中的日不合法 |
-123.123 | NULL | 负数时间无法得到合法日期 |
From Datelike Types
支持 Datetime 和 Time 类型转换为 Date 类型。
Datetime
规则描述
从 Datetime 转换时,结果为输入的日期部分。该转换必定合法。
例子
输入 Datetime | Cast as Date 结果 |
---|---|
2012-02-05 12:35:24.123456 | 2012-02-05 |
Time
规则描述
从 Time 转换时,结果为当前日期与 Time 输入进行加和运算。由于该转换在可预见的未来(9999 年 12 月之前)是合法的,Doris 中认定它必定合法。
例子
假设当前日期为 2025-04-29,则:
输入 Time | Cast as Date 结果 |
---|---|
500:00:00 | 2025-05-19 |
23:59:59 | 2025-04-29 |
-128:00:00 | 2025-04-23 |