using System.Collections.Generic;
Dictionary<DateTimeOffset, List<DateTimeOffset>> availableSlots = new Dictionary<DateTimeOffset, List<DateTimeOffset>>();
DateTime readyByTime = new DateTime(2020, 01, 14, 9, 0, 0);
DateTime closeTime = new DateTime(2020, 01, 14, 21, 0, 0);
DateTime latesBookingTime = new DateTime(2020, 01, 14, 15, 0, 0);
var customerLocalTime = DateTimeOffset.UtcNow;
for (int i = readyByTime.Hour; i <= latesBookingTime.Hour; i++)
var nextReadyTime = new DateTimeOffset(customerLocalTime.Date.AddHours(i), customerLocalTime.Offset);
availableSlots[nextReadyTime] = new List<DateTimeOffset>();
for (int j = Math.Max(nextReadyTime.Hour + minHourWindow, this.Ceil(latesBookingTime, TimeSpan.FromHours(1)).Hour); j <= closeTime.Hour; j++)
var nextEndTime = new DateTimeOffset(customerLocalTime.Date.AddHours(j), customerLocalTime.Offset);
availableSlots[nextReadyTime].Add(nextEndTime);
foreach (KeyValuePair<DateTimeOffset, List<DateTimeOffset>> kvp in availableSlots)
foreach(var endTime in kvp.Value)
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key.ToString(), endTime.ToString());
public DateTime Ceil(DateTime date, TimeSpan span)
long ticks = (date.Ticks + span.Ticks - 1) / span.Ticks;
return new DateTime(ticks * span.Ticks);