web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Service | Customer Service, Contact Center, Fie...
Unanswered

Find non working hours from calendar

(0) ShareShare
ReportReport
Posted on by 205

Hello All,

I am trying to find business hours from the calendar and while i was exploring for options i did not find anything other than creating a custom workflow activity that queries the calendar and determining any holidays and weekends. I would like to really use a non code solution, is it possible?

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Workflow;
using System;
using System.Activities;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WorkHours
{

    public class CalculateBusinessHours : CodeActivity
    {
        [RequiredArgument]
        [Input("Start Date")]
        public InArgument StartDate { get; set; }

        [RequiredArgument]
        [Input("End Date")]
        public InArgument EndDate { get; set; }

        [RequiredArgument]
        [Input("Exclude Weekend?")]
        public InArgument ExcludeWeekend { get; set; }

        [RequiredArgument]
        [Input("Exclude Busines Closure")]
        public InArgument ExcludeBusinessClosure { get; set; }

        [Output("Minutes")]
        public OutArgument Minutes { get; set; }

        [Output("Hours")]
        public OutArgument Hours { get; set; }
        protected override void Execute(CodeActivityContext excontext)
        {
            IWorkflowContext context = excontext.GetExtension();
            IOrganizationServiceFactory factory = excontext.GetExtension();
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            List Closures = new List();

            Util helper = new Util();

            if (ExcludeBusinessClosure.Get(excontext))
            {
                Closures = helper.GetClosureConfig(service);
            }

            #region CalculateMinutes
            int TotalMinutes = CalculateMinutes(StartDate.Get(excontext), EndDate.Get(excontext), Closures, ExcludeWeekend.Get(excontext), 8, 30, 17, 0, service);
            decimal TotalHours = CalculateHours(TotalMinutes);
            Minutes.Set(excontext, TotalMinutes);
            Hours.Set(excontext, TotalHours);
            #endregion
        }

        private int CalculateMinutes(DateTime StartDate, DateTime EndDate, List ListClosure, bool ExcludeWeekend, int StartHours, int StartMinutes, int EndHours, int EndMinutes, IOrganizationService service)
        {
            #region Office Start/End Time
            TimeSpan OfficeStart = new TimeSpan(StartHours, StartMinutes, 0);
            TimeSpan OfficeEnd = new TimeSpan(EndHours, EndMinutes, 0);
            #endregion

            #region CalculateMinutes
            Util helper = new Util();

            //Converting Local time from UTC
            DateTime EDate = TimeConversionUtility.GetLocalTime(EndDate, service);
            DateTime SDate = TimeConversionUtility.GetLocalTime(StartDate, service);

            StartDate = SDate.AddSeconds(SDate.Second * -1);
            EndDate = EDate.AddSeconds(EDate.Second * -1);

            int TotalMinutes = 0;
            while (StartDate < EndDate)
            {
                bool IsDayAddRequired = true;
                #region Logic for calculating Minutes
                if (!helper.IsBusinessClosure(StartDate, ListClosure))
                {
                    if (ExcludeWeekend)
                    {
                        if (helper.IsInDaysConfigured(StartDate))
                        {
                            if (StartDate.TimeOfDay >= OfficeStart && StartDate.TimeOfDay <= OfficeEnd)
                            {
                                if (StartDate.Date == EndDate.Date)
                                {
                                    if (EndDate.TimeOfDay > OfficeEnd)
                                        EndDate = EndDate.Date.AddHours(EndHours).AddMinutes(EndMinutes);

                                    TimeSpan span = EndDate.Subtract(StartDate);
                                    TotalMinutes  = (int)span.TotalMinutes;
                                    //IsDayAddRequired = true;

                                    //Logic for subtracting Lunch break
                                    if (EndDate.TimeOfDay >= new TimeSpan(12, 30, 0) && StartDate.TimeOfDay <= new TimeSpan(12, 0, 0))
                                    {
                                        //Subtract Lunch
                                        TotalMinutes = TotalMinutes - 30;
                                    }
                                    else if (EndDate.TimeOfDay >= new TimeSpan(12, 0, 0) && EndDate.TimeOfDay <= new TimeSpan(12,30,0))
                                    {
                                        TotalMinutes = TotalMinutes - EndDate.Minute;
                                    }
                                    
                                }
                                else
                                {
                                    TimeSpan span = StartDate.Date.AddHours(EndHours).AddMinutes(EndMinutes).Subtract(StartDate);
                                    TotalMinutes  = (int)span.TotalMinutes;

                                    //Subtract Lunch break
                                    TotalMinutes = TotalMinutes - 30;
                                    //IsDayAddRequired = true;
                                }

                            }
                            else if (StartDate.TimeOfDay < OfficeStart)
                            {
                                StartDate = StartDate.Date.AddHours(StartHours).AddMinutes(StartMinutes);
                                IsDayAddRequired = false;
                            }
                        }
                    }
                    else
                    {
                        if (StartDate.TimeOfDay >= OfficeStart && StartDate.TimeOfDay <= OfficeEnd)
                        {
                            if (StartDate.Date == EndDate.Date)
                            {
                                TimeSpan span = EndDate.Subtract(StartDate);
                                TotalMinutes  = (int)span.TotalMinutes;
                                //IsDayAddRequired = true;
                            }
                            else
                            {
                                TimeSpan span = StartDate.Date.AddHours(EndHours).AddMinutes(EndMinutes).Subtract(StartDate);
                                TotalMinutes  = (int)span.TotalMinutes;
                                //IsDayAddRequired = true;
                            }

                        }
                        else if (StartDate.TimeOfDay < OfficeStart)
                        {
                            StartDate = StartDate.Date.AddHours(StartHours).AddMinutes(StartMinutes);
                            IsDayAddRequired = false;
                        }
                    }
                }
                #endregion
                if (IsDayAddRequired)
                    StartDate = StartDate.AddDays(1).Date.AddHours(StartHours).AddMinutes(StartMinutes);
            }
            return TotalMinutes;
            #endregion
        }

        private decimal CalculateHours(int TotalMinutes)
        {
            return (TotalMinutes / 60M);
        }
    }

    class Util
    {
        public bool IsInDaysConfigured(DateTime Dt)
        {
            bool IsValidForTheDay = false;

            switch (Dt.DayOfWeek)
            {
                case DayOfWeek.Sunday:
                    IsValidForTheDay = false;
                    break;
                case DayOfWeek.Monday:
                    IsValidForTheDay = true;
                    break;
                case DayOfWeek.Tuesday:
                    IsValidForTheDay = true;
                    break;
                case DayOfWeek.Wednesday:
                    IsValidForTheDay = true;
                    break;
                case DayOfWeek.Thursday:
                    IsValidForTheDay = true;
                    break;
                case DayOfWeek.Friday:
                    IsValidForTheDay = true;
                    break;
                case DayOfWeek.Saturday:
                    IsValidForTheDay = false;
                    break;
            }

            return IsValidForTheDay;
        }

        public bool IsBusinessClosure(DateTime Dt, List BusinessClosure)
        {
            bool IsBusinessClosure = false;

            foreach (ClosureConfig rule in BusinessClosure)
            {
                if (Dt >= rule.Start && Dt <= rule.End)
                {
                    IsBusinessClosure = true;
                }
            }

            return IsBusinessClosure;
        }
        public List GetClosureConfig(IOrganizationService service)
        {
            List list = new List();
            QueryByAttribute query = new QueryByAttribute();
            query.EntityName = "calendar";
            query.Attributes.Add("name");
            query.Values.Add("Business Closure Calendar");
            query.ColumnSet = new ColumnSet(true);

            EntityCollection collection = service.RetrieveMultiple(query);

            EntityCollection CalenderRules = collection.Entities[0].Attributes["calendarrules"] as EntityCollection;

            foreach (Entity Calender in CalenderRules.Entities)
            {
                if (Calender.Attributes.Contains("effectiveintervalend") && Calender.Attributes.Contains("effectiveintervalstart"))
                {
                    DateTime StartDate = (DateTime)Calender.Attributes["effectiveintervalstart"];
                    DateTime EndDate = (DateTime)Calender.Attributes["effectiveintervalend"];

                    list.Add(new ClosureConfig() { Start = StartDate, End = EndDate });
                }
            }

            return list;
        }

    }

    class ClosureConfig
    {
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
    }

}

I have the same question (0)
  • Community Member Profile Picture
    on at

    Hi Suresh_Satti,

    Unfortunately, there is no OOB way to do this. You could post an idea at here(experience.dynamics.com/.../) to progress this feature.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Meet the Microsoft Dynamics 365 Contact Center Champions

We are thrilled to have these Champions in our Community!

Congratulations to the April Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Service | Customer Service, Contact Center, Field Service, Guides

#1
FSRon Profile Picture

FSRon 75

#2
James White Profile Picture

James White 21

#3
AT-28040446-0 Profile Picture

AT-28040446-0 20

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans