Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine the difference between two DateTimes, only counting opening hours

Tags:

c#

datetime

For our support software in C#, I need to determine the time span between two DateTimes, but I only want opening hours counted (i.e. weekdays from 09:00 to 17:00).

So, for instance, if the first DateTime is 15/02/2011 16:00 and the second is 16/02/2011 10:00, the method shall return 2 hours.

Any help is greatly appreciated!

like image 767
Anders Avatar asked Feb 15 '11 15:02

Anders


People also ask

How do I find the difference between two Datetimes in Python?

timedelta() method. To find the difference between two dates in Python, one can use the timedelta class which is present in the datetime library. The timedelta class stores the difference between two datetime objects.

How can I get the difference between two Datetimes in C#?

The difference between two dates can be calculated in C# by using the substraction operator - or the DateTime. Subtract() method. The following example demonstrates getting the time interval between two dates using the - operator.

How do you find the difference between two dates in hours and minutes?

get time() -startDate. gettime())/1000; Log. d("App","difference in hour is"+diff/1000/60/60); Mins = diff/1000/60; Seconds = diff/1000; Using this code I'm getting hours as a correct value.


4 Answers

DateTime start = DateTime.Parse("15/02/2011 16:00");
DateTime end = DateTime.Parse("16/02/2011 10:00");

int count = 0;

for (var i = start; i < end; i = i.AddHours(1))
{
    if (i.DayOfWeek != DayOfWeek.Saturday && i.DayOfWeek != DayOfWeek.Sunday)
    {
        if (i.TimeOfDay.Hours >= 9 && i.TimeOfDay.Hours < 17)
        {
            count++;
        }
    }
}

Console.WriteLine(count);
like image 194
Oleg Rudckivsky Avatar answered Oct 25 '22 18:10

Oleg Rudckivsky


Here we go, spent a while on this one for you. :)

Has room to detect holidays (if you write a function that checks whether a DateTime is a holiday), detects weekends in between the dates, and handles more than just hours.

The algorithm is to compute how much time is from the start til close of business and from the start of business to the end time, and then compute how many days are in between. Falling on the same date is a special case.

Caveat: I did some basic testing but probably didn't get all corner cases.

    public static TimeSpan BusinessTimeDelta(DateTime start, DateTime stop)
    {
        if (start == stop)
            return TimeSpan.Zero;

        if (start > stop)
        {
            DateTime temp = start;
            start = stop;
            stop = temp;
        }

        // First we are going to truncate these DateTimes so that they are within the business day.

        // How much time from the beginning til the end of the day?
        DateTime startFloor = StartOfBusiness(start);
        DateTime startCeil = CloseOfBusiness(start);
        if (start < startFloor) start = startFloor;
        if (start > startCeil) start = startCeil;

        TimeSpan firstDayTime = startCeil - start;
        bool workday = true; // Saves doublechecking later
        if (!IsWorkday(start))
        {
            workday = false;
            firstDayTime = TimeSpan.Zero;
        }

        // How much time from the start of the last day til the end?
        DateTime stopFloor = StartOfBusiness(stop);
        DateTime stopCeil = CloseOfBusiness(stop);
        if (stop < stopFloor) stop = stopFloor;
        if (stop > stopCeil) stop = stopCeil;

        TimeSpan lastDayTime = stop - stopFloor;
        if (!IsWorkday(stop))
            lastDayTime = TimeSpan.Zero;

        // At this point all dates are snipped to within business hours.

        if (start.Date == stop.Date)
        {
            if (!workday) // Precomputed value from earlier
                return TimeSpan.Zero;

            return stop - start;
        }

        // At this point we know they occur on different dates, so we can use
        // the offset from SOB and COB.

        TimeSpan timeInBetween = TimeSpan.Zero;
        TimeSpan hoursInAWorkday = (startCeil - startFloor);

        // I tried cool math stuff instead of a for-loop, but that leaves no clean way to count holidays.
        for (DateTime itr = startFloor.AddDays(1); itr < stopFloor; itr = itr.AddDays(1))
        {
            if (!IsWorkday(itr))
                continue;

            // Otherwise, it's a workday!
            timeInBetween += hoursInAWorkday;
        }

        return firstDayTime + lastDayTime + timeInBetween;
    }

    public static bool IsWorkday(DateTime date)
    {
        // Weekend
        if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
            return false;

        // Could add holiday logic here.

        return true;
    }

    public static DateTime StartOfBusiness(DateTime date)
    {
        return new DateTime(date.Year, date.Month, date.Day, 9, 0, 0);
    }

    public static DateTime CloseOfBusiness(DateTime date)
    {
        return new DateTime(date.Year, date.Month, date.Day, 17, 0, 0);
    }
like image 29
Sapph Avatar answered Oct 25 '22 17:10

Sapph


Use LINQ:

DateTime dt1 = new DateTime(2010, 10, 1, 16, 0, 0);
DateTime dt2 = new DateTime(2010, 10, 2, 10, 0, 0);

int hours = Enumerable.Range(1, (dt2 - dt1).Hours)
                 .Where(h =>
                    {
                        var dt = dt1.AddHours(h);
                        return dt.DayOfWeek != DayOfWeek.Saturday
                               && dt.DayOfWeek != DayOfWeek.Sunday
                               && dt.Hour >= 9 && dt.Hour <= 17;
                    }).Count();

Here I assume all Minute and Second are zero. Otherwise (dt2 - dt1).Hours will give unexpected value.

like image 5
Cheng Chen Avatar answered Oct 25 '22 19:10

Cheng Chen


You can try this Algorithm:

  1. Calculate total No Of Hours (lets say TotalHours = (Date2 - Date1).TotalHours)
  2. Calculate No of Holidays (holidays, includes weekends & other holidays)
  3. Calcualte No of Working days ( (Date2-Date1).TotalDays - Holidays) as int

Working Hours = TotalHours - 24*holidays - 16*WorkingDays

(16 = Time difference between 5pm and 9am the next day)

like image 1
Viv Avatar answered Oct 25 '22 19:10

Viv