跳到主要内容

转换为 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>
  • 日期与时区之间允许出现任意空白符

  • 不区分大小写

  • 允许三类:

    1. 数值偏移:(+|-)HH[:MM](+|-)HHMM 等。

      • <hour-offset>:0–14,1 位时允许省略前导 0。

      • <minute-offset>:00, 30 或者 45,可省略“:”。

      • 数值偏移的最大范围是 [-14:00, +14:00]

    2. 特殊 UTC 标识:Z/UTC/GMT/CST/ZULU。其中各个符号代表的时区偏移为:

      • Z:+00:00

      • UTC:+00:00

      • GMT:+00:00

      • CST:+08:00

      • ZULU:+00:00

    3. 长格式时区名:IANA 管理的 Timezone Database 包含的所有合法时区名,如 Europe/ParisEtc/GMT+2 等,不区分大小写。

      • 时区名的可用性,详情见于时区文档。
空白
  • <whitespace>:空格、制表、换行等所有 ASCII 码中空白符号。
解析逻辑

对于 <datetime> 所有输入域全部合法的输入串,Doris 只解读 <date> 部分并使用其结果作为转换后的目标值。对输入按照域的对应赋值到结果的对应部分,例如,以 <year> 的匹配结果设置结果的年部分,以 <month> 的匹配结果设置结果的月部分,以 <day> 的匹配结果设置结果的日部分。

特别地,如果输入日期结果为 0000 年 00 月 00 日,如果 BE CONFIG allow_zero_datetrue,则不认为是值域错误,产生结果 0000 年 01 月 01 日。

进位

不发生进位。

错误处理
  • 格式错误:不符合上述任一 BNF 分支,立即报错。

  • 值域错误:如果 <date> 部分不合法(结果不为一合法公历时间),报错。

例子

假设当前 Doris 时区为东八区(+08:00),时区对于时间类型解析的影响参见时区文档。

字符串Cast as DATE 结果Comment
2023-07-16T19:20:30.123+08:002023-07-16带分隔符日期 + “T” + 带秒及毫秒 + 数值偏移
2023-07-16T19+08:002023-07-16连写时间格式,省略分秒。转换至东八区结果不变。
2023-07-16T1920+08:002023-07-16连写时间格式,省略秒。转换至东八区结果不变。
70-1-1T00:00:00-00001970-01-01两位年 + 月日单/双位 + 分隔符 + 偏移连写
19991231T235960.5UTC1999-12-31连写日期 + “T” + 连写时分秒+分数 + UTC
2024-02-29 12:00:00 Europe/Paris2024-02-29闰年合法日期 + 空格 + 完整时间 + 空格 + 时区名
2024-05-01T00:00Asia/Shanghai2024-05-01不完整时间 + 时区名
20231005T081530Europe/London2023-10-05连写日期 + 时区名
85-12-25T0000gMt1985-12-25大小写混合时区
2024-05-012024-05-01仅日期
24-5-12024-05-012 位年 + 1 位月 + 1 位日
2024-05-01 0:1:2.3332024-05-01连写日期 + “T” + 个位时分秒 + 毫秒
2024-05-01 0:1:2.2024-05-01连写日期 + “T” + 个位时分秒 + 单独的小数点
20240501 012024-05-01连写日期 + “ ” + 省略分秒
20230716 1920Z2023-07-16连写日期 + 空格 + 连写时分 + UTC “Z”
20240501T00002024-05-01连写日期 + “T” + 连写时间省略秒
2024-12-31 23:59:59.99999992024-12-31带分隔符日期 + 空格 + 带毫秒时间,时间部分被忽略
2025/06/15T00:00:00.999999999999992025-06-15允许任意位小数
2020-12-12 13:12:12-03:002020-12-12不进位
0023-01-01T00:00Z0023-01-01四位年合法
69-12-311969-12-31两位年 69 → 1969-12-31
70-01-011970-01-01两位年 70 → 1970-01-01
2301022023-01-02短年份的 DATE 连写格式
192301011923-01-01长年份的 DATE 连写格式
120102030405报错(格式错误)缺少 DATE - TIME 分隔符
20120102030405.123 +082012-01-0214 位日期连写格式 + 小数 + 短时区 offset
120102030405.999报错(格式错误)缺少 DATE - TIME 分隔符
2020-05-05 12:30:602020-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>(同严格模式)
  • 日期与时区之间允许出现任意空白符

  • 不区分大小写

  • 允许三类:

    1. 数值偏移:(+|-)HH[:MM](+|-)HHMM

      • <hour-offset>:0–14,1 位时允许省略前导 0。

      • <minute-offset>:00, 30 或者 45,可省略“:”。

      • 数值偏移的最大范围是 [-14:00, +14:00]

    2. 特殊 UTC 标识:Z/UTC/GMT/CST/ZULU。其中各个符号代表的时区偏移为:

      • Z:+00:00

      • UTC:+00:00

      • GMT:+00:00

      • CST:+08:00

      • ZULU:+00:00

    3. 长格式时区名:IANA 管理的 Timezone Database 包含的所有合法时区名,如 Europe/ParisEtc/GMT+2 等,不区分大小写。

      • 时区名的可用性,详情见于时区文档。
