Подтвердить что ты не робот

Определите разницу между двумя DateTimes, только считая часы работы

Для нашего программного обеспечения поддержки на С# мне нужно определить временной интервал между двумя DateTimes, но мне нужно только подсчитать часы работы (например, с будних дней с 09:00 до 17:00).

Итак, например, если первое DateTime - 15/02/2011 16:00, а второе - 16/02/2011 10:00, метод должен вернуть 2 часа.

Любая помощь очень ценится!

4b9b3361

Ответ 1

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);

Ответ 2

Здесь мы идем, потратили некоторое время на это для вас.:)

Имеет место для обнаружения праздников (если вы пишете функцию, которая проверяет, является ли DateTime праздником), определяет выходные дни между датами и обрабатывает больше, чем часы.

Алгоритм состоит в том, чтобы вычислить, сколько времени с начала до конца бизнеса и от начала бизнеса до конечного времени, а затем вычислить, сколько дней находится между ними. Падение на ту же дату - особый случай.

Предостережение: я провел некоторое базовое тестирование, но, вероятно, не получил все угловые случаи.

    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 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);
    }

Ответ 3

Используйте 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();

Здесь я предполагаю, что все Minute и Second равны нулю. В противном случае (dt2 - dt1).Hours даст неожиданное значение.

Ответ 5

Вы можете попробовать этот алгоритм:

  • Рассчитать общее количество часов (скажем, TotalHours = (Date2 - Date1).TotalHours)
  • Рассчитайте количество праздников (праздники, включая выходные и другие праздники).
  • Calcualte No of Working days ((Date2-Date1).TotalDays - Holidays) as int

Рабочие часы = TotalHours - 24 * праздники - 16 * WorkDays

(16 = Разница во времени между 17:00 и 9:00 следующего дня)

Ответ 6

попробуйте это

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        var date1 = new DateTime(2010, 10, 12, 12, 00, 00);
        var date2 = new DateTime(2010, 10, 14, 15, 00, 00);

        var hr1 = ((date1.Hour > 9) && (date1.Hour < 17)) ? 17 - date1.Hour : 0;
        var hr2 = ((date2.Hour > 9) && (date2.Hour < 17)) ? 17 - date2.Hour : 0;

        var middleHours = ((date2.Date -  date1.Date).Days -1) * 8 ;

        Console.WriteLine(hr1+hr2+ middleHours);
        Console.ReadKey();

    }
}

}

Я попробовал, и он работает:)