【问题标题】:Calculate Duration of Overlapping Time Periods计算重叠时间段的持续时间
【发布时间】:2014-11-08 06:06:26
【问题描述】:

考虑以下示例:

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

【问题讨论】:

    标签: javascript c# algorithm datetime time


    【解决方案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

    【讨论】:

      【解决方案2】:

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


      逻辑大纲:-

      如果 taskEnd > taskStart (没有日期更改 -> redEye =false )
      从头到尾遍历您的任务。检查每个小时并根据它们所在的区域增加 Day/NightHours 计数
      else (即 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());
          }
      

      结果
      夜间:2
      白天:13

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-30
        • 1970-01-01
        • 1970-01-01
        • 2022-11-17
        • 2018-07-27
        相关资源
        最近更新 更多