空白
  • <whitespace>:空格、制表、换行等所有 ASCII 码中空白符号。
解析逻辑

对于 <datetime> 所有输入域全部合法的输入串,Doris 只解读 <date> 部分并使用其结果作为转换后的目标值。对输入按照域的对应赋值到结果的对应部分,例如,以 <year> 的匹配结果设置结果的年部分,以 <month> 的匹配结果设置结果的月部分,以 <day> 的匹配结果设置结果的日部分。

特别地,如果输入日期结果为 0000 年 00 月 00 日,如果 BE CONFIG allow_zero_datetrue,则不认为是值域错误,产生结果 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.1Z2023-07-04前后空白;日期 2023-7-4- 分隔,支持一位月日);时间与时区都合规
99.12.31 23.59.59+05:301999-12-31. 分隔日期与时间;时区 +05:30(分钟 30 合法);无“T”
2000/01/01T00/00/00-2302000-01-01/ 分隔;时区无冒号且 1 位小时数 -230
85 1 1T0 0 0. CST1985-01-01空格分隔所有字段;两位年映射 1985;小数点后零位;短时区名忽略大小写
2024-02-29T23:59:59.999999 UTC2024-02-29闰年合法;高精度小数不进位;特定时区名
70-01-01T00:00:00+141970-01-01两位年 1970;最大合法偏移 +14;无分钟部分
0023-1-1T1:2:3. -00:000023-01-01四位年 0023;混合一位/两位时间字段;小数后零位;偏移无符号分钟
2025/06/15T00:00:00.0-02025-06-15/ 分隔;小数后 1 位;偏移 -0(等同 -00:00
2025/06/15T00:00:00.999999999999992025-06-15任意位小数,忽略
2024-02-29T23-59-60ZULUNULL秒越界
2024 12 31T121212.123456 America/New_YorkNULL纯数字时间无分隔符
123.123NULL行为变更:原表示 2012-03-12。现不支持。
12121NULL行为变更:原表示 2012-12-12。现不支持。

From Numeric

支持所有数字类型转换为 DATE 类型。

行为变更

自 4.0 开始,DECIMAL 类型按照其字面数值表示进行转换。不支持 Boolean 类型转换为时间类型。支持解析数字类型输入的小数部分。

严格模式

规则描述

合法格式

对于整数位,将数字从低位到高位,从日期最右端向左填充。以下是合法格式及其对应的填充结果(不含微秒部分):

3 位数字(abc) => 20000a 月 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.1232000-01-233 位数字
201501020304052015-01-0214 位数字
20150102030405.1234562015-01-0214 位数字,小数合法
20151231235959.999999999992015-12-3114 位数字,小数合法
1000报错2000-10-00 中的日不合法
-123.123报错负数时间无法得到合法日期

非严格模式

除错误处理外,非严格模式的行为同严格模式完全一致。

规则描述

合法格式

对于整数位,将数字从低位到高位,从日期最右端向左填充。以下是合法格式及其对应的填充结果(不含微秒部分):

3 位数字(abc) => 20000a 月 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.1232000-01-233 位数字
201501020304052015-01-0214 位数字
20150102030405.1234562015-01-0214 位数字,小数合法
20151231235959.999999999992015-12-3114 位数字,小数合法
1000NULL2000-10-00 中的日不合法
-123.123NULL负数时间无法得到合法日期

From Datelike Types

支持 Datetime 和 Time 类型转换为 Date 类型。

Datetime

规则描述

从 Datetime 转换时,结果为输入的日期部分。该转换必定合法。

例子

输入 DatetimeCast as Date 结果
2012-02-05 12:35:24.1234562012-02-05

Time

规则描述

从 Time 转换时,结果为当前日期与 Time 输入进行加和运算。由于该转换在可预见的未来(9999 年 12 月之前)是合法的,Doris 中认定它必定合法。

例子

假设当前日期为 2025-04-29,则:

输入 TimeCast as Date 结果
500:00:002025-05-19
23:59:592025-04-29
-128:00:002025-04-23