Calculate Day of Week and Business Hours Between Date-Times in Apex

Quick guide: get weekday names from a Date and compute business-hours-only duration between two DateTime values using Apex. Includes code samples and explanation for weekday/weekend schedules.

Introduction

When tracking Lead handling time, Case SLAs, or Task worklogs in Salesforce, you often need two related capabilities: determine the day of the week for a Date field, and compute the actual time spent between two DateTime values while excluding non-business hours. This post shows concise Apex implementations and explains how they work.

Determine day of week from a Date in Apex

Salesforce Date doesn’t expose a built-in “day name” method, but you can derive it using toStartOfWeek() and daysBetween() to map a date to Sunday-Saturday.

public static String getDayOfWeek(Date inputDate) {
    // Get the start of the week (Sunday) for the given date
    Date startOfWeek = inputDate.toStartOfWeek();
   
    // Calculate the difference in days between the input date and the start of the week
    Integer dayDifference = inputDate.daysBetween(startOfWeek);
   
    // Determine the day of the week based on the difference
    String dayOfWeek;
    switch on dayDifference {
        when 0 { dayOfWeek = 'Sunday'; }
        when 1 { dayOfWeek = 'Monday'; }
        when 2 { dayOfWeek = 'Tuesday'; }
        when 3 { dayOfWeek = 'Wednesday'; }
        when 4 { dayOfWeek = 'Thursday'; }
        when 5 { dayOfWeek = 'Friday'; }
        when 6 { dayOfWeek = 'Saturday'; }
        when else { dayOfWeek = 'Invalid'; }
    }
   
    return dayOfWeek;
}

How it works

  • toStartOfWeek() returns the Sunday of that week.
  • daysBetween() gives the day offset (0..6) that maps to a weekday name.

Calculate actual time spent between two DateTimes excluding off-hours

To calculate business-only duration, iterate each date in the range and clamp the day’s interval to the configured business start/end times. The example below assumes:

  • Weekdays (Mon–Fri): 8:00 AM – 8:00 PM
  • Weekends (Sat–Sun): 8:00 AM – 4:30 PM
public static Decimal calculateBusinessHours(Datetime startDateTime, Datetime endDateTime) {
    if (startDateTime == null || endDateTime == null) {
        return 0;
    }       
   
    Date startDate = startDateTime.date();
    Date endDate = endDateTime.date();    
    Decimal totalHours = 0;
   
    // Loop through each date from start to end
    for (Date currentDate = startDate; currentDate <= endDate; currentDate = currentDate.addDays(1)) {
        // Determine the day of the week (0 = Sunday, 6 = Saturday)
        Date startOfWeek = currentDate.toStartOfWeek();
        Integer dayDifference = currentDate.daysBetween(startOfWeek);
       
        // Define business hours start time (8 AM)
        Datetime businessStart = Datetime.newInstance(currentDate, Time.newInstance(8, 0, 0, 0));
        Datetime businessEnd;
       
        // Set business end time based on weekday/weekend
        if (dayDifference == 6 || dayDifference == 0) { // Weekend (Saturday = 6, Sunday = 0)
            businessEnd = Datetime.newInstance(currentDate, Time.newInstance(16, 30, 0, 0)); // 4:30 PM
        } else {
            businessEnd = Datetime.newInstance(currentDate, Time.newInstance(20, 0, 0, 0)); // 8:00 PM
        }
       
        // Determine effective start and end time for this date
        Datetime effectiveStart = (startDateTime > businessStart) ? startDateTime : businessStart;
        Datetime effectiveEnd = (endDateTime < businessEnd) ? endDateTime : businessEnd;
       
        // If within business hours, calculate time difference
        if (effectiveStart < effectiveEnd) {
            totalHours += (effectiveEnd.getTime() - effectiveStart.getTime()) / (1000 * 60 * 60); // Convert ms to hours
        }
    }
   
    return totalHours;
}

How it works

  • Iterates every calendar date from start to end.
  • Determines day type using daysBetween() against the week start.
  • Creates businessStart and businessEnd Datetimes per day.
  • Clamps the actual start/end to the business window, then sums elapsed hours.

Example usage

Datetime startDT = Datetime.newInstance(2025, 3, 18, 10, 0, 0); // March 18, 2025 - 10:00 AM
Datetime endDT = Datetime.newInstance(2025, 3, 19, 15, 30, 0);   // March 19, 2025 - 3:30 PM
System.debug(calculateBusinessHours(startDT, endDT)); // Expected: 17.5 (if both are weekdays)

Best practices & considerations

  • Timezone: Datetime.newInstance uses the org timezone; ensure your calculations respect user or org timezone as needed.
  • Public holidays: extend the loop to skip configured holidays (use Custom Metadata or a Holiday object).
  • Performance: for very large ranges consider batching or short-circuiting when dates are entirely outside business hours.
  • Testing: write unit tests covering same-day, multi-day, weekend-only, and boundary conditions (start before business hours, end after business hours).

Conclusion

Using simple Date and Datetime utilities in Apex you can reliably map a Date to its weekday name and compute business-hours-only durations between two DateTimes. This is especially useful for SLA measurements, case/ticket aging, and accurate worklog reporting.

Why this matters: Salesforce admins and developers gain accurate, auditable timing for processes such as SLA enforcement and reporting — helping business teams make decisions based on true working-time metrics.