ADD_MONTHS() 如果第二个参数是小数会怎么样?

    我们经常使用ADD_MONTHS()函数来获取一个日期的几个月之后的日期,例如,我们希望得到两个月之后的日期(2013年04月05日):

ChenZw> alter session set nls_date_format = 'yyyy-mm-dd';
会话已更改。
已用时间:  00: 00: 00.00
ChenZw> select add_months(to_date('20130405','yyyymmdd'),2) from dual;
ADD_MONTHS
----------
2013-06-05
已选择 1 行。
已用时间:  00: 00: 00.00

    上面的例子中,我们得到了2013年04月05日后面第二个月的该日期,也就是2013年06月05日,这个是符合我们期望的日期。

但是这里有一个问题,如果我想得到,该日期(2013年04月05日)之后的1.2个月的日期呢?让我们看一下:

ChenZw> select add_months(to_date('20130405','yyyymmdd'),1.2) from dual;
ADD_MONTHS
----------
2013-05-05
已选择 1 行。
已用时间:  00: 00: 00.00

    咦? 这个答案好像不是我想要的,我希望的应该是1.2个月之后的啊!能不能不要这么不严谨!你应该是给我四舍五入了吧?那就告诉我1.9999999999999个月的今天是几号吧!

ChenZw> select add_months(to_date('20130405','yyyymmdd'),1.9999999999999) from dual;
ADD_MONTHS
----------
2013-05-05
已选择 1 行。
已用时间:  00: 00: 00.00

    看到这个答案,我有点无语哽咽了,幸亏没有在工作中使用啊,否则我就悲剧了,日期很有可能就算错了。Oracle,你能不能不这么坑爹。

带着疑惑的心情,去请教Oracle的官方文档:

ADD_MONTHS

Syntax


Purpose

ADD_MONTHS returns the date date plus integer months. A month is defined by the session parameter NLS_CALENDAR. The date argument can be a datetime value or any value that can be implicitly converted to DATEThe integer argument can be an integer or any value that can be implicitly converted to an integer. The return type is always DATE, regardless of the data type of date. If date is the last day of the month or if the resulting month has fewer days than the day component of date, then the result is the last day of the resulting month. Otherwise, the result has the same day component as date.

Examples

The following example returns the month after the hire_date in the sample table employees:

SELECT TO_CHAR(ADD_MONTHS(hire_date, 1), 'DD-MON-YYYY') "Next month"
  FROM employees 
  WHERE last_name = 'Baer';

Next Month
-----------
07-JUL-2002

    现在明白了,原来1.9999999999999是被直接截取成1了,Oracle所谓的implicitly convert是截掉小数点之后的部分。



posted @ 2013-04-05 12:50  坚固66  阅读(190)  评论(0编辑  收藏  举报