如何将给定的天数添加到日期并排除周末

时间:2021-07-19 21:15:01

标签: sql oracle

如何向日期字段添加天数并跳过周末的计算。

ex: if  Date  = 7/7/2021  then  Due Date = 07/21/2021`

Date = uxsubmtlDateRcvdDOP,
Number of days = 10, 
Due Date = uxsubmtlDateRcvdDOP + 10`

我有

Select uxsubmtlDateRcvdDOP + 10 as duedate

但这也计算周末。

3 个答案:

答案 0 :(得分:2)

这可以在 Oracle 中使用一个小的 PL/SQL 函数来完成,该函数使用 TRUNC(<date>, 'IW') 来查找包含您的日期的一周中的星期一。

create or replace function plus_weekdays(d0 date, weekdays number) return date
is
  d0_Monday            date;    /* Monday <= d0 */
  weekdays_from_Monday number;  /* # of weekdays to increment from d0_Monday */
  nweeks               int;     /* # of weeks to increment from d0_Monday */
  ndays                number;  /* # of days to increment after nweeks */
begin
  d0_Monday := trunc(d0, 'iw');

  if d0 - d0_Monday >= 5 then
    -- This case means the given date is a Saturday or Sunday.
    -- We round the given date up to the next Monday and decerement the 
    -- number of weekdays that we are adding. For example:
    --   Saturday - 1 = Thursday (computed as Monday - 2)
    --   Saturday + 0 = Friday   (computed as Monday - 1)
    --   Saturday + 1 = Monday   (computed as Monday + 0)
    --   Saturday + 2 = Tuesday  (computed as Monday + 1)

    d0_Monday := d0_Monday + 7;
    weekdays_from_Monday := weekdays - 1;
  else
    weekdays_from_Monday := weekdays + (d0 - d0_Monday);
  end if;

  nweeks := floor(weekdays_from_Monday / 5);
  ndays  := (weekdays_from_Monday - nweeks * 5);

  return d0_Monday + nweeks * 7 + ndays;
end;
/
show errors;

SQL> select plus_weekdays(DATE '2020-07-07', 10) from dual;

PLUS_WEEK                                                                       
---------                                                                       
21-JUL-20                                                                       

答案 1 :(得分:1)

您可以使用:

SELECT date_value,
       added_weekdays,
       weekday_date_value
       + MOD(added_weekdays, 5)        -- Number of days of part week
       + FLOOR(added_weekdays / 5) * 7 -- Number of full weeks
       + CASE TRUNC( weekday_date_value + MOD(added_weekdays, 5) )
              - TRUNC( weekday_date_value + MOD(added_weekdays, 5), 'IW' )
         WHEN 5 THEN 2
         WHEN 6 THEN 1
         ELSE 0 END                    -- Shift value if it falls on a weekend.
         AS final_value
FROM   (
  SELECT t.*,
         date_value
         + CASE TRUNC(date_value) - TRUNC(date_value, 'IW')
           WHEN 5 THEN 2
           WHEN 6 THEN 1
           ELSE 0 END AS weekday_date_value -- Shift the start date if it is on
                                            -- a weekend. 
  FROM   table_name t
)

对于样本数据:

CREATE TABLE table_name ( date_value, added_weekdays ) AS
SELECT DATE '2021-07-07', 10 FROM DUAL UNION ALL
SELECT DATE '2021-07-07', 11 FROM DUAL UNION ALL
SELECT DATE '2021-07-07', 12 FROM DUAL UNION ALL
SELECT DATE '2021-07-07', 13 FROM DUAL UNION ALL
SELECT DATE '2021-07-10',  0 FROM DUAL UNION ALL
SELECT DATE '2021-07-10',  1 FROM DUAL;

输出(日期格式为 YYYY-MM-DD (DY)):

<块引用>
<头>
DATE_VALUE ADDED_WEEKDAYS FINAL_VALUE
2021-07-07(周三) 10 2021-07-21(周三)
2021-07-07(周三) 11 2021-07-22 (星期四)
2021-07-07(周三) 12 2021-07-23 (周五)
2021-07-07(周三) 13 2021-07-26 (星期一)
2021-07-10 (SAT) 0 2021-07-12 (星期一)
2021-07-10 (SAT) 1 2021-07-13 (周二)

db<>fiddle here

答案 2 :(得分:-1)

Dateadd(mydate,,trunc(mydays/5)*7 + mod(mydays,5) + 2*trunc((weekday(mydate)+mod(mydays,5))/7))

最后一个学期检查你是否跨越了最后一个周末的界限。

如果您的开始日期是周六或周日,这有点奇怪。星期五 + 1 天 = 星期一,星期六 + 1 天 = 星期二,但星期日 + 1 天是星期一。