更新时间:2024-12-13 GMT+08:00
分享

日期和时间函数

以下为GaussDB数据库MySQL兼容性B模式中日期时间函数的公共说明,与MySQL行为一致。

  • 函数入参为时间类型表达式的情况:

    时间类型表达式主要包括text、datetime、date或time,但所有可以隐式转换为时间表达式的类型都可以作为入参,比如数字类型可以通过先隐式转化为text,再作为时间类型表达式生效。

    但是,不同函数的具体生效情况会有所不同。例如:datediff函数仅计算日期之间的差值,因此时间表达式会被解析为日期;而timestampdiff函数在计算时间差值时,会根据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正常转换的日期,才是正常合理的日期。

  • 函数入参的分隔符场景:

    对于时间函数,处理入参时会将所有非数字字符视作分隔符,然后根据数字所处的位置进行计算,推荐使用标准写法,年月日之间使用-分隔符,时分秒之间使用:分隔符,毫秒之前通过.来进行分隔。

    易错场景:在MySQL兼容性B模式数据库中执行“SELECT timestampdiff(hour, '2020-03-01 00:00:00', '2020-02-28 00:00:00+08');”时,时间函数不会自动计算时区,所以此处+08并未识别为时区,而是+作为分隔符当作秒来进行计算。

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)
表1 日期与和时间函数列表

MySQL数据库

GaussDB数据库

差异

ADDDATE()

支持,存在差异

此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明

ADDTIME()

支持,存在差异

  • MySQL对第二入参为DATETIME样式字符串返回NULL,GaussDB可以计算。
  • 入参取值范围为['0001-01-01 00:00:00', 9999-12-31 23:59:59.999999]。
  • MySQL中ADDTIME函数如果第一个参数是动态参数(例如在预准备语句中),则返回类型为TIME。否则,函数的解析类型派生自第一个参数的解析类型。GaussDB中ADDTIME函数的返回值规则如下:
    • 第一个入参为date,第二个入参为date,返回值为time。
    • 第一个入参为date,第二个入参为text,返回值为text。
    • 第一个入参为date,第二个入参为datetime,返回值为time。
    • 第一个入参为date,第二个入参为time,返回值为time。
    • 第一个入参为text,第二个入参为date,返回值为text。
    • 第一个入参为text,第二个入参为text,返回值为text。
    • 第一个入参为text,第二个入参为datetime,返回值为text。
    • 第一个入参为text,第二个入参为time,返回值为text。
    • 第一个入参为datetime,第二个入参为date,返回值为datetime。
    • 第一个入参为datetime,第二个入参为text,返回值为text。
    • 第一个入参为datetime,第二个入参为datetime,返回值为datetime。
    • 第一个入参为datetime,第二个入参为time,返回值为datetime。
    • 第一个入参为time,第二个入参为date,返回值为time。
    • 第一个入参为time,第二个入参为text,返回值为text。
    • 第一个入参为time,第二个入参为datetime,返回值为time。
    • 第一个入参为time,第二个入参为time,返回值为time。

CONVERT_TZ()

支持

-

CURDATE()

支持

-

CURRENT_DATE(), CURRENT_DATE

支持

-

CURRENT_TIME(), CURRENT_TIME

支持,存在差异

GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,其他均报错;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。

CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP

支持,存在差异

GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,超过6的整型值,会告警并按照精度6输出时间值;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。

CURTIME()

支持,存在差异

GaussDB此函数输入字符串或者非整型值,会被隐式转成整型,然后再校验精度,[0,6]范围之外的会报错,范围之内会正常输出时间值;MySQL直接报错。GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示,GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,其他均报错;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。

YEARWEEK()

支持

-

DATE_ADD()

支持,存在差异

此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明

DATE_FORMAT()

支持

-

DATE_SUB()

支持,存在差异

此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明

DATEDIFF()

支持

-

DAY()

支持

-

DAYNAME()

支持

-

DAYOFMONTH()

支持

-

DAYOFWEEK()

支持

-

DAYOFYEAR()

支持

-

EXTRACT()

支持

-

FROM_DAYS()

支持

-

FROM_UNIXTIME()

支持

-

GET_FORMAT()

支持

-

HOUR()

支持

-

LAST_DAY

支持

-

LOCALTIME(), LOCALTIME

支持,存在差异

GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,其他整型值直接报错;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。

LOCALTIMESTAMP, LOCALTIMESTAMP()

