Skip to main content
Solved

SQL: Calculate Workday Hours Between 2 Dates


Forum|alt.badge.img+10
  • Sidekick (Customer)
  • 119 replies

We have need to calculate the number of hours between 2 dates, minus weekends. We’re using the OrderHistory tab’s rows.

I have it working for just the number of days between 2 dates, and then did it for the number of hours (I simply removed TRUNC() around the 2 dates).

But that included weekends and now the team wants just business days. I was able find a solution for 2 dates, but it doesn’t include the hours.

I’m thinking the solution is to add HH24:MM:SS to the to_date() function but am receiving errors.

How do I format to_date() to include hours in the calculation?

 

1SELECT
2Site,
3OrderNo,
4status,
5lag_status,
6dt,
7lag_dt,
8TO_CHAR(to_date(dt,'YYYY/MM/DD'),'DY','nls_date_language=english') as DT_DAY,
9TO_CHAR(to_date(lag_dt,'YYYY/MM/DD'),'DY','nls_date_language=english') as LAG_DT_DAY,
10
11 (to_date(dt,'YYYY/MM/DD') - to_date(lag_dt,'YYYY/MM/DD') ) -
12 ((((TRUNC(to_date(dt,'YYYY/MM/DD'),'D'))-(TRUNC(to_date(lag_dt,'YYYY/MM/DD'),'D')))/7)*2) -
13
14 (CASE WHEN TO_CHAR(to_date(lag_dt,'YYYY/MM/DD'),'DY','nls_date_language=english')='SUN' THEN 1 ELSE 0 END) -
15
16 (CASE WHEN TO_CHAR(to_date(dt,'YYYY/MM/DD'),'DY','nls_date_language=english')='SAT' THEN 1 ELSE 0 END) as Bus_Days_Diff
17
18from ifsinfo.RW_OUT_ORDERS_HIST_ONE_LAG

 

Best answer by durette

Your should have a calendar set up under Site from which you can exclude non-working days.

 

Here’s how to use the distribution calendar to achieve this. (On our system, this example shows that 5 working days separate last Wednesday and this Wednesday.)

1SELECT work_time_calendar_api.get_work_days_between(
2 calendar_id_ => site_api.get_dist_calendar_id('YOUR SITE'),
3 from_date_ => TO_DATE('2021-01-06', 'YYYY-MM-DD'),
4 to_date_ => TO_DATE('2021-01-13', 'YYYY-MM-DD'))
5 FROM DUAL;

 

View original
Did this topic help you find an answer to your question?
This topic has been closed for replies.

14 replies

durette
Superhero (Customer)
Forum|alt.badge.img+19
  • Superhero (Customer)
  • 541 replies
  • Answer
  • January 9, 2021

Your should have a calendar set up under Site from which you can exclude non-working days.

 

Here’s how to use the distribution calendar to achieve this. (On our system, this example shows that 5 working days separate last Wednesday and this Wednesday.)

1SELECT work_time_calendar_api.get_work_days_between(
2 calendar_id_ => site_api.get_dist_calendar_id('YOUR SITE'),
3 from_date_ => TO_DATE('2021-01-06', 'YYYY-MM-DD'),
4 to_date_ => TO_DATE('2021-01-13', 'YYYY-MM-DD'))
5 FROM DUAL;

 


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 11, 2021

Kevin,

that works! Thank you very much.

 


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 11, 2021

I then tried this to also include the number of hours in addition to the number of days, however that fails.

1work_time_calendar_api.get_work_days_between(site_api.get_dist_calendar_id(site),
2 TO_DATE(lag_dt, 'YYYY-MM-DD HH:MM:SS'),TO_DATE(dt, 'YYYY-MM-DD HH:MM:SS')) as BusDays_API

 


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 11, 2021

I also get an error when I try to put that API in an ILA:

 

I tried prefacing it with SITE.

 

 


  • Superhero (Employee)
  • 1485 replies
  • January 12, 2021
DevBob wrote:

I also get an error when I try to put that API in an ILA:

 

I tried prefacing it with SITE.

 

 

You need to prefix the function calls in the IAL with &AO.. or &IAL.. (like it says in the instructions on the left side of the screen).

DevBob wrote:

I then tried this to also include the number of hours in addition to the number of days, however that fails.

1work_time_calendar_api.get_work_days_between(site_api.get_dist_calendar_id(site),
2 TO_DATE(lag_dt, 'YYYY-MM-DD HH:MM:SS'),TO_DATE(dt, 'YYYY-MM-DD HH:MM:SS')) as BusDays_API

 

You could use work_time_calendar_api.Get_Work_Minutes_Between to get the minutes between two dates in the calendar.

