问题
I have a requirement to generate to Billing cycle date, ex
- if My input is 27th March then my next cycle starts from 27 april.
- If input is 10th Jan then next cycle should start from 10th Feb.
I am using Oracle Add_Month(i/p Date, 1). This add a new month and give me same date for next month, working fine for above mentioned dates.
But there is one corner case when my Input date is 28th Feb, 2018 and If I do select ADD_MONTHS(date '2018-02-28', 1) from dual then output is 31st March,2018.
I am expecting the outcome should be 28thMarch. Any poosible solution for this corner case.
回答1:
A little bit of calculation might help.
SQL> with test (col) as
2 (select date '2020-03-27' from dual union all
3 select date '2020-01-10' from dual union all
4 select date '2018-02-27' from dual union all
5 select date '2018-02-28' from dual
6 )
7 select col,
8 least(add_months(col, 1),
9 add_months(trunc(col, 'mm'), 1) + (col - trunc(col, 'mm'))
10 ) result
11 from test
12 order by col;
COL RESULT
---------- ----------
27.02.2018 27.03.2018
28.02.2018 28.03.2018
10.01.2020 10.02.2020
27.03.2020 27.04.2020
SQL>
回答2:
select to_date('28-FEB-2020', 'DD-MON-YYYY'),
ADD_MONTHS( to_date('28-FEB-2020', 'DD-MON-YYYY'), 1) from dual;
select to_date('28-FEB-2018', 'DD-MON-YYYY'),
ADD_MONTHS( to_date('28-FEB-2018', 'DD-MON-YYYY'), 1) from dual;
Above query will give you 31st March because, 28th FEB is the last day of the month on 2018 and since you are using ADD_MONTHS function, it is considering the last day of each month. Execute below query, you will understand easily,
select to_date('28-FEB-2018', 'DD-MON-YYYY'),
ADD_MONTHS( to_date('28-FEB-2018', 'DD-MON-YYYY'), 1) from dual;
回答3:
You can use below code and accordingly add conditions for 29th Feb as well if you want.
select
case when extract( day from last_day(to_date('28-FEB-2020', 'DD-MON-YYYY'))) = extract( day from to_date('28-FEB-2020', 'DD-MON-YYYY'))
then decode(extract( day from last_day(to_date('28-FEB-2020', 'DD-MON-YYYY'))), 28, to_date('28-FEB-2020', 'DD-MON-YYYY') + 28,ADD_MONTHS( to_date('28-FEB-2020', 'DD-MON-YYYY'), 1) )
else ADD_MONTHS( to_date('28-FEB-2020', 'DD-MON-YYYY'), 1) end as result
from dual;
来源:https://stackoverflow.com/questions/63128687/issue-with-add-month-in-oracle-i-need-to-generate-billing-cycle