c# 計算兩日期的工做時間間隔(排除非工做日)及計算下一個工做時間點

一個日期段如工做時間爲 8:00 至 17:00spa

複製代碼
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:00code

複製代碼
    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.00blog

複製代碼
    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);
        }
    }
複製代碼

使用方法:string

複製代碼
        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();

        }
複製代碼
相關文章
相關標籤/搜索