支持,存在差异

GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,超过6的整型值,会告警并按照精度6输出时间值;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。

MAKEDATE()

支持

-

MAKETIME()

支持,存在差异

与MySQL相比, 入参为NULL时,GaussDB不支持maketime函数自嵌套,MySQL支持。

MICROSECOND()

支持

-

MINUTE()

支持

-

MONTH()

支持

-

MONTHNAME()

支持

-

NOW()

支持,存在差异

GaussDB的按精度输出的时间值(小数点后的值)是四舍五入的;MySQL是直接截断的。GaussDB按精度输出的时间值(小数点后的值)末尾0都不显示;MySQL会显示。GaussDB只支持输入[0,6]范围内的整型值,作为返回时间的精度,超过6的整型值,会告警并按照精度6输出时间值;MySQL的精度值有效值是[0,6],但是输入的整型值内部会对256求余(例257,会返回精度1的时间值)。

PERIOD_ADD()

支持,存在差异

当入参period或结果小于0时,GaussDB参考MySQL 8.0.x版本的表现,报错处理。MySQL 5.7会发生整数回绕,导致计算结果异常。

PERIOD_DIFF()

支持,存在差异

当入参或结果小于0时,GaussDB参考MySQL 8.0.x版本的表现,报错处理。MySQL 5.7会发生整数回绕,导致计算结果异常。

QUARTER()

支持

-

SEC_TO_TIME()

支持

-

SECOND()

支持

-

STR_TO_DATE()

支持,存在差异

返回值与MySQL有差异,GaussDB返回的是text,MySQL返回的是datetime、date。

SUBDATE()

支持,存在差异

此函数的表现会因为interval表达式的差异与MySQL有差异,具体可见INTERVAL差异说明

SUBTIME()

支持,存在差异

  • MySQL对第二入参为DATETIME样式字符串返回NULL,GaussDB可以计算。
  • 入参取值范围为['0001-01-01 00:00:00', 9999-12-31 23:59:59.999999]。
  • MySQL中SUBTIME函数如果第一个参数是动态参数(例如在预准备语句中),则返回类型为 TIME。否则,函数的解析类型派生自第一个参数的解析类型。GaussDB中SUBTIME函数的返回值规则如下:
    • 第一个入参为date,第二个入参为date,返回值为time。
    • 第一个入参为date,第二个入参为text,返回值为text。
    • 第一个入参为date,第二个入参为datetime,返回值为time。
    • 第一个入参为date,第二个入参为time,返回值为time。
    • 第一个入参为text,第二个入参为date,返回值为text。
    • 第一个入参为text,第二个入参为text,返回值为text。
    • 第一个入参为text,第二个入参为datetime,返回值为text。
    • 第一个入参为text,第二个入参为time,返回值为text。
    • 第一个入参为datetime,第二个入参为date,返回值为datetime。
    • 第一个入参为datetime,第二个入参为text,返回值为text。
    • 第一个入参为datetime,第二个入参为datetime,返回值为datetime。
    • 第一个入参为datetime,第二个入参为time,返回值为datetime。
    • 第一个入参为time,第二个入参为date,返回值为time。
    • 第一个入参为time,第二个入参为text,返回值为text。
    • 第一个入参为time,第二个入参为datetime,返回值为time。
    • 第一个入参为time,第二个入参为time,返回值为time。

SYSDATE()

支持,存在差异

MySQL入参整型值会按照一字节最大值255整数回绕,GaussDB不回绕。

YEAR()

支持

-

TIME_FORMAT()

支持

-

TIME_TO_SEC()

支持

-

TIMEDIFF()

支持

-

WEEKOFYEAR()

支持

-

TIMESTAMPADD()

支持

-

TIMESTAMPDIFF()

支持

-

TO_DAYS()

支持

-

TO_SECONDS()

支持

-

UNIX_TIMESTAMP()

支持,存在差异

返回值与MySQL有差异,GaussDB返回的是numeric,MySQL返回的是int。

UTC_DATE()

支持,存在差异

  • MySQL支持无括号调用,GaussDB不支持。MySQL入参整型值会按照一字节最大值255整数回绕。
  • MySQL入参只支持0-6整数, GaussDB支持可以隐式转为0-6的输入。

UTC_TIME()

支持,存在差异

UTC_TIMESTAMP()

支持,存在差异

WEEK()

支持

-

WEEKDAY()

支持

-

相关文档