有时我们需要在一个日期的基础杀那个增加某个时间长度或者减去某个时间长度,比如我们知道每个员工的出生日期,而想计算出他出生后10000填的日期,再如我们想计算所有合同到期的3个月后的日期。由于存在每个月天数不同、闰月等复杂的立法规则,所以本鞥使用简单地数字加减发进行计算,主流的数据库系统中都提供了对日期增减的计算下面分别进行介绍。
1. MySQL
MySQL中提供的DATE_ADD() 函数用于进行日期时间的加法运算,这个函数还有一个别名为ADDDATE(), DATE_ADD()函数的参数格式如下:
DATE_ADD(date, INTERVAL, expr type)
其中参数date为待计算的日期;参数expr为待进行加法运算的增量,它可以说数值类型或者字符串类型,取决于type参数的取值;参数type则为进行加法运算的单位。type参数可选值;参数type则为进行加法运算的单位。type参数可选值及对应的expr参数的格式如下表所示:
Type 参数值 |
Expr 参数格式 |
说明 |
MICROSECOND |
数值类型 |
以微秒为计算单位 |
MINUTE |
数值类型 |
以秒为单位 |
HOUR |
数值类型 |
以小时为单位 |
DAY |
数值类型 |
以天为单位 |
WEEK |
数值类型 |
以周为单位 |
MONTH |
数值类型 |
以月为单位 |
QUARTER |
数值类型 |
以季度为单位 |
YEAR |
数值类型 |
以年为单位 |
HOUR_MINUTE |
字符串类型,格式为: ‘HOURS:MINUTES’ |
以秒小时、分钟为计算单位,要求 expr参数必须是“小时 :分”的格式,比如“ 30:10”增加 30小时 10分钟 |
DAY_HOUR |
字符串类型,格式为: ‘DAYS HOURS’ |
以天、小时为计算单位,要求 expr参数必须是“天 小时”的格式,比如“ 30 10”表示增加 30天 10小时 |
YEAR_MONTH |
字符串类型,格式为: ‘YEARS-MONTHS’ |
以年、月为计算单位,要求 expr参数必须是“年 -月”的格式,比如“ 2-8”表示增加 2年 8个月 |
表中前9种用法都非常简单,比如DATE_ADD(date, INTERVAL 1 HOUR)就可以得到在日期date基础上增加一小时后的日期时间。
下面的SQL语句用来计算每个人出生一周、两个月及5个季度后的日期:
SELECT FBirthday,
DATE_ADD(FBirthday, INTERVAL 1 WEEK) as w1,
DATE_ADD(FBirthday, INTERVAL 2 MONTH) as m2,
DATE_ADD(FBirthday, INTERVAL 5 QUARTER) as q5
FROM T_Person
比如下面的SQL语句分别结算出生日期后3天2小时10分钟、6个月的日期时间:
SELECT FBirthdaty, DATE_ADD(FBirthday, INTERVAL '3 2:10' DAY_MINUTE) as dm,
DATE_ADD(FBirthday, INTERVAL '1-6' YEAR_MONTH) as ym
FROM T_Person
几乎所有版本的MySQL都支持DATE_ADD()函数的前9中用法,但是MySQL的早期版本不完全支持DATE_ADD()函数的后几种用法,不过在MySQL的早期版本中可以嵌套调用DATE_ADD()函数来实现后几种用法的效果。下面的SQL语句使用嵌套函数的方式来分别计算出生日期后1年6个月的日期时间:
SELECT FBirthday, DATE_ADD(DATE_ADD(FBirthday, INTERVAL 1 YEAR), INTERVAL 6 MONTH) as dm FROM T_Person
DATE_ADD()函数不仅可以用来做日期基础上增加指定的时间段,而且还可以在日期的基础上减少指定的时间段,只要在expr参数中使用负数就可以了。下面SQL语句用来计算每个人出生一周、两个月及5个季度前的日期:
SELECT FBirthday, DATE_ADD(FBirthday, INTERVAL -1 WEEK) as w1, DATE_ADD(FBirthday, INTERVAL -2 MONTH) as m2, DATE_ADD(FBirthday, INTERVAL -5 QUARTER) as q5 FROM T_Person
在MySQL中提供了DATE_SUB()函数用于计算指定日期前的特定时间段的日期,期效果和在DATE_ADD()函数中使用负数的expr参数的效果一样,其用法也和DATE_ADD()几乎相同。下面的SQL语句用来计算每个人出生一周、两个月及3天2小时1-分钟前的日期:
SELECT FBirthday, DATE_SUB(FBirthday, INTERVAL 1 WEEK) as w1, DATE_SUB(FBirthday, INTERVAL 2 MONTH) as m2,DATE_SUB(FBirthday, INTERVAL '3 2:10' DAY_MINUTE) as dm FROM T_Person