# 时间和日期运算函数
#### age(timestamp, timestamp)
描述：将两个参数相减，并以年、月、日作为返回值。若相减值为负，则函数返回亦为负。
返回值类型：interval
示例：
```
SELECT age(timestamp '2001-04-10', timestamp '1957-06-13');
           age           
-------------------------
 43 years 9 mons 27 days
(1 row)
```
#### age(timestamp)
描述：当前时间和参数相减。
返回值类型：interval
示例：
```
SELECT age(timestamp '1957-06-13');
           age           
-------------------------
 68 years 7 mons 7 days
(1 row)
```
 #### adddate(date, interval \| int)
描述：返回给定日期时间加上指定单位的时间间隔的结果。默认单位（即第二个参数为整型时）为天数。
返回值类型：timestamp
示例：
当入参为text类型时：
```
SELECT adddate('2020-11-13', 10);
  adddate
------------
 2020-11-23
(1 row)
SELECT adddate('2020-11-13', interval '1' month);
  adddate
------------
 2020-12-13
(1 row)
SELECT adddate('2020-11-13 12:15:16', interval '1' month);
       adddate
---------------------
 2020-12-13 12:15:16
(1 row)
SELECT adddate('2020-11-13', interval '1' minute);
       adddate
---------------------
 2020-11-13 00:01:00
(1 row)
```
当入参为date类型时：
```
SELECT adddate(current_date, 10);
  adddate
------------
 2021-09-24
(1 row)
SELECT adddate(date '2020-11-13', interval '1' month);
       adddate
---------------------
 2020-12-13 00:00:00
(1 row)
```
 #### subdate(date, interval \| int)
描述：返回给定日期时间减去指定单位的时间间隔的结果。默认单位（即第二个参数为整型时）为天数。
返回值类型：timestamp
示例：
当入参为text类型时：
```
SELECT subdate('2020-11-13', 10);
  subdate
------------
 2020-11-03
(1 row)
SELECT subdate('2020-11-13', interval '2' month);
  subdate
------------
 2020-09-13
(1 row)
SELECT subdate('2020-11-13 12:15:16', interval '1' month);
       subdate
---------------------
 2020-10-13 12:15:16
(1 row)
SELECT subdate('2020-11-13', interval '2' minute);
       subdate
---------------------
 2020-11-12 23:58:00
(1 row)
```
当入参为date类型时：
```
SELECT subdate(current_date, 10);
  subdate
------------
 2021-09-05
(1 row)
SELECT subdate(current_date, interval '1' month);
       subdate
---------------------
 2021-08-15 00:00:00
(1 row)
```
#### addtime(timestamp \| time \| text, interval \| text \| numeric)
描述：返回给定日期/时间加上指定时间间隔的结果。该函数仅8.2.0及以上集群版本支持。
- 如果第一个参数为timestamp，函数返回timestamp。
- 如果第一个参数为time或text，函数返回text或time（取决于具体实现和兼容性配置，通常表现为字符串格式的时间），且支持超过24 小时的时间表示（类似于MySQL 行为）。

- 支持第二个参数为numeric类型（通常表示秒数）。
- 支持第二个参数为text类型（解析为时间格式或数值）。
- 当输入文本包含无效字符时，会尝试截断并处理首字符负号的情况。
返回值类型：与第一个入参类型相同。
示例：
给定时间（Timestamp类型）加指定时间间隔 （Interval类型）。
```
SELECT ADDTIME('2020-11-13 01:01:01', '23:59:59');
addtime
---------------------
2020-11-14 01:01:00
(1 row)
```
给定时间（text类型）加指定时间间隔（text类型）返回结果可超过24小时。
```
SELECT ADDTIME('20:1:1', '20:59:59+8');
addtime
----------
41:01:00
(1 row)
```
给定时间（time类型）加指定时间间隔数值（numeric类型，通常表示秒数）。
```
SELECT addtime('10:00:00', 1.999999);
addtime
-----------------
10:00:01.999999
(1 row)
```
给定时间（text类型）加带有无效字符的文本时，会截断无效字符。
```
SELECT addtime('12:30:45', '00:15:30xyz');
addtime
----------
12:46:15
(1 row)
```
#### subtime(timestamp \| time \| text, interval \| text \| numeric)
描述：返回给定日期/时间减去指定时间间隔的结果。该函数仅8.2.0及以上集群版本支持。
返回值类型：与第一个入参类型相同。
示例：
timestamp减interval。
```
SELECT subtime('2020-11-13 01:01:01', '23:59:59');
subtime
---------------------
2020-11-12 01:01:02
(1 row)
```
time减数值 (数值视为秒)。
```
SELECT subtime('10:00:00', 1.999999);
subtime
-----------------
09:59:58.000001
(1 row)
```
处理负数文本输入。
```
SELECT subtime('10:00:00', '-59.9999999');
subtime
----------
10:01:00
(1 row)
```
文本输入包含负号及无效字符。
```
SELECT subtime('12:30:45', '-00:10:15abc');
subtime
----------
12:41:00
(1 row)
```
#### date_add(date, interval)
描述：返回给定日期时间加上指定单位的时间间隔的结果。等效于[adddate(date, interval \| int)]。
返回值类型：timestamp
#### date_sub(date, interval)
描述：返回给定日期时间减去指定单位的时间间隔的结果，等效于[subdate(date, interval \| int)]。
返回值类型：timestamp
#### timestampadd(field, numeric \| text, timestamp)
描述：将以单位field的整数时间间隔（秒数可以带小数）添加到日期时间表达式中。若数值为负，则表示从给定的时间日期时间表达式中减去对应的时间间隔。
field 支持的参数：year，month，quarter，day，week，hour，minute，second，microsecond。
截断逻辑：
- 当第二个参数为 **数值 (numeric)** 时：支持小数运算（如 1.5 year）。
- 当第二个参数为 **文本 (text)** 时：
  - 若 field 为 second：保留小数部分进行计算。
  
  - 若 field 为其他单位（如 day, year 等）：**小数部分会被截断**（取整），仅使用整数部分进行计算。这是为了解决与 MySQL 行为不一致的问题。
   
