Back to Devexpress

FreeTimeCalculator Class

corelibraries-devexpress-dot-xtrascheduler-dot-tools.md

latest14.4 KB
Original Source

FreeTimeCalculator Class

Enables you to find available spare time intervals within the specified period.

Namespace : DevExpress.XtraScheduler.Tools

Assembly : DevExpress.XtraScheduler.v25.2.Core.Desktop.dll

NuGet Package : DevExpress.Scheduler.CoreDesktop

Declaration

csharp
public class FreeTimeCalculator :
    ITimeZoneHost
vb
Public Class FreeTimeCalculator
    Implements ITimeZoneHost

Remarks

The FreeTimeCalculator class enables you to find free time slots within the specified time interval. It can be helpful when searching for time periods suitable for a new meeting arrangement. The time interval can be queried based on a specific resource.

The FreeTimeCalculator.CalculateFreeTime method finds all available spare time intervals within the specified period of time. To find the nearest free slot with the specified duration, use the FreeTimeCalculator.FindFreeTimeInterval method. The search technique calculates the time in use based on the appointments currently contained within the Scheduler Storage. You can restrict the search to filtered appointments via the FreeTimeCalculator.ApplyAppointmentFilters property.

To find the spare time periods in work time only, so that holidays, night shifts and lunch hours are excluded, handle the FreeTimeCalculator.IntervalFound event. It gives you the flexibility to decide whether a particular free time slot satisfies your requirements. Use the TimeIntervalCollectionEx collection methods to modify the time intervals as needed.

The following code sample illustrates the implementation of the method used to find a free time slot which has a specified duration, or is longer than that, before the end of the current work week.

Example

The following code sample illustrates the implementation of the method used to find a free time slot which has a specified duration, or is longer than that, before the end of the current work week.

Note

A complete sample project is available at https://github.com/DevExpress-Examples/winforms-scheduler-find-free-time-intervals

csharp
using DevExpress.XtraScheduler;
using DevExpress.XtraScheduler.Tools;
using System;
using System.Windows.Forms;

namespace FreeTimeIntervals
{
    public partial class Form1 : Form {
        TimeZoneHelper timeZoneHelper;
        // Specify non-working time interval.
        TimeOfDayInterval nonWorkingTime = new TimeOfDayInterval(TimeSpan.FromHours(18), TimeSpan.FromDays(1) + TimeSpan.FromHours(9));

        internal TimeZoneHelper TimeZoneHelper { get { return timeZoneHelper; } }
        internal TimeOfDayInterval NonWorkingTime { get { return nonWorkingTime; } set { nonWorkingTime = value; } }

        public Form1() {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e) {
            // TODO: This line of code loads data into the 'xtraSchedulingDataSet1.Resources' table. You can move, or remove it, as needed.
            this.resourcesTableAdapter.Fill(this.xtraSchedulingDataSet1.Resources);
            // TODO: This line of code loads data into the 'xtraSchedulingDataSet.Appointments' table. You can move, or remove it, as needed.
            this.appointmentsTableAdapter.Fill(this.xtraSchedulingDataSet.Appointments);

            timeZoneHelper = new TimeZoneHelper(this.schedulerControl1.OptionsBehavior.ClientTimeZoneId);
        }

        private void button1_Click(object sender, EventArgs e) {
            TimeSpan duration = ((DateTime)slotDuration.EditValue).TimeOfDay;
            DateTime start = schedulerControl1.ActiveView.SelectedInterval.End;
            DateTime startOfWeek = DevExpress.XtraScheduler.Native.DateTimeHelper.GetStartOfWeek(start);
            TimeInterval interval = new TimeInterval(start, startOfWeek.AddDays(7));
            TimeInterval freeTime = FindInterval(interval, duration);
            string text;
            if (TimeInterval.Equals(freeTime, TimeInterval.Empty))
                text = "Not found";
            else {
                TimeInterval clientFreeInterval = TimeZoneHelper.ToClientTime(freeTime);
                text = "Free time interval with duration " + clientFreeInterval.Duration.ToString() +
                    " is found! \n\r It starts on " + clientFreeInterval.Start.Date.ToShortDateString() +
                    " at " + clientFreeInterval.Start.TimeOfDay.ToString() + ".";
                schedulerControl1.ActiveView.SetSelection(clientFreeInterval, ResourceEmpty.Resource);
            }
            MessageBox.Show(text, "Search Result", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        private TimeInterval FindInterval(TimeInterval clientInterval, TimeSpan duration) {
            FreeTimeCalculator calculator = new FreeTimeCalculator(schedulerControl1.Storage);
            // Set a handler for the IntervalFound event.
            calculator.IntervalFound += new IntervalFoundEventHandler(OnIntervalFound);
            TimeInterval interval = TimeZoneHelper.FromClientTime(clientInterval);
            // Call the method which raises the event.
            return calculator.FindFreeTimeInterval(interval, duration, true);
        }
        private void OnIntervalFound(object sender, IntervalFoundEventArgs args) {
            TimeIntervalCollectionEx freeIntervals = args.FreeIntervals;
            DateTime start = freeIntervals.Start.Date.AddDays(-1);
            DateTime end = freeIntervals.End;
            while (start < end) {
                RemoveNonWorkingTime(freeIntervals, start);
                RemoveNonWorkingDay(freeIntervals, start);
                start += TimeSpan.FromDays(1);
            }
        }
        private void RemoveNonWorkingTime(TimeIntervalCollectionEx freeIntervals, DateTime date) {
            DateTime clientDate = TimeZoneHelper.ToClientTime(date).Date;        

            TimeInterval clientNonWorkingTime = new TimeInterval(clientDate + NonWorkingTime.Start, clientDate + NonWorkingTime.End);
            freeIntervals.Remove(TimeZoneHelper.FromClientTime(clientNonWorkingTime));
        }
        private void RemoveNonWorkingDay(TimeIntervalCollectionEx freeIntervals, DateTime date) {
            DateTime clientDate = TimeZoneHelper.ToClientTime(date).Date;
            bool isWorkDay = schedulerControl1.WorkDays.IsWorkDay(clientDate);
            if (!isWorkDay) {
                TimeInterval clientInterval = new TimeInterval(clientDate, TimeSpan.FromDays(1));
                freeIntervals.Remove(TimeZoneHelper.FromClientTime(clientInterval));
            }
        }
        private void OnApptChangedInsertedDeleted(object sender, PersistentObjectsEventArgs e) {
            appointmentsTableAdapter.Update(xtraSchedulingDataSet);
            xtraSchedulingDataSet.AcceptChanges();
        }
    }
}
csharp
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace FreeTimeIntervals
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            DevExpress.Skins.SkinManager.EnableFormSkins();
            Application.Run(new Form1());
        }
    }
}
vb
Imports DevExpress.XtraScheduler
Imports DevExpress.XtraScheduler.Tools
Imports System
Imports System.Windows.Forms

Namespace FreeTimeIntervals
    Partial Public Class Form1
        Inherits Form

        Private timeZoneHelper_Renamed As TimeZoneHelper
        ' Specify non-working time interval.

        Private nonWorkingTime_Renamed As New TimeOfDayInterval(TimeSpan.FromHours(18), TimeSpan.FromDays(1).Add(TimeSpan.FromHours(9)))

        Friend ReadOnly Property TimeZoneHelper() As TimeZoneHelper
            Get
                Return timeZoneHelper_Renamed
            End Get
        End Property
        Friend Property NonWorkingTime() As TimeOfDayInterval
            Get
                Return nonWorkingTime_Renamed
            End Get
            Set(ByVal value As TimeOfDayInterval)
                nonWorkingTime_Renamed = value
            End Set
        End Property

        Public Sub New()
            InitializeComponent()
        End Sub
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
            ' TODO: This line of code loads data into the 'xtraSchedulingDataSet1.Resources' table. You can move, or remove it, as needed.
            Me.resourcesTableAdapter.Fill(Me.xtraSchedulingDataSet1.Resources)
            ' TODO: This line of code loads data into the 'xtraSchedulingDataSet.Appointments' table. You can move, or remove it, as needed.
            Me.appointmentsTableAdapter.Fill(Me.xtraSchedulingDataSet.Appointments)

            timeZoneHelper_Renamed = New TimeZoneHelper(Me.schedulerControl1.OptionsBehavior.ClientTimeZoneId)
        End Sub

        Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles button1.Click
            Dim duration As TimeSpan = CDate(slotDuration.EditValue).TimeOfDay
            Dim start As Date = schedulerControl1.ActiveView.SelectedInterval.End
            Dim startOfWeek As Date = DevExpress.XtraScheduler.Native.DateTimeHelper.GetStartOfWeek(start)
            Dim interval As New TimeInterval(start, startOfWeek.AddDays(7))
            Dim freeTime As TimeInterval = FindInterval(interval, duration)

            Dim text_Renamed As String
            If TimeInterval.Equals(freeTime, TimeInterval.Empty) Then
                text_Renamed = "Not found"
            Else
                Dim clientFreeInterval As TimeInterval = TimeZoneHelper.ToClientTime(freeTime)
                text_Renamed = "Free time interval with duration " & clientFreeInterval.Duration.ToString() & " is found! " & ControlChars.Lf & ControlChars.Cr & " It starts on " & clientFreeInterval.Start.Date.ToShortDateString() & " at " & clientFreeInterval.Start.TimeOfDay.ToString() & "."
                schedulerControl1.ActiveView.SetSelection(clientFreeInterval, ResourceEmpty.Resource)
            End If
            MessageBox.Show(text_Renamed, "Search Result", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End Sub
        Private Function FindInterval(ByVal clientInterval As TimeInterval, ByVal duration As TimeSpan) As TimeInterval
            Dim calculator As New FreeTimeCalculator(schedulerControl1.Storage)
            ' Set a handler for the IntervalFound event.
            AddHandler calculator.IntervalFound, AddressOf OnIntervalFound
            Dim interval As TimeInterval = TimeZoneHelper.FromClientTime(clientInterval)
            ' Call the method which raises the event.
            Return calculator.FindFreeTimeInterval(interval, duration, True)
        End Function
        Private Sub OnIntervalFound(ByVal sender As Object, ByVal args As IntervalFoundEventArgs)
            Dim freeIntervals As TimeIntervalCollectionEx = args.FreeIntervals
            Dim start As Date = freeIntervals.Start.Date.AddDays(-1)
            Dim [end] As Date = freeIntervals.End
            Do While start < [end]
                RemoveNonWorkingTime(freeIntervals, start)
                RemoveNonWorkingDay(freeIntervals, start)
                start = start.Add(TimeSpan.FromDays(1))
            Loop
        End Sub
        Private Sub RemoveNonWorkingTime(ByVal freeIntervals As TimeIntervalCollectionEx, ByVal [date] As Date)
            Dim clientDate As Date = TimeZoneHelper.ToClientTime([date]).Date

            Dim clientNonWorkingTime As New TimeInterval(clientDate + NonWorkingTime.Start, clientDate + NonWorkingTime.End)
            freeIntervals.Remove(TimeZoneHelper.FromClientTime(clientNonWorkingTime))
        End Sub
        Private Sub RemoveNonWorkingDay(ByVal freeIntervals As TimeIntervalCollectionEx, ByVal [date] As Date)
            Dim clientDate As Date = TimeZoneHelper.ToClientTime([date]).Date
            Dim isWorkDay As Boolean = schedulerControl1.WorkDays.IsWorkDay(clientDate)
            If Not isWorkDay Then
                Dim clientInterval As New TimeInterval(clientDate, TimeSpan.FromDays(1))
                freeIntervals.Remove(TimeZoneHelper.FromClientTime(clientInterval))
            End If
        End Sub
        Private Sub OnApptChangedInsertedDeleted(ByVal sender As Object, ByVal e As PersistentObjectsEventArgs) Handles schedulerStorage1.AppointmentsChanged, schedulerStorage1.AppointmentsInserted, schedulerStorage1.AppointmentsDeleted
            appointmentsTableAdapter.Update(xtraSchedulingDataSet)
            xtraSchedulingDataSet.AcceptChanges()
        End Sub
    End Class
End Namespace
vb
Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms

Namespace FreeTimeIntervals
    Friend NotInheritable Class Program

        Private Sub New()
        End Sub

        ''' <summary>
        ''' The main entry point for the application.
        ''' </summary>
        <STAThread> _
        Shared Sub Main()
            Application.EnableVisualStyles()
            Application.SetCompatibleTextRenderingDefault(False)
            DevExpress.Skins.SkinManager.EnableFormSkins()
            Application.Run(New Form1())
        End Sub
    End Class
End Namespace

Inheritance

Object FreeTimeCalculator

See Also

FreeTimeCalculator Members

DevExpress.XtraScheduler.Tools Namespace