[SalesForce] Apex: Calculate hour ranges

Given a start time (datetime) and a finish time (datetime) how can I easily calculate the number of hours that fell between 6:00am – 12:00pm (day hours) and 12:00 – 6:00am (night hours). They would be rounded up, so if there is any time at all in a given hour, that constitutes a complete hour.

So for example if your start time is 22:00 (military time here) and finish time is at 01:00 it would yield 2 day hours, 1 night hour. If instead the finish time was 1:10, that would yield 2 day hours and 2 night hours.

I'm pretty sure I could find a brute force solution to this, but I'm pretty sure there is an elegant type of solution that is escaping me.

Thanks!

Best Answer

So you could do something like this:

Decimal MilliSeconds = EndTime.getTime() -StartTime.getTime() ; Decimal HourConvert = Millisecds / (1000.0*60.0*60.0)

When you use .getTime() it returns the number of Milliseconds since 1970.

Subtract the two to get the total milliseconds between the two dateTimes.

Then you take the milliseconds to calculate up to get your hours. 1000 (Seconds), * 60 (Minutes) * 60 (hours)

Edit Based On actually reading the questions correctly*

So the above gives you total time.

To get the Night/Day hours you need to break it up.

  1. Figure out Hours of Day and Night for the Start Time
  2. Figure out Hours of Day and Night for End Time
  3. Figure out Total WHOLE DAYS between Start and End time. Then you can split that number to get your Day/Night Hours.

So that's the basis of this. Below is a class (Quick and Dirty) to do just what I listed above. What's not included is the Rounding up of the values.

public class TimeCalc {

Public static string TimeCalcHr(DateTime InputStart, Datetime InputEnd){
    Datetime DayStart = datetime.newinstance(InputStart.Year(),InputStart.Month(), Inputstart.Day(),6,0,0);
    Datetime DayEnd = datetime.newinstance(InputStart.Year(),InputStart.Month(), Inputstart.Day(),12,0,0);

    Decimal StartingDaysMS = InputStart.getTime() - DayStart.getTime();
    Decimal StartingNightsMS = InputStart.getTime() - DayEnd.getTime();

    if(StartingDaysMS <0){
       StartingDaysMS =0;
    }
    if(StartingNightsMS <0){
        StartingNIghtsMS = 0;
    }
    //Repeat for End Date
    DayStart = datetime.newinstance(InputEnd.Year(),InputEnd.Month(), InputEnd.Day(),6,0,0);
    DayEnd = datetime.newinstance(InputEnd.Year(),InputEnd.Month(), InputEnd.Day(),12,0,0);

    Decimal EndingDaysMS = InputEnd.getTime() - DayStart.getTime();
    Decimal EndingNightsMS = InputEnd.getTime() - DayEnd.getTime();
    if(EndingDaysMS <0){
       EndingDaysMS =0;
    }
    if(EndingNightsMS <0){
        EndingNIghtsMS = 0;
    }
    //Figure out hours between
    decimal NightMSInADay = DayEnd.GetTime() - DayStart.getTime();
    Decimal DayMSInADay = DayStart.Adddays(1).getTime()-DayEnd.GetTime();
    //figure out number of days between times
    integer NumOfDays = InputStart.Date().daysBetween(InputEnd.Date()); 
    Decimal NumMSBetweenDays = NumOfDays * DayMSInADay;
    Decimal NumMSBetweenNights = NumOfDays * NightMSInADay;

    //Add Everything Togeter
    Decimal TotalNightMS = NumMSBetweenNights +  EndingNIghtsMS + StartingNightsMS;
    Decimal TotalDaysMS = NumMSBetweenDays+ EndingDaysMS+ StartingDaysMS;
    Decimal TotalNightHrs = TotalNightMs / (1000*60*60);
    Decimal TotalDayHrs = TotalDaysMS /  (1000*60*60);

    String Output = 'Night Hours: ' + string.Valueof(TotalNighthrs) + ' Day Hours: ' + string.valueof(TotalDayHrs);
    return Output;
}

}

Related Topic