![](https://support.huaweicloud.com/sqlreference-911-dws/public_sys-resources/note_3.0-zh-cn.png)
当函数传入的时间表达式格式为yyyy-mon-day+{value}的格式时，其中{value}字段将被解析为时区表达式，表示当前时间的时区，如'2023-01-31+1'将被解析为东一区时区的2023年01月31日。DWS这种表达式传入格式的解析与MySQL解析规则不一致，MySQL数据库仅当开启宽松解析规则才能支持此类格式，且解析结果为系统时区的2023年01月31日1时。
返回值类型：timestamp
示例：
基础整数加法。
```
SELECT timestampadd(year, 1, timestamp '2020-2-29');
    timestampadd
---------------------
 2021-02-28 00:00:00
(1 row)
```
数值类型支持小数 (Month 2.8，约等于2个月+0.8个月)。
```
SELECT timestampadd(month, 2.8, '2020-01-31'::timestamp);
    timestampadd     
---------------------
 2020-04-30 00:00:00
(1 row)
```
文本类型在非second 单位下的截断行为（Day '30.9' 被截断为30）。
```
SELECT timestampadd(day, '30.9', '2016-02-29');
    timestampadd     
---------------------
 2016-03-30 00:00:00
(1 row)
```
文本类型在second单位下保留小数。
```
SELECT timestampadd(second, '-4.999999', '2016-03-28 10:00:00');
        timestampadd        
----------------------------
 2016-03-28 09:59:55.000001
(1 row)
```
#### timestampdiff(field, timestamp1, timestamp2)
描述：将两个日期参数相减(timestamp2 - timestamp1)，并以单位field作为返回值。若相减值为负，则函数返回值为负。field支持的参数为year、month、quarter、day、week、hour、minute、second和microsecond。
返回值类型：bigint
示例：
```
SELECT timestampdiff(day, timestamp '2001-02-01', timestamp '2003-05-01 12:05:55');
 timestampdiff 
---------------
      819
(1 row)
```
#### timediff(timestamp \| time \| text, timestamp \| time \| text)
描述：将两个日期参数相减。若相减值为负，则函数返回值为负。该函数仅8.2.0及以上集群版本支持。
- 两个入参类型应当一致，或者可以隐式转换为一致的类型（均支持 text 格式输入）。
- 若第一个参数小于第二个参数，返回值为负数。
- 该函数支持计算结果超过24小时的差值。
返回值类型：time
示例：
timestamp相减。
```
SELECT TIMEDIFF('2022-7-5 1:1:1'::timestamp, '2022-7-5 2:2:2');
 timediff  
-----------
 -01:01:01
(1 row)
```
time相减 (结果为负)。
```
SELECT TIMEDIFF('1:1:1'::TIME, '23:22:59');
 timediff  
-----------
 -22:21:58
(1 row)
```
text格式相减。
```
SELECT TIMEDIFF('1:1:1', '23:22:59');
 timediff  
-----------
 -22:21:58
(1 row)
```
#### datediff(date1, date2)
描述：返回给定日期之间相差的天数值。
返回值类型：bigint
示例：
```
SELECT datediff(date '2020-11-13', date '2012-10-16');
 datediff
----------
     2950
(1 row)
```
#### period_add(P, N)
描述：返回给定时期加上N个月后的日期。
返回值类型：integer
示例：
```
SELECT period_add(200801, 2);
 period_add
------------
     200803
(1 row)
```
#### period_diff(P1, P2)
描述：返回给定日期之间的月数差值。
返回值类型：integer
```
SELECT period_diff(200802, 200703);
 period_diff
-------------
          11
(1 row)
```
#### add_months(d,n)
描述：用于计算日期date加上n个月后的日期值。
返回值类型：timestamp
示例：
```
SELECT add_months(to_date('2017-5-29', 'yyyy-mm-dd'), 11) FROM dual;
     add_months      
---------------------
 2018-04-29 00:00:00
(1 row)
```
