Skip to main content
Inspiring
April 24, 2019
Question

Calculate the number of hours between two dates and exclude Saturday and Sunday using DateDiff?

  • April 24, 2019
  • 4 replies
  • 643 views

Hi,

I have to calculate the number of hours between two dates and exclude Saturday and Sunday. The first 24 hours (Monday, Tuesday, Wednesday, Thursday or Friday) of the calculation is a grace period. After the first 24 hours, is the calculation for over of compliance.

For example:

Notified: 2019-02-03 08:58:00.0000000  (is a Sunday)

Entered: 2019-02-05 08:38:00.0000000  (is a Tuesday)

Since 2/3/2019 is a Sunday, the time shouldn’t start counting until 2/4 at 00:01. There’s then the 24 hour grace period, so it becomes out of compliance on 2/5/2019 at 00:02. It should only be 9 hours out of compliance.

The query in The SQL runs fine for Monday - Friday. It's not excluding Saturday and Sunday.

Below is the SQL code for the number of hours:

DATEDIFF(hour,CAST(tbla.NOTIFYDATE AS DATETIME) +

  CAST(Coalesce(tbla.NOTIFYTIME,'23:59:00') AS DATETIME),

  CAST(tbla.ENTRYDATE AS DATETIME) +

  CAST(Coalesce(tbla.ENTRYTIME,'23:59:00') AS DATETIME)) - ( (DATEDIFF(wk, tbla.NOTIFYDATE,

  tbla.ENTRYDATE) * 2)-(CASE WHEN DATENAME(dw, tbla.NOTIFYDATE) = 'Sunday' THEN 1 ELSE 0 END)-

  (CASE WHEN DATENAME(dw, tbla.ENTRYDATE) = 'Saturday' THEN 1 ELSE 0 END)) * 24 - 24 AS timelyOOCHours

Is there a way to perform the calculation in Cold Fusion 2016?

Can DateDiff do this? If so, is there an example?

    This topic has been closed for replies.

    4 replies

    BKBK
    Community Expert
    Community Expert
    April 30, 2019

    Hi userCold9,

    How are you getting on? In case you're having difficulty with the ColdFusion code, here is a suggestion:

    Compliance.cfc

    <cfscript>

    component {

    Date function getGracePeriodStartDate(Date notifyDate, Date entryDate) {

         var graceStartDate=arguments.notifyDate;

         if (dayOfWeek(arguments.notifyDate) eq 7) {

              // then notifyDate is a Saturday; grace period starts Sunday midnight

              var nextMonday=dateAdd("d",2,arguments.notifyDate);

              graceStartDate=createdatetime(year(nextMonday),month(nextMonday),day(nextMonday),0,1,0);

         }

         if (dayOfWeek(arguments.notifyDate) eq 1) {

              // then notifyDate is a Sunday; grace period starts at midnight

              var nextMonday=dateAdd("d",1,arguments.notifyDate);

              graceStartDate=createdatetime(year(nextMonday),month(nextMonday),day(nextMonday),0,1,0);

         }

         if (dateAdd("h",24,graceStartDate) gt arguments.entryDate) {

              throw(type="InvalidInput", message="The 24-hour grace period cannot exceed the entry date");

         }

         return graceStartDate;

    }

    Date function getGracePeriodEndDate(Date notifyDate, Date entryDate) {

         var graceStartDate=getGracePeriodStartDate(arguments.notifyDate, arguments.entryDate);

         return dateAdd("h",24,graceStartDate);

    }

    Date function getCompliancePeriodEndDate(Date notifyDate, Date entryDate) {

         var compliancePeriodEndDate=arguments.entryDate;

         if (dayOfWeek(arguments.entryDate) eq 7) {

              // then entryDate is a Saturday; compliance period ended the day before (Friday), at midnight

              var lastFriday=dateAdd("d",-1,arguments.entryDate);

              compliancePeriodEndDate=createdatetime(year(lastFriday),month(lastFriday),day(lastFriday),23,59,0);

         }

         if (dayOfWeek(arguments.entryDate) eq 1) {

              // then entryDate is a Sunday; compliance period ended two days before (Friday), at midnight

              var lastFriday=dateAdd("d",-2,arguments.entryDate);

              compliancePeriodEndDate=createdatetime(year(lastFriday),month(lastFriday),day(lastFriday),23,59,0);

         }

         if (compliancePeriodEndDate lt arguments.notifyDate) {

              throw(type="InvalidInput", message="The compliance end date cannot be before the notify date");

         }

         return compliancePeriodEndDate;

    }

    numeric function getComplianceHours(Date notifyDate, Date entryDate) {

         var startDate=arguments.notifyDate;

         var endDate=arguments.entryDate;

         var numberOfWeekendHours=0;

         var graceStartDate=getGracePeriodStartDate(startDate, endDate);

         var gracePeriodEndDate=getGracePeriodEndDate(startDate, endDate);

         var compliancePeriodEndDate=getCompliancePeriodEndDate(startDate, endDate);

         var numberOfDaysInCompliancePeriod=dateDiff("d",gracePeriodEndDate,compliancePeriodEndDate);

         for (var n=1; n lte numberOfDaysInCompliancePeriod; n++) {

              // sum up number of Saturday and Sunday hours

              if (dayOfWeek(dateAdd("d",n,gracePeriodEndDate)) eq 7 or dayOfWeek(dateAdd("d",n,gracePeriodEndDate)) eq 1) {

                   numberOfWeekendHours=numberOfWeekendHours+24;

              }

         }

         var totalMinutesInCompliancePeriod=dateDiff("n",gracePeriodEndDate,compliancePeriodEndDate);

         // Calculate compliance hours, rounding up

         var complianceHours=ceiling(totalMinutesInCompliancePeriod/60)-numberOfWeekendHours;

         return complianceHours;

    }

    }

    </cfscript>

    testpage.cfm

    <cfscript>

    dt1=createdatetime(2019,02,3,8,58,0);

    dt2=createdatetime(2019,02,5,8,38,0);

    complianceObject=createobject("component","Compliance");

    writeoutput("Grace period start date: " & complianceObject.getGracePeriodStartDate(dt1,dt2) & "<br>");

    writeoutput("Grace period end date: " & complianceObject.getGracePeriodEndDate(dt1,dt2) & "<br>");

    writeoutput("Compliance period end date: " & complianceObject.getCompliancePeriodEndDate(dt1,dt2) & "<br>");

    writeoutput("Compliance hours: " & complianceObject.getComplianceHours(dt1,dt2) & "<br>");

    </cfscript>

    BKBK
    Community Expert
    Community Expert
    April 27, 2019

    It would be helpful if you first sketched the requirements. Something like this:

    1. Find the total number of hours from the start datetime (notifyDate) to the end datetime (entrydate). Call this H.

       2. On the first day, it might happen that the start of counting is not at the start of the day. See diagram below.

            So you have to count the number of hours from the start time to midnight. Call this number X. If the day is a Saturday or Sunday, you will have to subtract X from H.

    3.  On the last day, it might happen that the end of counting is not at the end of the day. So you have to count the number of hours from midnight to the end time. Call this number Y. If the day is a Saturday or Sunday, you will have to subtract this number from H.

    4.  For any whole Saturday or Sunday that falls in between the start (notifyDate) and end (entrydate), you have to subtract 24 hours from H.

    5.  Grace period

    If counting starts on a Saturday then, using the above notation, the grace period will start X+24 hours after the start time. If counting starts on a Sunday then the grace period will start X hours after the start time. If counting starts on a day between Monday and Friday the grace period will start immediately at the start.

    6.  Compliance

    The end time of the grace period is 24 hours after the start time of the grace period. If it falls after the end time of counting, then the total count will be 0 hours. That is, the compliance will be 0 hours. If the end time of the grace period falls before the end time of counting, then you have to subtract 24 hours from the remaining total number of hours. The resulting number of hours is the compliance.

    The compliance start date or end date cannot be a Saturday or Sunday. If the start date is at the weekend, then the date is adjusted to 00:01:00 the following Monday. If the end date is at the weekend, then the date is adjusted to 23:59:00 the previous Friday.

    BKBK
    Community Expert
    Community Expert
    April 25, 2019

    I agree with WolfShade​. You should write a user-defined function to perform the task. You could then bring it here for discussion and feedback.

    WolfShade
    Legend
    April 26, 2019

    AND!!!  If it rocks, you could share it with others who might need to do the same thing. 

    V/r,

    ^ _ ^

    WolfShade
    Legend
    April 24, 2019

    AFAIK, there is not a native CF way to do what you seek.  I believe you'll have to custom-build a UDF/CFC to get the value you are looking to get.

    V/r,

    ^ _ ^