In C #, What is the best way to combine and convert one DateTime collection to another?

I have a small calendar tool in C #, and I'm trying to figure out how to convert from one array of DateTime objects to another. Here are the details:

I start with a collection of a DateTime object

 IEnumerable<DateTime> slots = GetSlots();

where each DateTime represents the start time of an available slot (I think the open slot in the calendar) All slots within 30 minutes This is the task. For example:

var slots = new List<DateTime>()

slots.Add(DateTime.Today + new TimeSpan(5,00, 0));

slots.Add(DateTime.Today + new TimeSpan(9,00, 0));
slots.Add(DateTime.Today + new TimeSpan(9,30, 0));
slots.Add(DateTime.Today + new TimeSpan(10,00, 0));
slots.Add(DateTime.Today + new TimeSpan(10,30, 0));
slots.Add(DateTime.Today + new TimeSpan(11,00, 0));
slots.Add(DateTime.Today + new TimeSpan(16,30, 0));

in the above example, this means I'm free:

  • 5:00 to 5:30
  • From 9:00 to 9:30
  • From 9:30 a.m. to 10:00 a.m.
  • 10:00 to 10:30
  • From 10:30 a.m. to 11:00 a.m.
  • From 11:00 to 11:30
  • From 4:30 to 5:00

because I take the time from the item in the collection as the start time and just add 30 minutes to it, and this is considered a free slot.

( 2 ) , 2- , "" . , 2 (120 ),

IEnumerable<DateTime> aggregateArray = MergeIntoLargerSlots(slots, 120);

"" , , . - 2 , . , aggregateArray 2 , :

  • 9AM ( 9-11 (120 ).
  • 9:30 ( 9: 30-11: 30 AM (120 ).

. 30 "" - , 9:05 - 11:05

, , 2-

, MergeIntoLargerSlots , , .

+4
4

, , , .

public List<DateTime> MergeIntoLargerSlots(List<DateTime> slots, int minutes)
{
     int count = minutes/30;
     List<DateTime> retVal = new List<DateTime>();
     foreach (DateTime slot in slots)
     {
          DateTime end = slot.AddMinutes(minutes);
          if (slots.Where(x => x >= slot && x < end).Count() == count)
          {
              retVal.Add(slot);
          }
     }
     return retVal;   
}

; . , , . Where IEnumerable<DateTime> slots, . count, minutes/slotLength, , . Where 9 AM 4 ; 9, 9:30, 10 10:30, count 4, 120/30 == 4, retVal. 9:30, .

+4

, ( , , ), , ( , 30 ). - ( 4 30- , , , , ), .

, , , :

var twoHourSlots = new List<DateTime>();
int consecutiveSlotsCount = 0;
DateTime? previousSlot;
foreach (DateTime smallSlotStart in slots) {
    if (previousSlot.HasValue) {
        if (smallSlotStart - previousSlot.Value == new TimeSpan(0, 30, 0)) {
            consecutiveSlotsCount++;
        } else {
            consecutiveSlotsCount = 0;
        }
    }
    if (consecutiveSlotsCount == 4) {
        twoHourSlots.Add(smallSlotStart - new TimeSpan(1, 30, 0));
        consecutiveSlots = 0;
        previousSlot = null;
    } else {
        previousSlot = smallSlotStart;
    }
}

:

  • DateTime. docs, ; TimeSpan.
  • TimeSpan, , . , .
  • previousSlot, , , ( ), DateTime? ( , docs, , ). , foreach , -.
  • , previousSlot null, 2- , 30- 2- 2- .
  • 30- , . , 30 30- 2- .
0

, :

    private List<DateTime> MergeArray(List<DateTime> slots, int minutes)
    {
        var segments = minutes / InitialSegment;
        var validSegments = new List<DateTime>();
        foreach (var slot in slots.OrderBy(x => x))
        {
            var validSegment = true;
            for (var i = 0; i < segments-1; i++)  
            {
                var next = slot.AddMinutes(InitialSegment * (i + 1));
                if (slots.All(x => x != next))
                {
                    validSegment = false;
                    break;
                }
            }
            if (validSegment)
                validSegments.Add(slot);
        }
        return validSegments;
    }
0

TimeInterval, , .

public sealed class TimeInterval
{
    public DateTime Start { get; private set; }
    public DateTime End { get { return Start.AddMinutes(Duration); } }
    public double Duration { get; private set; }

    public TimeInterval(DateTime start, int duration)
    {
        Start = start;
        Duration = duration;
    }

    public IEnumerable<TimeInterval> Merge(TimeInterval that)
    {
        if(that.Start >= this.Start && that.Start <= this.End)
        {
            if(that.End > this.End)
                Duration += (that.Duration - (this.End - that.Start).TotalMinutes);

            yield return this;
        }
        else
        {       
            yield return this;
            yield return that;
        }
    }
}   

O (n), ( ).

//the `spans` parameter must be presorted
public IEnumerable<TimeInterval> Merge(IEnumerable<TimeInterval> spans, int duration)
{
    var stack = new Stack<TimeInterval>();

    stack.Push(spans.First());

    foreach (var span in spans.Skip(1))
        foreach(var interval in stack.Pop().Merge(span)) //this enumeration is guaranteed to have either one element or two elements.
            stack.Push(interval);

    return from interval in stack where interval.Duration >= duration select interval;
}
0

All Articles