コード例 #1
0
ファイル: DBManager.cs プロジェクト: tordf/iLabs
        public static Recurrence[] GetRecurrences(string serviceBrokerGuid, string groupName,
                    string labServerGuid, string clientGuid, DateTime startTime, DateTime endTime)
        {
            TimeBlock range = new TimeBlock(startTime, endTime);
            List<Recurrence> recurrences = new List<Recurrence>();
            DbConnection connection = FactoryDB.GetConnection();

            // create sql command
            // command executes the "RetrieveRecurrenceIDs" stored procedure
            DbCommand cmd = FactoryDB.CreateCommand("Recurrences_Retrieve", connection);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@sbGuid", serviceBrokerGuid, DbType.AnsiString, 50));
            cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@group", groupName, DbType.String, 256));
            cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@lsGuid", labServerGuid, DbType.AnsiString, 50));
            cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@clientGuid", clientGuid, DbType.AnsiString, 50));
            cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@start", DateUtil.SpecifyUTC(startTime), DbType.DateTime));
            cmd.Parameters.Add(FactoryDB.CreateParameter(cmd,"@end", DateUtil.SpecifyUTC(endTime), DbType.DateTime));

            try
            {
                DbDataReader dataReader = null;
                Recurrence recur = null;
                connection.Open();

                //recurrence_id,resource_id,recurrence_type,day_mask,recurrence_start_date,recurrence_num_days
                //recurrence_start_offset,recurrence_end_offset, quantum
                dataReader = cmd.ExecuteReader();
                while (dataReader.Read())
                {
                    recur = new Recurrence();
                    recur.recurrenceId = dataReader.GetInt32(0);
                    recur.resourceId = dataReader.GetInt32(1);
                    recur.recurrenceType = (Recurrence.RecurrenceType)dataReader.GetInt32(2);
                    recur.dayMask = dataReader.GetByte(3);
                    recur.startDate = DateUtil.SpecifyUTC(dataReader.GetDateTime(4));
                    recur.numDays = dataReader.GetInt32(5);
                    recur.startOffset = TimeSpan.FromSeconds((double)dataReader.GetInt32(6));
                    recur.endOffset = TimeSpan.FromSeconds((double)dataReader.GetInt32(7));
                    recur.quantum = dataReader.GetInt32(8);
                    TimeBlock[] blocks = recur.GetTimeBlocks();
                    foreach (TimeBlock tb in blocks)
                    {
                        if (range.Intersects(tb))
                        {
                            recurrences.Add(recur);
                            break;
                        }
                    }
                }
                dataReader.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("Exception thrown in get recurrences", ex);
            }
            finally
            {
                connection.Close();
            }
            return recurrences.ToArray();
        }
コード例 #2
0
ファイル: SchedulingControl.cs プロジェクト: tordf/iLabs
        private void renderTimePeriods(HtmlTextWriter output, DateTime date, IEnumerable periods)
        {
            TimeBlock validTime = new TimeBlock(date.AddHours((int)minTOD.Hours), date.AddHours((int)maxTOD.TotalHours));
            if (periods != null)
            {
                IEnumerator enumTP = null;
                try
                {
                    enumTP = periods.GetEnumerator();
                    enumTP.MoveNext();
                    TimePeriod first = (TimePeriod)enumTP.Current;
                    if (first.Start > validTime.Start)
                    {
                        renderVoidTime(output, Convert.ToInt32((first.Start - validTime.Start).TotalSeconds));
                    }
                }
                catch (Exception ex) { }
                finally
                {
                    enumTP.Reset();
                }

                foreach (TimePeriod tp in periods)
                {
                    if (validTime.Intersects(tp))
                    {
                        TimeBlock valid = validTime.Intersection(tp);
                        if (tp.quantum == 0)
                        {
                            renderScheduledTime(output, valid);
                        }
                        else
                        {
                            int cellDur = 0;
                            int tDur = valid.Duration;
                            DateTime cur = valid.Start;
                            DateTime end = valid.End;

                            while (cur < end)
                            {
                                cellDur = defaultCellDuration -(cur.TimeOfDay.Minutes % defaultCellDuration);
                                if(cellDur < defaultCellDuration)
                                    cellDur += defaultCellDuration;
                                if ((end - cur.AddMinutes(cellDur)).TotalMinutes < (defaultCellDuration/2))
                                {
                                    cellDur += Convert.ToInt32((end - cur.AddMinutes(cellDur)).TotalMinutes );
                                }
                                cellDur = (cur.AddMinutes(cellDur) <= end) ? cellDur : (int)(end - cur).TotalMinutes;
                                renderAvailableTime(output, cur, tDur, tp.quantum, cellDur * 60, false);
                                cur = cur.AddMinutes(cellDur);
                                tDur = tDur - (cellDur * 60);

                                //cellDur = (cur.TimeOfDay.Minutes % defaultCellDuration) + defaultCellDuration;
                                //cellDur = (cur.AddMinutes(cellDur) <= end) ? cellDur : (int)(end - cur).TotalMinutes;
                                //renderAvailableTime(output, cur, tDur, tp.quantum, cellDur * 60, false);
                                //cur = cur.AddMinutes(cellDur);
                                //tDur = tDur - (cellDur * 60);
                            }
                        }
                    }
                }
            }
        }
