C# 确定两个日期时间之间的差异,仅计算开放时间

C# 确定两个日期时间之间的差异,仅计算开放时间,c#,datetime,C#,Datetime,对于C#中的支持软件,我需要确定两个日期时间之间的时间跨度,但我只希望计算开放时间(即工作日从09:00到17:00) 因此,例如,如果第一个日期时间为2011年2月15日16:00,第二个日期时间为2011年2月16日10:00,则该方法应返回2小时 非常感谢您的帮助 DateTime start=DateTime.Parse(“15/02/2011 16:00”); DateTime start = DateTime.Parse("15/02/2011 16:00"); DateTime e

对于C#中的支持软件,我需要确定两个日期时间之间的时间跨度,但我只希望计算开放时间(即工作日从09:00到17:00)

因此,例如,如果第一个日期时间为2011年2月15日16:00,第二个日期时间为2011年2月16日10:00,则该方法应返回2小时

非常感谢您的帮助

DateTime start=DateTime.Parse(“15/02/2011 16:00”);
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);
DateTime end=DateTime.Parse(“16/02/2011 10:00”); 整数计数=0; 对于(变量i=开始;i<结束;i=i.AddHours(1)) { 如果(i.DayOfWeek!=星期六和i.DayOfWeek!=星期日、星期日) { 如果(i.TimeOfDay.Hours>=9和&i.TimeOfDay.Hours<17) { 计数++; } } } 控制台写入线(计数);
试试这个

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

    }
}
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
var date1=新的日期时间(2010,10,12,12,00,00);
var date2=新的日期时间(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;
控制台写入线(hr1+hr2+middleHours);
Console.ReadKey();
}
}
}

我已经试过了,它正在工作:)

使用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();
DateTime dt1=新的日期时间(2010,10,1,16,0,0);
DateTime dt2=新的日期时间(2010,10,2,10,0,0);
整数小时=可枚举范围(1,(dt2-dt1).hours)
.其中(h=>
{
var dt=dt1.AddHours(h);
return dt.DayOfWeek!=DayOfWeek.周六
&&dt.DayOfWeek!=DayOfWeek.Sunday

&&dt.Hour>=9&&dt.Hour您可以尝试以下算法:

  • 计算总小时数(假设TotalHours=(Date2-Date1).TotalHours)
  • 计算假期数(假期,包括周末和其他假期)
  • 计算工作天数((Date2-Date1)。总天数-节假日)为整数
  • 工作时间=总小时数-24*节假日-16*工作日


    (16=下午5点到第二天上午9点之间的时差)

    我们开始了,为您花了一段时间做这件事。:)

    有检测假日的空间(如果您编写了一个函数来检查
    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'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);
        }
    
    publicstatictimespan-BusinessTimeDelta(DateTime-start,DateTime-stop)
    {
    如果(开始=停止)
    返回TimeSpan.0;
    如果(开始>停止)
    {
    日期时间温度=开始;
    开始=停止;
    停止=温度;
    }
    //首先,我们将截断这些日期时间,使其在工作日内。
    //从一天的开始到结束有多长时间?
    DateTime startFloor=StartTofBusiness(开始);
    DateTime startCeil=业务结束(开始);
    如果(开始<开始楼层)开始=开始楼层;
    如果(start>startCeil)start=startCeil;
    TimeSpan FirstDaily=开始EIL-开始;
    bool workday=true;//稍后保存双重检查
    如果(!IsWorkday(开始))
    {
    workday=假;
    第一天=时间跨度0;
    }
    //从最后一天开始到结束有多长时间?
    DateTime stopFloor=开始营业(停止);
    DateTime stopCeil=业务关闭(停止);
    如果(停止<停止层)停止=停止层;
    如果(stop>stopCeil)stop=stopCeil;
    TimeSpan LastDayer=停车-停车场;
    如果(!IsWorkday(停止))
    LastDayer=时间跨度0;
    //在这一点上,所有日期都被截取到营业时间内。
    if(start.Date==stop.Date)
    {
    if(!workday)//来自早期版本的预计算值
    返回TimeSpan.0;
    返回停止-启动;
    }
    //在这一点上,我们知道它们发生在不同的日期,所以我们可以使用
    //与账套和账套的偏移量。
    TimeSpan timeInBetween=TimeSpan.Zero;
    TimeSpan hoursInAWorkday=(startCeil-startFloor);
    //我尝试了一些很酷的数学知识,而不是一个for循环,但这并没有留下一个干净的方法来计算假期。
    对于(日期时间itr=startFloor.AddDays(1);itr
    这是一种提供分钟级精度并支持夜间时间范围的方法,它基于Oleg Rudckivsky接受的答案

    /// <summary>
    /// Counts the number of minutes between <paramref name="from"/> and <paramref name="to"/>
    /// that fall between <paramref name="rangeStart"/> and <paramref name="rangeEnd"/>.
    /// </summary>
    /// <returns>The total minutes spanned between the given range.</returns>
    public static int GetMinutesInRange(DateTime from, DateTime to, TimeSpan rangeStart, TimeSpan rangeEnd) {
        int minutes = 0;
        bool overnight = rangeStart > rangeEnd;
        for (var m = from; m < to; m = m.AddMinutes(1)) {
            if (overnight) {
                if (rangeStart <= m.TimeOfDay || m.TimeOfDay < rangeEnd) {
                    minutes++;
                }
            } else {
                if (rangeStart <= m.TimeOfDay) {
                    if (m.TimeOfDay < rangeEnd) {
                        minutes++;
                    } else {
                        break;
                    }
                }
            }
        }
        return minutes;
    }
    

    有一些类似的问题已经在讨论中了。例如,假期?分钟和秒?精确到最近的一小时对于我来说应该足够了。丹麦假期很好,但不是关键性的。谢谢你的回答
    DateTime from = new DateTime(1990, 1, 1, 6, 30, 0);  // 7:30 AM
    DateTime to = new DateTime(1990, 1, 1, 13, 30, 0);   // 1:30 PM
    TimeSpan rangeStart = new TimeSpan(9, 0, 0);  // 9 AM
    TimeSpan rangeEnd = new TimeSpan(17, 0, 0);   // 5 PM
    
    // Results in 270 (4.5 hours)
    int minutes = GlobalHelpers.GetMinutesInRange(from, to, rangeStart, rangeEnd);