日期和时间函数
以下为GaussDB MySQL兼容性日期时间函数公共说明。
- 开发指南中函数入参为时间类型表达式的情况:
时间类型表达式主要包括text、datetime、date或time,但所有可以隐式转换为时间表达式的类型都可以作为入参,比如数字类型可以通过先隐式转化为text,再作为时间类型表达式生效。
但是生效的情况根据函数有所不同,比如:datediff由于只计算日期的差值,所以时间表达式会当做日期来解析。timestampdiff由于计算时间差值时是根据unit来决定的,所以会根据unit选择将时间表达式当做date或者time或者datetime来解析。
- 函数入参为无效日期的情况:
一般而言,日期时间函数支持date、datetime的范围和MySQL保持一致。date支持的范围为'0000-01-01'到'9999-12-31',datetime支持的范围为'0000-01-01 00:00:00'到'9999-12-31 23:59:59'。虽然GaussDB支持的date、datetime范围大于MySQL,但是越界仍然算无效日期。
大部分时间函数会告警并返回NULL,只有能通过cast正常转换的日期,才是正常合理的日期。
GaussDB的日期时间函数的大部分功能场景与MySQL一致,但仍有差异,一些差异如下:
- 函数入参为NULL时,函数返回NULL,无warning或error告警。这些函数包括:
from_days、date_format、str_to_date、datediff、timestampdiff、date_add、subtime、month、time_to_sec、to_days、to_seconds、dayname、monthname、convert_tz、sec_to_time、addtime、adddate、date_sub、timediff、last_day、weekday、from_unixtime、unix_timestamp、subdate、day、year、weekofyear、dayofmonth、dayofyear、week、yearweek、dayofweek、time_format、hour、minute、second、microsecond、quarter、get_format、extract、makedate、period_add、timestampadd、period_diff、utc_time、utc_timestamp、maketime、curtime
示例:
gaussdb=# select day(null); day ----- (1 row)
- 纯数字入参个别函数与MySQL有差异,不带引号的数字入参统一转成text入参来处理。
gaussdb=# select day(19231221.123141); WARNING: Incorrect datetime value: "19231221.123141" CONTEXT: referenced column: day day ----- (1 row)
- 时间日期运算函数:adddate、subdate、date_add、date_sub。当运算后的结果为日期时,支持的范围为[0000-01-01, 9999-12-31],当运算后的结果为日期时间时,支持的范围为[0000-01-01 00:00:00.000000, 9999-12-31 23:59:59.999999],当运算后的结果超过支持的范围时,在严格模式下报ERROR,在宽松模式下报WARNING。另外,当运算后的日期结果在范围[0000-01-01, 0001-01-01]中时,GaussDB正常返回结果,MySQL返回'0000-00-00'。
gaussdb=# SELECT subdate('0000-01-01', interval 1 hour); ERROR: Datetime function: datetime field overflow CONTEXT: referenced column: subdate gaussdb=# SELECT subdate('0001-01-01', interval 1 day); subdate ------------- 0000-12-31 (1 row)
- 对于日期和时间函数的date或datetime类型入参,含有0月或0日则为非法值,在严格模式下报error;在宽松模式,当输入为字符串或数字时,报warning,输入为date或datetime类型时视为上一年12月或上一月最后一日处理。
对于cast函数,转换为date、datetime时,严格模式下会报error;宽松模式下不会报warning,而是视为上一年12月或上一月最后一日处理,需要注意此区别。MySQL对于包含0年、0月或0日的情况会原样输出。
示例:
gaussdb=# select adddate('2023-01-00', 1);-- 严格模式 ERROR: Incorrect datetime value: "2023-01-00" CONTEXT: referenced column: adddate gaussdb=# select adddate('2023-01-00', 1);-- 宽松模式 WARNING: Incorrect datetime value: "2023-01-00" CONTEXT: referenced column: adddate adddate --------- (1 row) gaussdb=# select adddate(date'2023-00-00', 1);-- 宽松模式 adddate ------------ 2022-12-01 (1 row) gaussdb=# select cast('2023/00/00' as date);-- 宽松模式 date ------------ 2022-11-30 (1 row) gaussdb=# select cast('0000-00-00' as datetime);-- 宽松模式 timestamp --------------------- 0000-00-00 00:00:00 (1 row)
- 若函数入参为numeric数据类型,在非法输入的情况下不会产生报错,会把入参当做0值处理。
gaussdb=# select from_unixtime('aa'); from_unixtime --------------------- 1970-01-01 08:00:00 (1 row)
- 最多保留6位小数,不保留后置都为0的小数。
gaussdb=# select from_unixtime('1234567899.00000'); from_unixtime --------------------- 2009-02-14 07:31:39 (1 row)
- 时间函数参数为字符串时,只保证年月日之间使用“-”分隔,时分秒之间使用“:”分隔时结果正确。
gaussdb=# select adddate('20-12-12',interval 1 day); adddate ------------ 2020-12-13 (1 row)
- 在MySQL中,当函数的返回值为varchar时,在GaussDB中,函数对应的返回值为text。
-- GaussDB中函数的返回值。 gaussdb=# SELECT pg_typeof(adddate('2023-01-01', 1)); pg_typeof ----------- text (1 row) -- MySQL中函数的返回值。 mysql> CREATE VIEW v1 AS SELECT adddate('2023-01-01', 1); Query OK, 0 rows affected (0.00 sec) mysql> DESC v1; +--------------------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------------------+-------------+------+-----+---------+-------+ | adddate('2023-01-01', 1) | varchar(29) | YES | | NULL | | +--------------------------+-------------+------+-----+---------+-------+ 1 row in set (0.00 sec)
序号 |
MySQL数据库 |
GaussDB数据库 |
差异 |
---|---|---|---|
1 |
ADDDATE() |
支持 |
此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明。 |
2 |
ADDTIME() |
支持 |
|
3 |
CONVERT_TZ() |
支持 |
- |
4 |
CURDATE() |
支持 |
- |
5 |
CURRENT_DATE(), CURRENT_DATE |
支持 |
- |
6 |
CURRENT_TIME(), CURRENT_TIME |
支持 |
GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,其他均报错;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。 |
7 |
CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP |
支持 |
GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,超过6的整型值,会告警并按照精度6输出时间值;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。 |
8 |
CURTIME() |
支持 |
GaussDB此函数输入字符串或者非整型值,会被隐式转成整型,然后再校验精度,[0,6]范围之外的会报错,范围之内会正常输出时间值;MySQL直接报错。GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,其他均报错;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。 |
9 |
YEARWEEK() |
支持 |
- |
10 |
DATE_ADD() |
支持 |
此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明。 |
11 |
DATE_FORMAT() |
支持 |
- |
12 |
DATE_SUB() |
支持 |
此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明。 |
13 |
DATEDIFF() |
支持 |
- |
14 |
DAY() |
支持 |
- |
15 |
DAYNAME() |
支持 |
- |
16 |
DAYOFMONTH() |
支持 |
- |
17 |
DAYOFWEEK() |
支持 |
- |
18 |
DAYOFYEAR() |
支持 |
- |
19 |
EXTRACT() |
支持 |
- |
20 |
FROM_DAYS() |
支持 |
- |
21 |
FROM_UNIXTIME() |
支持 |
- |
22 |
GET_FORMAT() |
支持 |
- |
23 |
HOUR() |
支持 |
- |
24 |
LAST_DAY |
支持 |
- |
25 |
LOCALTIME(), LOCALTIME |
支持 |
GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,其他整型值直接报错;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。 |
26 |
LOCALTIMESTAMP, LOCALTIMESTAMP() |
支持 |
GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,超过6的整型值,会告警并按照精度6输出时间值;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。 |
27 |
MAKEDATE() |
支持 |
- |
28 |
MAKETIME() |
支持 |
与MySQL相比, 入参为NULL时,GaussDB不支持maketime函数自嵌套,MySQL支持。 |
29 |
MICROSECOND() |
支持 |
- |
30 |
MINUTE() |
支持 |
- |
31 |
MONTH() |
支持 |
- |
32 |
MONTHNAME() |
支持 |
- |
33 |
NOW() |
支持 |
GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,超过6的整型值,会告警并按照精度6输出时间值;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。 |
34 |
PERIOD_ADD() |
支持 |
当入参period或结果小于0时,GaussDB参考MySQL8.0.x版本的表现,报错处理。MySQL5.7会发生整数回绕,导致计算结果异常。 |
35 |
PERIOD_DIFF() |
支持 |
当入参或结果小于0时,GaussDB参考MySQL8.0.x版本的表现,报错处理。MySQL5.7会发生整数回绕,导致计算结果异常。 |
36 |
QUARTER() |
支持 |
- |
37 |
SEC_TO_TIME() |
支持 |
- |
38 |
SECOND() |
支持 |
- |
39 |
STR_TO_DATE() |
支持 |
返回值与MySQL有差异,GaussDB返回的是text,MySQL返回的是datetime、date。 |
40 |
SUBDATE() |
支持 |
此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明。 |
41 |
SUBTIME() |
支持 |
|
42 |
SYSDATE() |
支持 |
MySQL入参整型值会按照一字节最大值255整数回绕,Gauss不回绕。 |
43 |
YEAR() |
支持 |
- |
44 |
TIME_FORMAT() |
支持 |
- |
45 |
TIME_TO_SEC() |
支持 |
- |
46 |
TIMEDIFF() |
支持 |
- |
47 |
WEEKOFYEAR() |
支持 |
- |
48 |
TIMESTAMPADD() |
支持 |
- |
49 |
TIMESTAMPDIFF() |
支持 |
- |
50 |
TO_DAYS() |
支持 |
- |
51 |
TO_SECONDS() |
支持 |
- |
52 |
UNIX_TIMESTAMP() |
支持 |
返回值与MySQL有差异,GaussDB返回的是numeric,MySQL返回的是int。 |
53 |
UTC_DATE() |
支持 |
MySQL支持无括号调用,GaussDB不支持。MySQL入参整型值会按照一字节最大值255整数回绕。 MySQL入参只支持0-6整数, GaussDB支持可以隐式转换为0-6的输入。 |
54 |
UTC_TIME() |
支持 |
|
55 |
UTC_TIMESTAMP() |
支持 |
|
56 |
WEEK() |
支持 |
- |
57 |
WEEKDAY() |
支持 |
- |