1SELECT work_time_calendar_api.Get_Work_Minutes_Between (
2 calendar_id_ => site_api.get_dist_calendar_id('AE010'),
3 from_time_ => TO_DATE('2021-01-06', 'YYYY-MM-DD'),
4 to_time_ => TO_DATE('2021-01-13', 'YYYY-MM-DD'))
5 FROM DUAL;
6

 


Forum|alt.badge.img+21
  • Superhero (Employee)
  • 500 replies
  • January 12, 2021

To solve the problem you have with adding HH24:MI:SS to your SQL-statements we need to know the data type of columns DT and LAG_DT in the IAL RW_OUT_ORDERS_HIST_ONE_LAG.

If it is VARCHAR2 or any other string data type we need to know the format of the data. (If data type is DATE there is no specific format.)


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 12, 2021

here’s the IAL:

1SELECT
2Site,
3 OrderNo,
4 OrderStatus,
5 Status,
6
7 TO_CHAR(StatusDate,'yyyy-mm-dd') dt,
8
9 LAG(Status) OVER(PARTITION BY OrderNo ORDER BY OrderNo, StatusDate) lag_status,
10
11 TO_CHAR(LAG(StatusDate) OVER(PARTITION BY OrderNo ORDER BY OrderNo, StatusDate),'yyyy-mm-dd') lag_dt,
12
13 StatusDate - LAG(StatusDate) OVER(PARTITION BY OrderNo ORDER BY OrderNo, StatusDate) diff
14
15FROM ifsinfo.RW_OUT_ORDERS_HIST_ONE_STS coh
16
17
18order by Site, OrderNo, Status

here’s some resulting data:

 

So are you saying in order to get HH:MM:SS we should use VARCHAR2()  instead of TO_CHAR()?


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 12, 2021

Thanks for the minutes API, that could be helpful.

The example doesn’t have HH:MM:SS included in the example so it’s not useful; we need # of hours between two full dates YYYY-MM-DD HH:MM:SS, excluding weekends.


Forum|alt.badge.img+21
  • Superhero (Employee)
  • 500 replies
  • January 12, 2021

Good information, now I see the problem.

The columns DT and LAG_DT in the IAL are already strings on format YYYY-MM-DD so they do not contain the timestamp.

The cleanest way seems to be to remove the to_char in the IAL to get the two columns as data type DATE.

1SELECT Site, OrderNo, OrderStatus, Status,
2 StatusDate dt,
3 LAG(Status) OVER(PARTITION BY OrderNo ORDER BY OrderNo, StatusDate) lag_status,
4 LAG(StatusDate) OVER(PARTITION BY OrderNo ORDER BY OrderNo, StatusDate) lag_dt,
5 StatusDate - LAG(StatusDate) OVER(PARTITION BY OrderNo ORDER BY OrderNo, StatusDate) diff
6FROM ifsinfo.RW_OUT_ORDERS_HIST_ONE_STS coh
7ORDER BY Site, OrderNo, Status

 

Then you do not need the to_date in your SQL and can send in the columns directly into “Work_Time_Calendar_API.Get_Work_Minutes_Between”.

 

1SELECT &AO.Work_Time_Calendar_API.Get_Work_Minutes_Between(&AO.Site_API.Get_Dist_Calendar_Id(site), lag_dt, dt)
2
3FROM IFSINFO.RW_OUT_ORDERS_HIST_ONE_LAG

 

Side note:

What I meant with VARCHAR2 was an example of a string data type. All columns in your IAL view has a data type and if you do a to_char on a column with data type DATE the data type will be VARCHAR2. 

Example:

 

 

 


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 12, 2021

awesome, thx!

I tried it and it works, however it looks like the minutes are low. Look at the first row. There are 17.6 days (including weekends); then 13 work days w/o weekends, yet the Hours (I took the minutes / 60) is only 111.18, when it should be around 13.6 * 24 = 326.4 hours.

What am I missing?

 


Forum|alt.badge.img+21
  • Superhero (Employee)
  • 500 replies
  • January 13, 2021

The problem is that the calendar you have as Distribution Calendar in your site does only have work time for 8 hours a day. 

You could check and see on the site which calendar you have and then go to this window to see the generated work minutes per day:

 

You must use another calendar which has 24 hours per day.


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 13, 2021

great, thx. Turns out we do have a calendar like that- named ‘5-24’. I plugged that in and now it works. Thx so much!

1ROUND(work_time_calendar_api.get_work_minutes_between('5-24',lag_dt,dt) / 60, 2) as Bus_Hrs_API

 

 

 


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 13, 2021

When I try to put the API call in the IAL I get this error. I do have it prefaced with &A)..

 

 


Forum|alt.badge.img+10
  • Author
  • Sidekick (Customer)
  • 119 replies
  • January 14, 2021

I figured it out; I need two periods, not one, after &AO.


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings