zoukankan      html  css  js  c++  java
  • c# 计算两日期的工作时间间隔(排除非工作日)及计算下一个工作时间点

    一个日期段如工作时间为 8:00 至 17:00

    复制代码
    public class TimeHelper
        {
    
            /// <summary>
            /// 计算时间间隔
            /// </summary>
            /// <param name="tsStart"></param>
            /// <param name="tsEnd"></param>
            /// <param name="time_start"></param>
            /// <param name="time_end"></param>
            /// <returns></returns>
            public static TimeSpan GetTimeSpan(TimeSpan tsStart, TimeSpan tsEnd, TimeSpan time_start, TimeSpan time_end)
            {
                if (tsStart > tsEnd)
                    return new TimeSpan(0);
    
                if (tsEnd < time_start)
                    return new TimeSpan(0);
    
                if (tsStart > time_end)
                    return new TimeSpan(0);
    
                if (tsStart >= time_start && tsStart <= time_end)
                    time_start = tsStart;
    
                if (tsEnd <= time_end && tsEnd >= time_start)
                    time_end = tsEnd;
    
                return time_end - time_start;
            }
            /// <summary>
            /// 获取两日期的工作时间间隔
            /// </summary>
            /// <param name="dtStart"></param>
            /// <param name="dtEnd"></param>
            /// <param name="time_start"></param>
            /// <param name="time_end"></param>
            /// <returns></returns>
            public static TimeSpan GetDateTimeSpan(DateTime dtStart, DateTime dtEnd, TimeSpan time_start, TimeSpan time_end)
            {
                if (dtStart.Date == dtEnd.Date) //如果是同一天
                {
                    if (IsWorkDay(dtStart))
                        return GetTimeSpan(dtStart.TimeOfDay, dtEnd.TimeOfDay, time_start, time_end);
                    else
                        return new TimeSpan(0);
                }
                //如果不是同一天 计算天数减去1 乘以标准时长 加上分别计算开始开数和结束天数
                double days = dtEnd.Date.Subtract(dtStart.Date).TotalDays - 1;
                
                TimeSpan startTimeSpan;
                if (IsWorkDay(dtStart))
                    startTimeSpan = GetTimeSpan(dtStart.TimeOfDay, new TimeSpan(23, 59, 60), time_start, time_end);//开始天
                else
                    startTimeSpan = new TimeSpan(0);
    
                TimeSpan endTimeSpan;
                if (IsWorkDay(dtEnd))
                    endTimeSpan = GetTimeSpan(new TimeSpan(0, 0, 0), dtEnd.TimeOfDay, time_start, time_end);//结束天
                else
                    endTimeSpan = new TimeSpan(0);
    
                TimeSpan totalTimeSpan = startTimeSpan + endTimeSpan; //总值
    
                TimeSpan preTimeSpan = time_end - time_start;
                for (int i = 1; i <=days; i++)
                {
                    if (IsWorkDay(dtStart.AddDays(i)))
                        totalTimeSpan += preTimeSpan; //添加间隔天
                }
    
                return totalTimeSpan;
            }
            /// <summary>
            /// 判断是否为工作日
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public static bool IsWorkDay(DateTime dt)
            {
                //先从日期表中,查找不是上班时间,如果不是直接返回 false ,如果是,直接返回 true。
                //如果在日期表中,找不到,则查找定义的日历,依据日历定义的周末时间来定义是否为工作日。
                //获取日历中不上班的标准周末时间,判断是不是上班时间
                if (dt.DayOfWeek == DayOfWeek.Sunday || dt.DayOfWeek == DayOfWeek.Saturday)
                    return false;
                else
                    return true;
            }
            /// <summary>
            /// 给定时间点加上时间间隔后得出新的时间
            /// </summary>
            /// <param name="startDate"></param>
            /// <param name="exTimeSpan"></param>
            /// <param name="time_start"></param>
            /// <param name="time_end"></param>
            /// <returns></returns>
            public static DateTime GetDateTime(DateTime startDate, TimeSpan exTimeSpan, TimeSpan time_start, TimeSpan time_end)
            {
                TimeSpan t_span = exTimeSpan;
                //初始到工作日
                while (!IsWorkDay(startDate))
                    startDate = startDate.AddDays(1);
                //初始到起始时间
                if (startDate.TimeOfDay < time_start)
                    startDate = startDate - startDate.TimeOfDay + time_start;
    
                if (startDate.TimeOfDay > time_end)
                {
                    startDate = startDate.AddDays(1);
                    startDate = startDate - startDate.TimeOfDay + time_start;
    
                    //初始到工作日
                    while (!IsWorkDay(startDate))
                        startDate = startDate.AddDays(1);
                }
                //计算本天结束剩余多少天
                TimeSpan tmpTs = GetTimeSpan(startDate.TimeOfDay, time_end, time_start, time_end);
    
                //剩余时长
                exTimeSpan = exTimeSpan - tmpTs;
                //如果计算后剩余小于零 直接返回
                if (exTimeSpan < new TimeSpan(0))
                    return startDate + t_span;
    
                //如果计算后大于零,继续新增1天.
                TimeSpan preDayTimeSpan = time_end - time_start;
                do
                {
                    do
                    {
                        startDate = startDate.AddDays(1);
                    } while (!IsWorkDay(startDate));
    
                    if (exTimeSpan > preDayTimeSpan)
                        exTimeSpan -= preDayTimeSpan;
                    else
                        break;
    
                } while (exTimeSpan > new TimeSpan(0));
    
                startDate = startDate - startDate.TimeOfDay + time_start; //把计算得出的当天值为初始时间如早上8:00
    
                return startDate + exTimeSpan;
            }
        }
    复制代码

    二段工作时间:如 8:00至12:00   13:00 至17:00

    复制代码
        public class TimeHelper2
        {
            public static TimeSpan GetDateTimeSpan(DateTime dtStart, DateTime dtEnd, TimeSpan time_start, TimeSpan time_end, TimeSpan time_start2, TimeSpan time_end2)
            {
                if (dtStart.Date == dtEnd.Date) //如果是同一天
                {
                    if (IsWorkDay(dtStart))
                        return GetTimeSpan(dtStart.TimeOfDay, dtEnd.TimeOfDay, time_start, time_end, time_start2, time_end2);
                    else
                        return new TimeSpan(0);
                }
                //如果不是同一天 计算天数减去1 乘以标准时长 加上分别计算开始开数和结束天数
                double days = dtEnd.Date.Subtract(dtStart.Date).TotalDays - 1;
    
                TimeSpan startTimeSpan;
                if (IsWorkDay(dtStart))
                    startTimeSpan = GetTimeSpan(dtStart.TimeOfDay, new TimeSpan(23, 59, 60), time_start, time_end, time_start2, time_end2);//开始天
                else
                    startTimeSpan = new TimeSpan(0);
    
                TimeSpan endTimeSpan;
                if (IsWorkDay(dtEnd))
                    endTimeSpan = GetTimeSpan(new TimeSpan(0, 0, 0), dtEnd.TimeOfDay, time_start, time_end, time_start2, time_end2);//结束天
                else
                    endTimeSpan = new TimeSpan(0);
    
                TimeSpan totalTimeSpan = startTimeSpan + endTimeSpan; //总值
    
                TimeSpan preTimeSpan = GetTimeSpan(new TimeSpan(0, 0, 0), new TimeSpan(23, 59, 60), time_start, time_end, time_start2, time_end2);//开始天
                for (int i = 1; i <= days; i++)
                {
                    if (IsWorkDay(dtStart.AddDays(i)))
                        totalTimeSpan += preTimeSpan; //添加间隔天
                }
    
                return totalTimeSpan;
            }
    
            /// <summary>
            /// 判断是否为工作日
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public static bool IsWorkDay(DateTime dt)
            {
                //先从日期表中,查找不是上班时间,如果不是直接返回 false ,如果是,直接返回 true。
                //如果在日期表中,找不到,则查找定义的日历,依据日历定义的周末时间来定义是否为工作日。
                //获取日历中不上班的标准周末时间,判断是不是上班时间
                if (dt.DayOfWeek == DayOfWeek.Sunday || dt.DayOfWeek == DayOfWeek.Saturday)
                    return false;
                else
                    return true;
            }
    
            //同一天获取
            public static TimeSpan GetTimeSpan(TimeSpan tsStart, TimeSpan tsEnd, TimeSpan time_start, TimeSpan time_end, TimeSpan time_start2, TimeSpan time_end2)
            {
    
                //判断 开始时间
                if (tsStart < time_start)
                {
                    //标准开始时间不变
                    //start1 不变
                    //start2 不变
                }
                else if (tsStart >= time_start && tsStart <= time_end)
                {
                    //标准开始= dtStart
                    time_start = tsStart;
                    //start1 变
                    //start2 不变
                }
                else if (tsStart > time_end && tsStart < time_start2)
                {
                    time_start = time_end;
                    //start1 变
                    //start2 不变
                }
                else if (tsStart >= time_start2 && tsStart <= time_end2)
                {
                    time_start = time_end;
                    time_start2 = tsStart;
                    //start1 变
                    //start2 变
                }
                else if (tsStart > time_end2)
                {
                    time_start = time_end;
                    time_start2 = time_end2;
                    //start1 变
                    //start2 变
                }
    
                //判断 结束时间
                if (tsEnd < time_start)
                {
                    //标准开始时间不变
                    time_end = time_start;
                    time_end2 = time_start2;
                    //time_end 变
                    //time_end2变
                }
                else if (tsEnd >= time_start && tsEnd <= time_end)
                {
                    time_end = tsEnd;
                    time_end2 = time_start2;
                    //time_end 变
                    //time_end2变
                }
                else if (tsEnd > time_end && tsEnd < time_start2)
                {
                    time_end2 = time_start2;
                    //time_end2 不变
                    //time_end1变
                }
                else if (tsEnd >= time_start2 && tsEnd <= time_end2)
                {
                    time_end2 = tsEnd;
                    //time_end 不变
                    //time_end2变
                }
                else if (tsEnd > time_end2)
                {
                    //time_end 不变
                    //time_end2不变
                }
    
                return (time_end - time_start) + (time_end2 - time_start2);
            }
        }
    复制代码

    三个时间段的 如工作时间为://8:30-12:00 13.30-17.30 18.00-21.00

    复制代码
        public class TimeHelper3
        {
    
            public static TimeSpan GetDateTimeSpan(DateTime dtStart, DateTime dtEnd, TimeSpan time_start, TimeSpan time_end, TimeSpan time_start2, TimeSpan time_end2, TimeSpan time_start3, TimeSpan time_end3)
            {
                if (dtStart.Date == dtEnd.Date) //如果是同一天
                {
                    if (IsWorkDay(dtStart))
                        return GetTimeSpan(dtStart.TimeOfDay, dtEnd.TimeOfDay, time_start, time_end, time_start2, time_end2, time_start3, time_end3);
                    else
                        return new TimeSpan(0);
                }
                //如果不是同一天 计算天数减去1 乘以标准时长 加上分别计算开始开数和结束天数
                double days = dtEnd.Date.Subtract(dtStart.Date).TotalDays - 1;
    
                TimeSpan startTimeSpan;
                if (IsWorkDay(dtStart))
                    startTimeSpan = GetTimeSpan(dtStart.TimeOfDay, new TimeSpan(23, 59, 60), time_start, time_end, time_start2, time_end2, time_start3, time_end3);//开始天
                else
                    startTimeSpan = new TimeSpan(0);
    
                TimeSpan endTimeSpan;
                if (IsWorkDay(dtEnd))
                    endTimeSpan = GetTimeSpan(new TimeSpan(0, 0, 0), dtEnd.TimeOfDay, time_start, time_end, time_start2, time_end2, time_start3, time_end3);//结束天
                else
                    endTimeSpan = new TimeSpan(0);
    
                TimeSpan totalTimeSpan = startTimeSpan + endTimeSpan; //总值
    
                TimeSpan preTimeSpan = GetTimeSpan(new TimeSpan(0, 0, 0), new TimeSpan(23, 59, 60), time_start, time_end, time_start2, time_end2, time_start3, time_end3);//开始天
                for (int i = 1; i <= days; i++)
                {
                    if (IsWorkDay(dtStart.AddDays(i)))
                        totalTimeSpan += preTimeSpan; //添加间隔天
                }
    
                return totalTimeSpan;
            }
    
            /// <summary>
            /// 判断是否为工作日
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public static bool IsWorkDay(DateTime dt)
            {
                //先从日期表中,查找不是上班时间,如果不是直接返回 false ,如果是,直接返回 true。
                //如果在日期表中,找不到,则查找定义的日历,依据日历定义的周末时间来定义是否为工作日。
                //获取日历中不上班的标准周末时间,判断是不是上班时间
                if (dt.DayOfWeek == DayOfWeek.Sunday || dt.DayOfWeek == DayOfWeek.Saturday)
                    return false;
                else
                    return true;
            }
            //同一天获取
            public static TimeSpan GetTimeSpan(TimeSpan tsStart, TimeSpan tsEnd, TimeSpan time_start, TimeSpan time_end, TimeSpan time_start2, TimeSpan time_end2, TimeSpan time_start3, TimeSpan time_end3)
            {
                //判断 开始时间
                if (tsStart < time_start)
                {
                    //标准开始时间不变
                    //start1 不变
                    //start2 不变
                    //start3 不变
                }
                else if (tsStart >= time_start && tsStart <= time_end)
                {
                    //标准开始= dtStart
                    time_start = tsStart;
                    //start1 变
                    //start2 不变
                    //start3 不变
                }
                else if (tsStart > time_end && tsStart < time_start2)
                {
                    time_start = time_end;
                    //start1 变
                    //start2 不变
                    //start3 不变
                }
                else if (tsStart >= time_start2 && tsStart <= time_end2)
                {
                    time_start = time_end;
                    time_start2 = tsStart;
                    //start1 变
                    //start2 变
                    //start3 不变
                }
                else if (tsStart > time_end2 && tsStart < time_start3)
                {
                    time_start = time_end;
                    time_start2 = time_end2;
                    //start1 变
                    //start2 变
                    //start3 不变
                }
                else if (tsStart >= time_start3 && tsStart <= time_end3)
                {
                    time_start = time_end;
                    time_start2 = time_end2;
                    time_start3 = tsStart;
                    //start1 变
                    //start2 变
                    //start3 变
                }
                else if (tsStart > time_end3)
                {
                    time_start = time_end;
                    time_start2 = time_end2;
                    time_start3 = time_end3;
                }
    
                //判断 结束时间
                if (tsEnd < time_start)
                {
                    //标准开始时间不变
                    time_end = time_start;
                    time_end2 = time_start2;
                    time_end3 = time_start3;
                    //time_end 变
                    //time_end2变
                    //time_end3变
                }
                else if (tsEnd >= time_start && tsEnd <= time_end)
                {
                    time_end = tsEnd;
                    time_end2 = time_start2;
                    time_end3 = time_start3;
                    //time_end 变
                    //time_end2变
                    //time_end3变
                }
                else if (tsEnd > time_end && tsEnd < time_start2)
                {
                    time_end2 = time_start2;
                    time_end3 = time_start3;
                    //time_end1 不变
                    //time_end2变
                    //time_end3变
                }
                else if (tsEnd >= time_start2 && tsEnd <= time_end2)
                {
                    time_end2 = tsEnd;
                    time_end3 = time_start3;
                    //time_end 不变
                    //time_end2变
                    //time_end3变
                }
                else if (tsEnd > time_end2 && tsEnd < time_start3)
                {
                    time_end3 = time_start3;
                    //time_end 不变
                    //time_end2不变
                    //time_end3变
                }
                else if (tsEnd >= time_start3 && tsEnd <= time_end3)
                {
                    time_end3 = tsEnd;
                    //time_end 不变
                    //time_end2不变
                    //time_end3变
                }
                else if (tsEnd > time_end3)
                {
                    //time_end 不变
                    //time_end2不变
                    //time_end3不变
                }
    
                return (time_end - time_start) + (time_end2 - time_start2) + (time_end3 - time_start3);
            }
        }
    复制代码

    使用方法:

    复制代码
            static void Main(string[] args)
            {
                DateTime dt = Convert.ToDateTime("2014-04-17 08:00");
                DateTime dt2 = Convert.ToDateTime("2014-04-21 08:00");
    
    
                TimeSpan tsStar1 = new TimeSpan(8, 0, 0);
                TimeSpan tsEnd1 = new TimeSpan(12, 0, 0);
    
                TimeSpan tsStar2 = new TimeSpan(13, 0, 0);
                TimeSpan tsEnd2 = new TimeSpan(17, 0, 0);
    
                TimeSpan tsStar3 = new TimeSpan(18, 0, 0);
                TimeSpan tsEnd3 = new TimeSpan(21, 0, 0);
    
                //8:30-12:00 13.30-17.30 18.00-21.00
    
                TimeSpan ts1 = TimeHelper.GetDateTimeSpan(dt, dt2, tsStar1, tsEnd1);
    
                TimeSpan ts2 = TimeHelper2.GetDateTimeSpan(dt, dt2, tsStar1, tsEnd1, tsStar2, tsEnd2);
    
                TimeSpan ts3 = TimeHelper3.GetDateTimeSpan(dt, dt2, tsStar1, tsEnd1, tsStar2, tsEnd2, tsStar3, tsEnd3);
    
    
                Console.WriteLine("一阶段:{0}天 {1}小时,{2}分,{3}秒", ts1.Days, ts1.Hours, ts1.Minutes, ts1.Seconds);
                Console.WriteLine("两阶段:{0}天 {1}小时,{2}分,{3}秒", ts2.Days, ts2.Hours, ts2.Minutes, ts2.Seconds);
                Console.WriteLine("三阶段:{0}天 {1}小时,{2}分,{3}秒", ts3.Days, ts3.Hours, ts3.Minutes, ts3.Seconds);
    
                Console.ReadLine();
    
            }
    复制代码
  • 相关阅读:
    转载:C#制作PDF
    搜索研究
    HDU 4029 Distinct Submatrix [后缀数组]
    HDU 4336 Card Collector [状态压缩概率DP]
    ZOJ 3329 One Person Game [数学期望]
    POJ 2096 Collecting Bugs[数学期望]
    HDU 4338 Simple Path [双联通分量+RMQ(LCA)]
    POJ 1222 EXTENDED LIGHTS OUT [高斯消元]
    HDU 2258 Continuous Same Game (1)[模拟]
    HDU 4339 Query [树状数组]
  • 原文地址:https://www.cnblogs.com/ssk-bak/p/7919927.html
Copyright © 2011-2022 走看看