计算重叠时间段的持续时间

时间:2014-11-08 06:06:27

标签: javascript c# algorithm datetime time

请考虑以下示例:

Daytime starts (night ends): 07:00
Daytime ends (night starts): 20:00

------------------------------

Task A start time: 06:00
Task A end time: 08:00

Task B start time: 10:00
Task B end time: 12:00

Task C start time: 19:00
Task C end time: 21:00

Task D start time: 23:00
Task D end time: 01:00

Task E start time: 06:00
Task E end time: 21:00

如何计算白天在任务中花费的时间,以及在夜间花费了多少时间?上述答案将是:

A (day): 1 hr
A (night): 1 hr

B (day): 2 hrs
B (night): 0 hrs

C (day): 1 hr
C (night): 1 hr

D (day): 0 hrs
D (night): 2 hrs

E (day): 13 hrs
E (night): 2 hrs

2 个答案:

答案 0 :(得分:1)

根据标签猜测您需要在javascript或C#中使用解决方案。这是c#的代码:

namespace DurationOfOverlappingTimePeriods
{
    class Program
    {
        static void Main(string[] args)
        {
            TimeSpan taskAStart = new TimeSpan(6, 0, 0);
            TimeSpan taskAEnd = new TimeSpan(8, 0, 0);
            Tuple<TimeSpan, TimeSpan> taskATimes = GetTaskDurations(taskAStart, taskAEnd);
            Console.WriteLine("A (day): {0}", taskATimes.Item1);
            Console.WriteLine("A (night): {0}", taskATimes.Item2);
            Console.WriteLine();

            TimeSpan taskBStart = new TimeSpan(10, 0, 0);
            TimeSpan taskBEnd = new TimeSpan(12, 0, 0);
            Tuple<TimeSpan, TimeSpan> taskBTimes = GetTaskDurations(taskBStart, taskBEnd);
            Console.WriteLine("B (day): {0}", taskBTimes.Item1);
            Console.WriteLine("B (night): {0}", taskBTimes.Item2);
            Console.WriteLine();

            TimeSpan taskCStart = new TimeSpan(19, 0, 0);
            TimeSpan taskCEnd = new TimeSpan(21, 0, 0);
            Tuple<TimeSpan, TimeSpan> taskCTimes = GetTaskDurations(taskCStart, taskCEnd);
            Console.WriteLine("C (day): {0}", taskCTimes.Item1);
            Console.WriteLine("C (night): {0}", taskCTimes.Item2);
            Console.WriteLine();

            TimeSpan taskDStart = new TimeSpan(23, 0, 0);
            TimeSpan taskDEnd = new TimeSpan(1, 0, 0);
            Tuple<TimeSpan, TimeSpan> taskDTimes = GetTaskDurations(taskDStart, taskDEnd);
            Console.WriteLine("D (day): {0}", taskDTimes.Item1);
            Console.WriteLine("D (night): {0}", taskDTimes.Item2);
            Console.WriteLine();

            TimeSpan taskEStart = new TimeSpan(6, 0, 0);
            TimeSpan taskEEnd = new TimeSpan(21, 0, 0);
            Tuple<TimeSpan, TimeSpan> taskETimes = GetTaskDurations(taskEStart, taskEEnd);
            Console.WriteLine("E (day): {0}", taskETimes.Item1);
            Console.WriteLine("E (night): {0}", taskETimes.Item2);
            Console.WriteLine();

        }

        static Tuple<TimeSpan, TimeSpan> GetTaskDurations(
            TimeSpan taskStartTime,
            TimeSpan taskEndTime)
        {
            DateTime daytimeStart = DateTime.Today.Add(new TimeSpan(7, 0, 0));
            DateTime daytimeEnd = DateTime.Today.Add(new TimeSpan(20, 0, 0));
            Range daytimeRange = new Range(daytimeStart, daytimeEnd);

            if (taskEndTime < taskStartTime)
                taskEndTime = taskEndTime + TimeSpan.FromDays(1);

            DateTime taskStart = DateTime.Today.Add(taskStartTime);
            DateTime taskEnd = DateTime.Today.Add(taskEndTime);
            Range taskRange = new Range(taskStart, taskEnd);

            TimeSpan daytimeTaskDuration = daytimeRange.IntersectionDuration(taskRange);
            TimeSpan nighttimeTaskDuration = taskRange.Duration() - daytimeTaskDuration;

            return new Tuple<TimeSpan, TimeSpan>(daytimeTaskDuration, nighttimeTaskDuration);
        }
    }

    class Range
    {
        public Range()
        {
        }

        public Range(DateTime start, DateTime End)
        {
            this.Start = start;
            this.End = End;
        }

        DateTime Start { get; set; }
        DateTime End { get; set; }

        public TimeSpan IntersectionDuration(Range otherRange)
        {
            Range intersection = new Range();
            intersection.Start = this.Start < otherRange.Start ? otherRange.Start : this.Start;
            intersection.End = this.End < otherRange.End ? this.End : otherRange.End;
            if (intersection.Start >= intersection.End)
                return new TimeSpan(0);
            else
                return intersection.End - intersection.Start;
        }

        public TimeSpan Duration()
        {
            return this.End - this.Start;
        }
    }
}

这是输出:
A(日):01:00:00
A(夜):01:00:00
B(日):02:00:00 B(夜间):00:00:00
C(日):01:00:00
C(夜晚):01:00:00
D(日):00:00:00
D(夜晚):02:00:00
E(日):13:00:00
E(夜晚):02:00:00

答案 1 :(得分:0)

假设:
1)TaskEnd - start&lt; = 24,即任务不超过24小时跨度 如果任务可以超过24小时,则需要实施日计数逻辑。 (DayCount限制?)
2)以小时为单位的时间分辨率。
(分数(分钟)可以容纳在逻辑中,代码改变特定于语言js / c#)


逻辑概要: -

如果taskEnd&gt; taskStart (没有日期更改 - &gt; redEye = false)
  从头到尾遍历您的任务。检查每小时,并根据它们落下的区域增加Day / NightHours计数
其他 (即redEye = true)
  将任务从0移动到任务结束,然后从任务开始到23,并根据它们落下的区域增加Day / NightHours。

static void Main(string[] args)
    {
        int DayHours = 0;
        int NightHours = 0;

        int dawn = 7;
        int dusk = 20;

        int start = 6;     // enter task start 
        int end = 21;      // enter task end 

        bool redEye = false;

        if (end < start) 
            redEye = true;

        for (int i = 0; i < 24; i++)
        {
            if (!redEye)
            {
                if (i >= start && i < end)
                {
                    if (i > 0 && i < dawn)
                        NightHours++;
                    else if (i >= dawn && i < dusk)
                        DayHours++;
                    else if (i >= dusk)
                        NightHours++;
                }
            }
            else {
                if (i < end || i >= start)   //i.e current time 0-end OR start-23 
                {
                    if (i < dawn)
                        NightHours++;
                    else if (i >= dawn && i < dusk)
                        DayHours++;
                    else if (i >= dusk)
                        NightHours++;
                }
            }            
        }


        System.Console.WriteLine("Nighthours :" +NightHours.ToString() );
        System.Console.WriteLine("DayHoures :" + DayHours.ToString());
    }

结果
Nighthours:2
DayHoures:13