コード例 #3
0
ファイル: LSSSchedulingAPI.cs プロジェクト: tordf/iLabs
        /// <summary>
        /// Returns an Boolean indicating whether a particular reservation from a USS is confirmed and added to the database in LSS successfully. If it fails, exception will be throw out indicating
        ///	the reason for rejection.
        /// </summary>
        /// <param name="serviceBrokerGuid"></param>
        /// <param name="groupName"></param>
        /// <param name="ussGuid"></param>
        /// <param name="labServerGuid"></param>
        /// <param name="clientGuid"></param>
        /// <param name="startTime"></param>the local time of LSS
        /// <param name="endTime"></param>the local time of LSS
        /// <returns></returns>the notification whether the reservation is confirmed. If not, notification will give a reason
        public static string ConfirmReservation(string serviceBrokerGuid, string groupName, string ussGuid,
             string labServerGuid, string clientGuid, DateTime startTime, DateTime endTime)
        {
            string notification = null;
            try
            {

                //get the experiment configuration

                int eID = DBManager.ListExperimentInfoIDByExperiment(labServerGuid, clientGuid);
                LssExperimentInfo exInfo = GetExperimentInfos(new int[] { eID })[0];
                int preTime = exInfo.prepareTime;
                int recTime = exInfo.recoverTime;
                int minTime = exInfo.minimumTime;
                //check whether the reservation is executable
                if (((TimeSpan)endTime.Subtract(startTime)).TotalMinutes < minTime)
                {
                    notification = "The reservation time is less than the minimum time the experiment required";
                    return notification;
                }
                //the start time for the experiment equipment
                DateTime expStartTime = startTime.AddMinutes(-preTime);
                //the end time for the experiment equipment
                DateTime expEndTime = endTime.AddMinutes(recTime);
                Recurrence[] recurrences = DBManager.GetRecurrences(serviceBrokerGuid, groupName,
                    labServerGuid, clientGuid, startTime, endTime);
                if ((recurrences == null) || (recurrences.Length == 0))
                {
                    notification = "This experiment is not available to your group during this time.";
                    return notification;
                }
                else if (recurrences.Length > 1)
                {
                    notification = "More than one recurrence was found for this request. Please choose another time.";
                    return notification;
                }

                else
                {
                    TimeBlock[] reserved = DBManager.ListReservationTimeBlocks(recurrences[0].resourceId, expStartTime, expEndTime);
                    bool ok = true;
                    if ((reserved != null) && (reserved.Length > 0))
                    {

                        // Need to process the reservations to make suggestions
                        notification = "This reservation time is not available now, please adjust your reservation time.";
                        TimeBlock check = new TimeBlock(expStartTime, expEndTime);
                        foreach (TimeBlock tb in reserved)
                        {
                            TimeBlock intersection = check.Intersection(tb);
                            if (intersection != null)
                            {
                                TimeSpan span = TimeSpan.FromSeconds(intersection.Duration);
                                if(intersection.Start < expEndTime)
                                    notification += @"<br />Adjust the time by starting " + span.TotalMinutes +
                                        " minutes earlier, or make the duration shorter by " + span.TotalMinutes + " minutes.";
                                if (intersection.End > expStartTime)
                                    notification += @"<br />Adjust the time by starting " + span.TotalMinutes +
                                        " minutes later.";

                            }

                        }
                        return notification;
                    }
                    //add the reservation to to reservationInfo table
                    int status = AddReservationInfo(serviceBrokerGuid, groupName, ussGuid, labServerGuid, clientGuid, startTime.ToUniversalTime(), endTime.ToUniversalTime(), 0);
                    if (status > 0)
                    {
                        notification = "The reservation is confirmed successfully";
                        if (exInfo.contactEmail != null && exInfo.contactEmail.Length > 0)
                        {
                            // Send a mail Message
                            StringBuilder message = new StringBuilder();

                            MailMessage mail = new MailMessage();
                            mail.To = exInfo.contactEmail;
                            mail.From = ConfigurationSettings.AppSettings["genericFromMailAddress"];
                            mail.Subject = "New Reservation: " + exInfo.labClientName;

                            message.Append("A new reservation for " + exInfo.labClientName + " version: " + exInfo.labClientVersion);
                            message.AppendLine(" on " + exInfo.labServerName + " has been made.");
                            message.AppendLine("\tGroup: " + groupName + " ServiceBroker: " + serviceBrokerGuid);
                            message.Append("\tFrom: " + DateUtil.ToUserTime(startTime, CultureInfo.CurrentCulture, DateUtil.LocalTzOffset));
                            message.AppendLine("\t\tTo: " + DateUtil.ToUserTime(endTime, CultureInfo.CurrentCulture, DateUtil.LocalTzOffset));
                            message.AppendLine("\tDateFormat: " + CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + " \tUTC Offset: " + (DateUtil.LocalTzOffset / 60.0));
                            message.AppendLine();
                            mail.Body = message.ToString();
                            SmtpMail.SmtpServer = "127.0.0.1";

                            try
                            {
                                SmtpMail.Send(mail);
                            }
                            catch (Exception ex)
                            {
                                // Report detailed SMTP Errors
                                StringBuilder smtpErrorMsg = new StringBuilder();
                                smtpErrorMsg.Append("Exception: " + ex.Message);
                                //check the InnerException
                                if (ex.InnerException != null)
                                {
                                    smtpErrorMsg.Append("<br>Inner Exceptions:");
                                    while (ex.InnerException != null)
                                    {
                                        smtpErrorMsg.Append("<br>" + ex.InnerException.Message);
                                        ex = ex.InnerException;
                                    }
                                    Utilities.WriteLog(smtpErrorMsg.ToString());
                                }
                            }
                        }
                    }
                    else
                        notification = "Error: AddReservation status = " + status;
                    return notification;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return notification;
        }
コード例 #4
0
        public int MakeReservation(string serviceBrokerGuid, string groupName, string ussGuid,
            string labServerGuid, string clientGuid, DateTime startTime, DateTime endTime, ref StringBuilder notification)
        {
            int status = -1;
            Recurrence[] recurrences = GetRecurrences(serviceBrokerGuid, groupName,
                labServerGuid, clientGuid, startTime, endTime);
            if ((recurrences == null) || (recurrences.Length == 0))
            {
                notification.AppendLine("This experiment is not available to your group during this time.");
                return status;
            }
            else if (recurrences.Length > 1)
            {
                notification.Append("More than one recurrence was found for this request. Please choose another time.");
                return status;
            }

            else
            {
                TimeBlock[] reserved = ListReservationTimeBlocks(recurrences[0].resourceId, startTime, endTime);
                bool ok = true;
                if ((reserved != null) && (reserved.Length > 0))
                {

                    // Need to process the reservations to make suggestions
                    notification.AppendLine("This reservation time is not available now, please adjust your reservation time.");
                    TimeBlock check = new TimeBlock(startTime, endTime);
                    foreach (TimeBlock tb in reserved)
                    {
                        TimeBlock intersection = check.Intersection(tb);
                        if (intersection != null)
                        {
                            TimeSpan span = TimeSpan.FromSeconds(intersection.Duration);
                            if (intersection.Start < endTime)
                                notification.AppendLine(@"<br />Adjust the time by starting " + span.TotalMinutes +
                                    " minutes earlier, or make the duration shorter by " + span.TotalMinutes + " minutes.");
                            if (intersection.End > startTime)
                                notification.AppendLine(@"<br />Adjust the time by starting " + span.TotalMinutes +
                                    " minutes later.");

                        }

                    }
                    return 0;
                }
                //add the reservation to to reservationInfo table
                status = AddReservationInfo(serviceBrokerGuid, groupName, ussGuid, labServerGuid, clientGuid, recurrences[0].resourceId,startTime.ToUniversalTime(), endTime.ToUniversalTime(), 0);
            }
            return status;
        }
コード例 #5
0
ファイル: SchedulingControl.cs プロジェクト: tordf/iLabs
        protected override void PerformDataBinding(IEnumerable schedulingData)
        {
            // don't bind in design mode
            if (DesignMode)
            {
                return;
            }

            base.PerformDataBinding(schedulingData);

            // Verify data exists.
            if (schedulingData != null)
            {

                TimeSpan tmpTS;
                TimeSpan oneDay = TimeSpan.FromDays(1);
                maxTOD = TimeSpan.Zero.Subtract(TimeSpan.FromMinutes(userTZ));
                minTOD = oneDay;

                foreach (ITimeBlock tb in schedulingData)
                {
                    tmpTS = tb.Start.AddMinutes(userTZ).TimeOfDay;
                    if (minTOD > tmpTS)
                        minTOD = tmpTS;
                    tmpTS = tmpTS.Add(TimeSpan.FromSeconds(tb.Duration));
                    if (tmpTS.TotalHours < 24)
                    {
                        if (maxTOD < tmpTS)
                        {
                            maxTOD = tmpTS;
                        }
                    }
                    else if (tmpTS.TotalHours == 24)
                    {
                        maxTOD = tmpTS;
                    }
                    else
                    {
                        minTOD = TimeSpan.Zero;
                        maxTOD = TimeSpan.FromHours(24);
                        break;
                    }
                }
                if (bindReservations)
                { // should be Reservations
                    reservations = new List<Reservation>();
                    foreach (Reservation r in schedulingData)
                    {
                        reservations.Add(r);
                    }
                }
                else
                {  // should be TimePeriods
                    TimeBlock range = new TimeBlock(StartTime, EndTime);
                    periods = new List<TimePeriod>();
                    foreach (TimePeriod tp in schedulingData)
                    {
                        if(range.Contains(tp)){
                            periods.Add(tp);
                        }
                        else if (range.Intersects(tp))
                        {
                            TimeBlock tmpTB = range.Intersection(tp);
                            periods.Add(new TimePeriod(tmpTB.Start, tmpTB.Duration, tp.quantum));
                        }
                    }
                    TimeBlock[] scheduledTBs = TimeBlock.Remaining(new TimeBlock[] { range }, periods.ToArray());
                    if (scheduledTBs != null && scheduledTBs.Length > 0)
                    {
                        periods.AddRange(TimePeriod.MakeArray(scheduledTBs, 0));
                    }
                    periods.Sort();
                }
            }
            else
            {
                minTOD = TimeSpan.Zero;
                maxTOD = TimeSpan.FromHours(24);
                periods = new List<TimePeriod>();
                periods.Add(new TimePeriod(StartTime, EndTime, 0));
            }
        }
コード例 #6
0
 public static TimeBlock Union(ITimeBlock a, ITimeBlock b)
 {
     TimeBlock tb = null;
     if(TimeBlock.HasUnion(a,b))
         tb = new TimeBlock(a.Start <= b.Start ? a.Start : b.Start,a.End >= b.End ?a.End:b.End);
     return tb;
 }
コード例 #7
0
 public int Split(ITimeBlock subBlock, ref TimeBlock intersection, ref TimeBlock previous, ref TimeBlock remaining)
 {
     int status = 0;
     intersection = null;
     previous = null;
     remaining = null;
     if (Intersects(subBlock))
     {
         intersection = Intersection(subBlock);
         if (startTime < intersection.Start)
         {
             previous = new TimeBlock(startTime, intersection.Start);
             status |= 1;
         }
         else if (intersection.Start > subBlock.Start)
         {
             previous = new TimeBlock(subBlock.Start, intersection.Start);
             status |= 2;
         }
         if (End > intersection.End)
         {
             remaining = new TimeBlock(intersection.End, End);
             status |= 4;
         }
         else if (subBlock.End > intersection.End)
         {
             remaining = new TimeBlock(intersection.End, subBlock.End);
             status |= 8;
         }
     }
     return status;
 }
コード例 #8
0
ファイル: Recurrence.cs プロジェクト: tordf/iLabs
        public TimeBlock[] GetTimeBlocks(DateTime start, DateTime end)
        {
            // Bounds check
            if (start >= End || end <= Start)
            {
                return null;
            }

            List<TimeBlock> list = new List<TimeBlock>();
            TimeBlock range = new TimeBlock(start >= Start ? start : Start, end.Ticks <= End.Ticks ? end : End);
            if (recurrenceType == RecurrenceType.SingleBlock)
            {

                list.Add(range);
            }
            else
            {
                TimeSpan day = TimeSpan.FromDays(1.0);

                int dayOffset = Convert.ToInt32(start.Subtract(startDate).TotalDays);
                int endDay = Convert.ToInt32(end.Subtract(startDate).TotalDays);
                endDay = numDays <= endDay ? numDays : endDay;
                DateTime work = startDate.Add(TimeSpan.FromDays(dayOffset -1));
                DateTime eDate = startDate.Add(TimeSpan.FromDays(endDay +1));
                TimeBlock chunk = null;

                if (recurrenceType == RecurrenceType.Daily)
                {

                    while (work < eDate)
                    {
                        chunk = range.Intersection(new TimeBlock(work.Add(startOffset),work.Add(endOffset)));
                        if(chunk != null)
                            list.Add(chunk);
                        work = work.Add(day);
                    }
                }
                else if (recurrenceType == RecurrenceType.Weekly)
                {
                    while (work < eDate)
                    {
                        if (DateUtil.CheckDayMask(work.DayOfWeek, dayMask))
                        {
                            chunk = range.Intersection(new TimeBlock(work.Add(startOffset), work.Add(endOffset)));
                            if (chunk != null)
                                list.Add(chunk);
                        }
                        work = work.Add(day);
                    }
                }
            }
            return list.ToArray();
        }
コード例 #9
0
ファイル: Recurrence.cs プロジェクト: tordf/iLabs
        public TimeBlock[] GetTimeBlocks()
        {
            List<TimeBlock> list = new List<TimeBlock>();
            TimeBlock chunk = null;
            TimeSpan day = TimeSpan.FromDays(1.0);
            DateTime endDate = startDate.AddDays(numDays);
            switch ((RecurrenceType)recurrenceType)
            {
                case RecurrenceType.SingleBlock:
                    chunk = new TimeBlock(Start,Duration);
                    list.Add(chunk);
                    break;
                case RecurrenceType.Daily:
                    DateTime work = startDate.Add(startOffset);
                    for (int i = 0; i < numDays; i++)
                    {
                        chunk = new TimeBlock(work,(int) (endOffset - startOffset).TotalSeconds);
                        if(chunk.End <= endDate)
                            list.Add(chunk);
                        work = work.AddDays(1.0);
                    }
                    break;
                case RecurrenceType.Weekly:

                    DateTime wwork = startDate;
                    for (int i = 0; i < numDays; i++)
                    {
                        if (DateUtil.CheckDayMask(wwork.DayOfWeek, dayMask))
                        {
                            chunk = new TimeBlock();
                            chunk.startTime = wwork.Add(startOffset);
                            chunk.duration = (int) (endOffset - startOffset).TotalSeconds;
                            if(chunk.End <= endDate)
                                list.Add(chunk);
                        }
                        wwork = wwork.AddDays(1.0);
                    }
                    break;
                default:
                    break;
            }
            return list.ToArray();
        }
コード例 #10
0
        protected override void PerformDataBinding(IEnumerable schedulingData)
        {
            // don't bind in design mode
            if (DesignMode)
            {
                return;
            }
            base.PerformDataBinding(schedulingData);
            
            MinTOD = TimeSpan.Zero;
            MaxTOD = oneDay;
            // Verify data exists.
            if (schedulingData != null)
            {

                if (NumDays == 1)
                {
                    TimeSpan tmpTS;
                    TimeSpan tmpMinTOD = oneDay;

                    //Check the first timeBlock
                    IEnumerator eTB = schedulingData.GetEnumerator();
                    if (eTB.MoveNext())
                    {
                        tmpTS = (( TimeBlock)eTB.Current).Start.AddMinutes(userTZ).TimeOfDay;
                        if (tmpMinTOD > tmpTS)
                        {
                            tmpMinTOD = tmpTS;
                            MinTOD = tmpMinTOD;
                        }

                    }
                
                }
                if (bindReservations)
                { // should be Reservations
                    reservations = new List<Reservation>();
                    foreach (Reservation r in schedulingData)
                    {
                        reservations.Add(r);
                    }
                }
                else
                {  // should be TimePeriods
                    TimeBlock range = new TimeBlock(StartTime, EndTime);
                    periods = new List<TimePeriod>();
                    foreach (TimePeriod tp in schedulingData)
                    {
                        if(range.Contains(tp)){
                            periods.Add(tp);
                        }
                        else if (range.Intersects(tp))
                        {
                            TimeBlock tmpTB = range.Intersection(tp);
                            periods.Add(new TimePeriod(tmpTB.Start, tmpTB.Duration, tp.quantum));
                        }
                    }
                    TimeBlock[] scheduledTBs = TimeBlock.Remaining(new TimeBlock[] { range }, periods.ToArray());
                    if (scheduledTBs != null && scheduledTBs.Length > 0)
                    {
                        periods.AddRange(TimePeriod.MakeArray(scheduledTBs, 0));
                    }
                    periods.Sort();
                }
            }
            else
            {
                
                periods = new List<TimePeriod>();
                periods.Add(new TimePeriod(StartTime, EndTime, 0));
            }
        }
コード例 #11
0
        private int renderScheduledTime(HtmlTextWriter output,  ITimeBlock tb)
        {
            int duration = 0;
            if (tb.End < endOfDay)
                duration = tb.Duration;
            else
                duration = new TimeBlock(tb.Start, endOfDay).Duration;
            if (duration > 0)
            {
                output.Write("<tr>");
                int height = Convert.ToInt32((((hourHeight * duration) / 3600.0)));
                //output.AddAttribute("onclick", "javascript:" + Page.ClientScript.GetPostBackEventReference(this, startTime.ToString("s")));
#if useStyle
             output.AddStyleAttribute(HtmlTextWriterStyle.Padding, zero.ToString());
            output.AddStyleAttribute(HtmlTextWriterStyle.Margin, zero.ToString());
           output.AddStyleAttribute("background-color", ColorTranslator.ToHtml(scheduledColor));
            output.AddStyleAttribute("cursor", "hand");
            //output.AddStyleAttribute("border-bottom", "1px solid " + ColorTranslator.ToHtml(BorderColor));
#endif
                output.AddAttribute("class", reservedClass);
                output.AddStyleAttribute("height", adjustHeight(height) + "px");
                if (browserMode > 0)
                {
                    output.AddStyleAttribute("border-bottom", "1px solid " + ColorTranslator.ToHtml(BorderColor));
                    output.AddStyleAttribute("background-color", ColorTranslator.ToHtml(scheduledColor));
                }
                output.AddAttribute("title", tb.Start.AddMinutes(userTZ).TimeOfDay.ToString() + " - " + tb.End.AddMinutes(userTZ).ToString());
                output.RenderBeginTag("td");
                output.RenderEndTag();
                output.WriteLine("</tr>");
            }
            return duration;
        }
コード例 #12
0
 private void renderTimePeriods(HtmlTextWriter output, DateTime date, List<TimePeriod> periods)
 {
     TimeBlock validTime = new TimeBlock(date.AddHours((int)minTOD.Hours), endTime);
     TimeBlock valid;
     DateTime cur = DateTime.MinValue;
     DateTime end = DateTime.MinValue;
     if (periods != null && periods.Count >0)
     {
         try
         {
             TimePeriod first = periods[0];
             if (first.Start > validTime.Start)
             {
                 renderVoidTime(output, Convert.ToInt32((first.Start - validTime.Start).TotalSeconds));
             }
         }
         catch (Exception ex) {
             throw ex;
         }
         foreach (TimePeriod tp in periods)
         {
             if (validTime.Intersects(tp))
             {
                 valid = validTime.Intersection(tp);
                 cur = valid.Start;
                 end = valid.End;
                 if (tp.quantum == 0)
                 {
                     renderScheduledTime(output, valid);
                 }
                 else
                 {
                     int cellDur = 0;
                     int tDur = valid.Duration;
                     
                     while (cur < end && cur < endOfDay)
                     {
                         cellDur = defaultCellDuration -( cur.TimeOfDay.Minutes % defaultCellDuration);
                         if(cellDur < defaultCellDuration) 
                             cellDur += defaultCellDuration;
                         if ((end - cur.AddMinutes(cellDur)).TotalMinutes < (defaultCellDuration/2))
                         {
                             cellDur += Convert.ToInt32((end - cur.AddMinutes(cellDur)).TotalMinutes );
                         }
                         cellDur = (cur.AddMinutes(cellDur) <= endOfDay) ? cellDur : (int)(endOfDay - cur).TotalMinutes;
                         renderAvailableTime(output, cur, tDur, tp.quantum, cellDur * 60, false);
                         cur = cur.AddMinutes(cellDur);
                         tDur = tDur - (cellDur * 60);
                     }
                 }
             }
         } // End of foreach period
         if (end < endOfDay)
         {
             renderScheduledTime(output, new TimeBlock(end,endOfDay));
         }
     }
 }