简体   繁体   中英

Adding half month in oracle pl/sql

I get a period from another select then I have to add half month to that date but it's not working . It's not giving me an error but the month is not being added when I try to change date based on newdate and delai (which is declared as FLOAT)

d_date = ADD_MONTHS( newdate ,  delai);

When period = 0.5 running dbms_output.put_line(delai); returns: ,5

thank you

add_months() takes an integer for its second argument. It's for adding whole months to the passed date. Even that is controversial (consider the output of add_months(date '2019-02-28', 1) against add_months(date '2020-02-28', 1) ).

If we pass a float to add_months() it just rounds down rather than hurling an exception. (Also, controversial, perhaps.) Thus passing 0.5 means it just returns the input date unchanged.

So, what do you mean by "half a month"? It's not a standard unit of time, as it depends on what month we are discussing.

If you mean two weeks, use that:

d_date := new_date + interval '14' day; -- interval doesn't support WEEK in Oracle

in the database we can add by a week (0.25), 2 weeks ( 0.5 ) , a month , or a year (12 ) and so on

You need to handle it programmatically. Declare an variable to hold an interval

i interval day to second;

Then your code should look something like this:

if period < 1 then
    if period  = 0.25 then 
       i := interval '7' day; 
    elsif period  = 0.5 then 
       i := interval '14' day; 
    elsif period  = 0.75 then 
       i := interval '21' day; 
    end if;
    d_date := new_date + i;
else
    d_date := add_months(new_date, period);
end;

If you want 'half a month' to mean half the number of days in that month then you could calculate that:

declare
  d_date date;
  delai float := 0.5;
  new_date date := date '2019-01-01';
begin
  d_date := new_date + floor(delai * extract(day from last_day(new_date)));
  dbms_output.put_line(d_date);
end;
/

2019-01-16


PL/SQL procedure successfully completed.

With new_date set to 2019-02-01 instead it gives 2019-02-15.

The last_day() function gives you the date on last day of that month, as you might guess; then extract(day from ...) gives you just the day number, ie 28, 29, 30 or 31. That's then multiplied by half, and the floor() stops any fractional days being added (which would affect the time portion).

Depending on your actual requirements you might want to subtract a day, or use ceil() instead of floor() , or something else, but I think this is close to what you described.

The same approach will work whether delai is 0.5 or 0.25; but for integer values you would probably then need to switch back to add_months() . Non-integer values (1.25?) would be headache even then, if they can occur...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM