Is there a function to derive "business days" only
Is there either an Oracle SQL built-in function or user-defined function for calculating the difference
between two dates or between SYSDATE and a date in the database, which uses business days
only (at least excluding weekends)?
I'd appreciate any help on this!
Thanks!
Kathy Kuehnle
[ [email protected] ]
We solved this with the following package:
create or replace
package body zentr_date_functions as
function eastern (p_year in number) return date is
-- Calculate easter sunday (valid from 1900 to 2099)
-- based on a Gauss algorithm
l_a pls_integer;
l_b pls_integer;
l_c pls_integer;
l_d pls_integer;
l_e pls_integer;
l_p pls_integer;
function make_date(p_d in pls_integer, p_m in pls_integer, p_y in pls_integer) return date is
begin
return to_date(to_char(p_d, '00')||to_char(p_m, '00')||to_char(p_y, '0000'), 'DDMMYYYY');
end;
begin
if p_year not between 1900 and 2099 then
return null;
end if;
l_a := mod(p_year, 19);
l_b := mod(p_year, 4);
l_c := mod(p_year, 7);
l_d := mod(19 * l_a + 24, 30);
l_e := mod(2 * l_b + 4 * l_c + 6 * l_d + 5, 7);
l_p := 22 + l_d + l_e;
if l_p > 31 then
if l_p = 56 and l_d = 28 and l_a > 10 then
return make_date(18, 4, p_year);
elsif l_p = 57 then
return make_date(19, 4, p_year);
else
return make_date(l_p - 31, 4, p_year);
end if;
else
return make_date(l_p, 3, p_year);
end if;
end eastern;
function is_workday (p_date in date) return number as
-- Is p_date a working day?
l_eastern date;
begin
if to_char(p_date, 'DY', 'NLS_DATE_LANGUAGE = AMERICAN') in ('SAT', 'SUN') then
return 0;
end if;
if to_char(p_date, 'DDMM') in ('0101', '0105', '0310', '2412', '2512', '2612', '3112') then
return 0; -- fixed bank holidays in lower saxony, Germany
end if;
if to_number(to_char(p_date, 'MM')) not between 3 and 6 then
return 1;
end if;
if to_number(to_char(p_date, 'YYYY')) not between 1900 and 2099 then
return null;
end if;
l_eastern := eastern (to_number(to_char(p_date, 'YYYY')));
if trunc(p_date) in (l_eastern - 2, l_eastern + 1, l_eastern + 39, l_eastern + 50) then
return 0; -- eastern depentent bank holidays in lower saxony, Germany
end if;
return 1;
end is_workday;
-- This is what you are looking for:
function workdays_between (p_date1 in date, p_date2 in date) return number as
-- count number of workdays between p_date1 and p_date2 (both p_date1 and p_date2 included).
l_count pls_integer := 0;
begin
for i in 0 .. p_date2 - p_date1 loop
l_count := l_count + is_workday(p_date1 + i);
end loop;
return l_count;
end workdays_between;
end;
Similar Messages
-
Get Business days ONLY excluding Thanks giving / Christmas etc
I know how to exclude Saturday and Sunday to get weekdays only but how to get business days only excluding thanks giving/ Christmas/memorial day etc (based on the locale or some other setting) ?
(If it is country- INDIA - the list of official government holidays changes, so the query should work properly depending on the country or some other setting.)Hello userPrasad.
Business or working days can not only be affected regionally but also by the nature of the industry that the system is used for; not to mention that change can occur. The few systems that I've worked with have typically provided a user-maintained listing of dates to be considered as business/working days. Obviously, this would contain more data than the system and your coding would actually require, but this is normally the most straightforward presentation to the business user.
Make it simple
Make it obvious
Make it usable
Make it flexible
Some food for thought,
Luke
Please mark the answer as helpful or answered if it is so. If not, provide additional details.
Always try to provide create table and insert table statements to help the forum members help you better. -
Data between Date Range with Business Days only
Hi All,
We have a requirement that we need to retrieve data between a data range, providing From date and To date as input.
We also have the option to Include Business Days Only through a check box which will be passed to CR 2008 through a report frame work.
Can some one help me how to display the report data within the Date Range entered and that includes only Business Days.
Thanks in advance for the help.
Regards,
Naresh.try this formula. Lets if your date range parameter is {?date} then try this formula
@startdate:
if datepart('w',minimum({?date}))=7 then
minimum({?date})+2
else if datepart('w',minimum({?date}))=1 then
minimum({?date})+1
else
minimum({?date})
@enddate
if datepart('w',maximum({?date}))=7 then
maximum({?date})+2
else if datepart('w',maximum({?date}))=1 then
maximum({?date})+1
else
maximum({?date})
regards,
Raghavendra -
hi
version oracle 10g
Function should accept start date and business_days_to_add and it should return date.
to a given date i want to add business_days(business days are all days except SAT SUN)
lets say i want to add 4 business days to sysdate then function should return date as 09/16/2010thanksOne way of doing it:
CREATE OR REPLACE FUNCTION add_business_days(p_date IN DATE, p_bus_days IN NUMBER) RETURN DATE DETERMINISTIC IS
v_return DATE;
BEGIN
WITH t AS
(SELECT rownum rn, trunc(p_date) + decode(sign(p_bus_days), 1, LEVEL - 1, -1, (LEVEL * -1) + 1, 0) theday
FROM dual
WHERE to_char(p_date + decode(sign(p_bus_days), 1, LEVEL - 1
,-1, (LEVEL * -1) + 1
, 0), 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') NOT IN ('SAT', 'SUN')
OR ROWNUM = 1
CONNECT BY rownum <= abs(p_bus_days) + 1)
SELECT theday
INTO v_return
FROM t
WHERE rn = abs(p_bus_days) + 1;
RETURN v_return;
END;Sample execution:
SQL> CREATE OR REPLACE FUNCTION add_business_days(p_date IN DATE, p_bus_days IN NUMBER) RETURN DATE DETERMINISTIC IS
2 v_return DATE;
3 BEGIN
4 WITH t AS
5 (SELECT rownum rn, trunc(p_date) + decode(sign(p_bus_days), 1, LEVEL - 1, -1, (LEVEL * -1) + 1, 0) theday
6 FROM dual
7 WHERE to_char(p_date + decode(sign(p_bus_days), 1, LEVEL - 1
8 ,-1, (LEVEL * -1) + 1
9 , 0), 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') NOT IN ('SAT', 'SUN')
10 OR ROWNUM = 1
11 CONNECT BY rownum <= abs(p_bus_days) + 1)
12 SELECT theday
13 INTO v_return
14 FROM t
15 WHERE rn = abs(p_bus_days) + 1;
16 RETURN v_return;
17 END;
18 /
Function created
SQL> select add_business_days(sysdate, 5) from dual;
ADD_BUSINESS_DAYS(SYSDATE,5)
17/9/2010
SQL> select add_business_days(sysdate, -55) from dual;
ADD_BUSINESS_DAYS(SYSDATE,-55)
25/6/2010
SQL> select add_business_days(sysdate+1, 1) from dual;
ADD_BUSINESS_DAYS(SYSDATE+1,1)
13/9/2010
SQL> select add_business_days(sysdate+1, -1) from dual;
ADD_BUSINESS_DAYS(SYSDATE+1,-1
10/9/2010
SQL> Edited by: fsitja on Sep 10, 2010 12:49 PM Fixed to take into account negative numbers. -
Is there any function to get the name of the days?
Hi,
I'm using oracle 10.2.0.1.0
Is there any function to get the days of the week?
like i need to get sunday,monday,tuesday.....saturday.
I know i can use union and select the name from dual one by one.
But just want to know whether there is any other way.
I need to show the 7 days in a poplist in my form, thats the requirement
ThanksDavid_Aldridge wrote:
BluShadow wrote:
Note: you may want to include "fm" in the format mask, otherwise the name of the day is padded with spaces:
SQL> ed
Wrote file afiedt.buf
1 select replace(to_char(dt,'Day'),' ','*') as fmt1
2 ,length(to_char(dt,'Day')) as length_fmt1
3 ,replace(to_char(dt,'fmDay'),' ','*') as fmt2
4 ,length(to_char(dt,'fmDay')) as length_fmt2
5 from (select TRUNC(SYSDATE ,'DAY')+Level-1 dt
6 from dual
7 connect by Level<8
8* )
SQL> /
FMT1 LENGTH_FMT1 FMT2 LENGTH_FMT2
Monday*** 9 Monday 6
Tuesday** 9 Tuesday 7
Wednesday 9 Wednesday 9
Thursday* 9 Thursday 8
Friday*** 9 Friday 6
Saturday* 9 Saturday 8
Sunday*** 9 Sunday 6
7 rows selected.
SQL>
I think you should use a pl/sql function for this.
Nah ... just joking.
I'd be tempted to just use a union all statement to return the seven literals. People will look at it and know exactly what it does.Yeah, agreed, I was just demonstrating that the format mask of a to_char(..., 'Day') pads with spaces, which seems to have been missed in the above answers. ;) -
Calculate "Business Days" and account for holidays
I have played with Date math based on what I have found for documentation, and adding an arbitrary number of days is pretty easy. But what about adding an arbitrary number of business days? I found a web site that talks about "Next business day",
which could be adapted I am sure, but it only accounts for weekends. I want to calculate the date an arbitrary number of business days from a provided date. So, +3 business days calculated from a Monday should produce the date of the following Thursday,
and calculated from a Friday should produce the date of the next Wednesday. And calculated from Friday Sept 4, 2015 (Friday before Labor Day) should produce Thursday Sept 10, 2015.
Given that Windows is very business focused, I wonder if there is some nice hidden .NET functionality to calculate business days based on holidays as well? I know, some offices might give extra days off, four day weekends, etc. But those would be edge case
enough to be safely ignorable for my purposes. Indeed, even holidays could probably be ignored, but if there is a quick approach I would rather use it. If I would need to code some sort of Exchange calendar scraper or some such, I'll live with just accounting
for weekends. ;)You can pull holiday info from outlook.hol file and do the date math based on it. It won't be 100% reliable though. Not all the holidays listed in calendar are non-business days (not in all countries at least). International support may also present additional
issues: in some countries it is a common practice to "move" weekend days to fill a single day gap between holidays and weekend (which screws up next business day calc anyway, regardless of holiday info :-). Not to mention all the possible industry-wide
or company specific policies regarding working days.
Gleb. -
Service Requests-Business days when year changes
Hi All,
I am trying to calculate for how long a SR has been open in business days only.
I have successfully used Mike Lairson's formula for the last 9 months but it seems it cannot cope with year changes. If the begin data is in 2009 and the end date in 2010, the results are not correct anymore.
E.G. For an SR that was opened on 12/30/2009 and closed on 01/05/2010 should return 5 business days but it is actually returning 110.
The syntax that I used so far is:
(CASE
/* Convert Sunday to the Business Day Of the Year */
WHEN DAYOFWEEK("Service Request"."Closed Date and Time") = 1
THEN (DAYOFYEAR("Service Request"."Closed Date and Time") - WEEK("Service Request"."Closed Date and Time")) -
(WEEK("Service Request"."Closed Date and Time") - 2)
/* Convert Saturday to the Business Day Of the Year */
WHEN DAYOFWEEK("Service Request"."Closed Date and Time") = 7
THEN (DAYOFYEAR("Service Request"."Closed Date and Time") - WEEK("Service Request"."Closed Date and Time")) -
(WEEK("Service Request"."Closed Date and Time") - 1)
/* Convert Mon-Fri to the Business Day Of the Year */
ELSE (DAYOFYEAR("Service Request"."Closed Date and Time") -
WEEK("Service Request"."Closed Date and Time")) +
(2 - WEEK("Service Request"."Closed Date and Time")) END)
(CASE
/* Convert Sunday to the Business Day Of the Year */
WHEN DAYOFWEEK("Service Request"."Opened Date") = 1
THEN (DAYOFYEAR("Service Request"."Opened Date") -
WEEK("Service Request"."Opened Date")) -
(WEEK("Service Request"."Opened Date") - 2)
/* Convert Saturday to the Business Day Of the Year */
WHEN DAYOFWEEK("Service Request"."Opened Date") = 7
THEN (DAYOFYEAR("Service Request"."Opened Date") -
WEEK("Service Request"."Opened Date")) -
(WEEK("Service Request"."Opened Date") - 1)
/* Convert Mon-Fri to the Business Day Of the Year */
ELSE (DAYOFYEAR("Service Request"."Opened Date") -
WEEK("Service Request"."Opened Date")) +
(2 - WEEK("Service Request"."Opened Date"))
END)
+
/* Adjust for Year Change */
(365 * (YEAR("Service Request"."Closed Date and Time") -
YEAR("Service Request"."Opened Date")))
Any ideea or hint would be highly appreciated.
Thank you.
Regards,
Dorin
Edited by: user805960 on 06.01.2010 07:07Hi,
i used this formula to find out the days it calculates between 31/12/2009 and 01/01/2010, the result it gave was 106 days.
So i subtracted 106 from 365 days (365-106=259)in the formula, the formula is now giving the correct values.
I think we have to add the total working days and not the no.of days in a year.
Please can you all reconfirm the results.
Thanks
Neena
Edited by: NNK on Jan 11, 2010 3:16 PM -
Function, procedure to find next 10 business days
Hi,
Is there any function procedure to find next 10 business days in oracle.
Also i have a local holiday table which are non-working days.
Thanks.user7987260 wrote:
Hi,
Is there any function procedure to find next 10 business days in oracle.
Also i have a local holiday table which are non-working days.
Thanks.Welcome to OTN!
This forum is for PL/SQL Developer questions. SQL and PL/SQL questions have their own forum that you can find under the Oracle Database heading. You should get a better answer if you ask your question there -
Function, procedure to find next "x" business days
Hi,
Is there any function procedure to find next 10 business days in oracle.
Also i have a local holiday table which are non-working days.
Thanks.Hi,
Ramin showed how to get the next 10 days.
If you want to exclude holidays and weekends, and get only the 10th day, then you can do something like this:
WITH next_hundred_days AS
SELECT TRUNC (SYSDATE) + LEVEL AS bnsdate
FROM dual
CONNECT BY LEVEL <= 100
, work_days AS
SELECT n.bnsdate
, ROW_NUMBER () OVER (ORDER BY bnsdate) AS day_num
FROM next_hundred_days n
LEFT OUTER JOIN holidays h ON h.dt = n.bnsdate
WHERE TO_CHAR ( bnsdate
, 'Dy'
, 'NLS_DATE_LANGUAGE=ENGLISH'
) NOT IN ('SAT', 'SUN')
AND h.dt IS NULL
SELECT bnsdate
FROM work_days
WHERE day_num = 10
;This assumes that there will be at least 10 work days in the next 100 days. Where I work, that's a very safe assumption.
I hope this answers your question.
If not, post CREATE TABLE and INSERT statements for a few rows from your holiday table.
Post a few (starting date, number of days) pairs, and the results that you would want from each pair, given the data you posted in the holiday table.
See the forum FAQ {message:id=9360002} -
IS THERE A FUNCTION TO RETURN THE NUMBER OF MONTHS OR DAYS?
I know that you can do a months between function between 2 dates divided by 12 and get years but is there a function that can return the number of months between 2 dates or the number of days between 2 dates in a select statement for a report? These 2 dates are entered in an Oracle forms.
I have 2 dates.
BEG_SVC_DT 30-JUL-1995 DATE FORMAT
END_SVC_DT 981007 VARCHAR2 FORMAT Positions 5 and 6 are the days.
I must subtract BEG_SVC_DT from END_SVC_DT.
In PLSQL I add 31 to 07 and get 38. I subtract 30 from 38 and get 8.
or I have 2 dates
BEG_SVC_DT 10-JAN-2003 DATE FORMAT
END_SVC_DT 050924 VARCHAR2 FORMAT Positions 5 and 6 are the days.
I must subtract BEG_SVC_DT from END_SVC_DT.
In PLSQL I subtract 10 from 24 and get 14.
In both scenarios the end_dt field must be VARCHAR2 because the user has to enter the word 'PRESENT' . Is there a function in SQL that would compute the
number of days between 2 dates?
Is there a function to get the number of months between 2 dates?
I have 2 dates.
BEG_SVC_DT 12-JUL-2004 DATE FORMAT
END_SVC_DT 050807 VARCHAR2 FORMAT Positions 3 and 4 are months.
I must subtract BEG_SVC_DT from END_SVC_DT
JUL is the 7th month.
In PLSQL, I subtract 07 from 08 and get 01
Or I have 2 dates
BEG_SVC_DT 13-NOV-2004 DATE FORMAT
END_SVC_DT 050429 VARCHAR2 FORMAT Positions 3 and 4 are months.
I must subtract BEG_SVC_DT from END_SVC_DT.
NOV is the eleventh month. 04 is less than 11.
In PLSQL I have to add 12 to 04 and subtract 11 from 16 to get 05.
In both scenarios, the end_dt field must be VARCHAR2 because the user has to enter the word 'PRESENT'. In SQL, is there a function to compute the number of months between 2 dates?
I am doing my calculations this way because this is the way that the user has been doing them when they created the report manually.
The database that I am using is Oracle 9.2.0.6
Report Writer Report Builder 6.0.8.22.0
Forms 6.0.8.22.1In your example:
BEG_SVC_DT 30-JUL-1995 DATE FORMAT
END_SVC_DT 981007 VARCHAR2 FORMAT Positions 5 and 6 are the days.
I must subtract BEG_SVC_DT from END_SVC_DT.
In PLSQL I add 31 to 07 and get 38. I subtract 30 from 38 and get 8.
Where is the "31" depending on, on year and month of BEG_SVC_DT or END_SVC_DT?
What would be the answer for the following example
BEG_SVC_DT 25-FEB-1995 DATE FORMAT
END_SVC_DT 980407 VARCHAR2 FORMAT
Do I add 28 (=number of days in FEB-1995),
or 30 (=number of days in APR-1998),
or 31 (= max number of days in any month?) -
Is there a way to use business objects in the program or function module?
Hi Experts,
Is there a way to use business objects in the program or function module.
Thanks in Advance.
Naval bhattHi Naval,
Ofcourse you can use business objects in your programms/ methods.
You can use function modules or macros (available from include <cntn01>) for using business objects in your application.
refere following two links for startup information
http://www.sap-img.com/abap/reading-attribute-of-a-business-object-in-abap.htm
http://www.jt77.com/business-warehouse/work-flow-12619.html
Regards,
Abhijit -
How to: Schedule a job to run on the first business day of the month
In Oracle 10.2.0.3, is there a way to schedule a repeating job to run on the first business day of the month? For example, if the first of the month falls on a weekend (such as Saturday, 11/01/2008), I would like the job to run automatically on Monday (for example, 11/03/2008) instead.
set serveroutput on
begin
print_dates('FREQ=MONTHLY;BYDAY=MON,TUE,WED,THU,FRI;BYSETPOS=1;',
to_timestamp_tz('01-JAN-2008 12:00:00','DD-MON-YYYY HH24:MI:SS'), 12);
end;
Gives:
TUE 01-JAN-2008 (001-01) 12:00:00 -07:00 -07:00
FRI 01-FEB-2008 (032-05) 12:00:00 -07:00 -07:00
MON 03-MAR-2008 (063-10) 12:00:00 -07:00 -07:00
TUE 01-APR-2008 (092-14) 12:00:00 -07:00 -07:00
THU 01-MAY-2008 (122-18) 12:00:00 -07:00 -07:00
MON 02-JUN-2008 (154-23) 12:00:00 -07:00 -07:00
TUE 01-JUL-2008 (183-27) 12:00:00 -07:00 -07:00
FRI 01-AUG-2008 (214-31) 12:00:00 -07:00 -07:00
MON 01-SEP-2008 (245-36) 12:00:00 -07:00 -07:00
WED 01-OCT-2008 (275-40) 12:00:00 -07:00 -07:00
MON 03-NOV-2008 (308-45) 12:00:00 -07:00 -07:00
MON 01-DEC-2008 (336-49) 12:00:00 -07:00 -07:00
and the print_dates function is (10.2):
create or replace procedure print_dates
cal_string in varchar2,
start_date in timestamp with time zone,
nr_of_dates in pls_integer
is
date_after timestamp with time zone := start_date - interval '1' second;
next_execution_date timestamp with time zone;
begin
dbms_output.put_line(' -->');
for i in 1 .. nr_of_dates
loop
dbms_scheduler.evaluate_calendar_string
(cal_string, start_date, date_after, next_execution_date);
dbms_output.put_line(to_char(next_execution_date,
'DY DD-MON-YYYY (DDD-IW) HH24:MI:SS TZD TZH TZR'));
date_after := next_execution_date;
end loop;
end;
[\pre] -
Calculation of due date based on Business Days for FICA documents
Hi All,
I am working on project where SD - FICA integration is in picture. We post some charges through SD and FICA document gets posted on relevant Contract Account.
Normally we create Sales Order using transaction VA01 and then we do Billing for this Sales Order through VF01. After billng is done, FICA document automatically gets generated.
We have following requirement to be fulfilled.
For the SD bills posted as above, I want to calculate due date of these bills based on Business Days for FICA document generated (SAP Standard calculate due date based on Calander days). We can use factory calander for calculating business days in relevant function module.
I have checked in the system and it seems that event 1330 ( FM - ISU_DUE_DATE_DETERMINE) is not working in this scenario. Is there any other FM which I can use?
Can anyone help me on this?
Regards,
PradeepHello Praeva ,
The event 1330 has a sample FM FKK_SAMPLE_1330. It doesnt even have a Standard Function Module.
You need to create a Installation-Specific FM and put your code to determine the Due Date based on the logic.
Rgds
Ram Kumar. -
Calculating Business Days in a Date Range
I have two questions:
1. Does anyone know a better formula for calculating business days in totals?
I am currently using the formula in https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/701a52c3-6b1e-2b10-21b3-a6e101be1a0f
I tailored to my needs. However, there are still a lot of manual maintenance every year.
2. I have many reports that need the formula. It is very consuming to update the formula in each report. Does anyone know a better way to do it?
I use Crystal XI. 11.0.0.895. We do have a Crystal Enterprise server hosted in another department.Not sure if this is any simpler but you could save this as a custom function, that way you will have to modify it once a year for the holidays.
numbervar days;
datevar date1 := minimum({?My Parameter});
datevar date2 := maximum({?My Parameter});
days := DateDiff ("d", date1, date2) -
DateDiff ("ww", date1, date2, crSaturday) -
DateDiff ("ww", date1, date2, crSunday); // this will give you the number of business days
// (excluding Saturdays and Sundays) for a given date range.
// then, for each holiday, you can enter lines like this
if date(2008,01,01) in {?My Parameter} then days := days - 1;
// The final tally of DAYS should give you the total business days in a date range.
totext(days,0);
where {?My Parameter} is the date range. -
Previous business day in sql query
Hi,
Is there a way to calculate the previous business day on teh sql query without using a function call.
Typically in the query where clause as seen below:
eg)
select * from sales where sale_date ='+previous_buss_day+'
If so please let me know....Thnx in advanc.that depends if your organization has a defined set of business days that will includes non-working days (holidays, etc.). if there is you need to have a lookup table that has a listing of all available normal business day and non-working days. then match it up with your transaction table. otherwise you can use the current system date less 1 days.
e.g.
select * from sales where sale_date = trunc(sysdate-1)
Maybe you are looking for
-
Managing iTunes match on multiple computers
I have iTune match turned on across two macbooks, an iPhone and iPad. Both music libraries on the two macbooks are identical with all of the songs physically downloaded to both hard drives. I am in the process of turning one macbook into a strictly w
-
Error message when burning a disc of photos
I was trying to burn a disc of a large number of photos - around 400, and I got this error message: "The burn to the HL-DT-ST DVDRW GS23N drive failed. The disc drive didn't respond properly and can't recover or retry." I did a sample burn of about
-
When iPhone is connected to PC, it shows in itunes but Autoplay does not open for me to copy photos. I tried the Control Panel, changing Autoplay settings but no use. I use a Windows Vista. Please help! All my little ones' pictures are on my iPhone 3
-
EHP1 SAPehpi failing at phase REV_PRPEXTRACT/RESET_PREPARE
Hi Experts, I'm attempting to install EHP1, SP7 on to our Netweaver BI system. I've got as far as starting the SAPehpi installer and have hit a problem at an early stage: REV_PRPEXTRACT/RESET_PREPARE The error message displayed on the installer scree
-
Exist OSDComputerName then Join Domain, if not join workgroup
I add OSDComputerName into Unknown Computer as below Right Click "Unknown Computers" and choose Properties. Open Collection Variables tab. Click on the yellow star to add a new variable. Type OSDComputerName http://www.gerryhampsoncm.blogspot.ie/20