Hi,
I am trying to check whether particular date/hour falls in holidays list or calendar rules.
I am able to retrieve calendar rules, but not sure how to check for the above mentioned rule. This below calender observes holidays list as well.
QueryExpression query = new QueryExpression("calendar");
query.ColumnSet = new ColumnSet(true);
query.Criteria.AddCondition("name", ConditionOperator.Equal, "Test");
EntityCollection TestCalender = service.RetrieveMultiple(query);
EntityCollection testcalendarrules = TestCalender .Entities[0].GetAttributeValue<EntityCollection>("calendarrules");
Datetime dt=datetime.now;
foreach(rule in calender rule)
{
check whether datetime falls in this.
}
*This post is locked for comments
Thanks for the response. But my scenario is if the datetime is not with in the calendar hours,
increase the hour by 1 and check or it can be set to the next working day starttime.
Hi there
I met this requirement in a plugin using these techniques
1. For the main calendar used the ExpandCalendarRequest message. It returns a list of timeslots within a specified time period docs.microsoft.com/.../gg307974(v=crm.8)
2. For the linked holiday calendar I queried the calendar entity joined to the calendarrule entity. This is because the holiday calendar behaved different to normal calendars
Here are several methods copied from a plugin project which may help. Note I haven't included the timezone conversion code in LocalisationServicebut I think it covers how to do it for the most part
public bool IsWithinCalendarHours(Guid calendarId, DateTime dateTime, int yesIfUpToMinutesAfter = 0)
{
var req = new ExpandCalendarRequest()
{
CalendarId = calendarId,
Start = dateTime.AddMinutes(-1 * yesIfUpToMinutesAfter).ToUniversalTime(),
End = dateTime.ToUniversalTime()
};
var response = (ExpandCalendarResponse)XrmService.Execute(req);
var isWithinCalendar = false;
foreach (var timeSlot in response.result)
{
if (dateTime.ToUniversalTime() >= timeSlot.Start && dateTime.AddMinutes(-1 * yesIfUpToMinutesAfter).ToUniversalTime() <= timeSlot.End)
isWithinCalendar = true;
}
if (isWithinCalendar)
{
isWithinCalendar = !IsPublicHoliday(calendarId, dateTime);
}
return isWithinCalendar;
}
private bool IsPublicHoliday(Guid calendarId, DateTime dateTime)
{
var isPublicHoliday = false;
//public holiday dates are returned as utc
//however we want to compare it for the actual local time
//so lets create datetimes as the local time, but fake it as utc for the comparison
var vicDateTime = LocalisationService.ConvertToTargetTime(dateTime);
var myStart = new DateTime(vicDateTime.Year, vicDateTime.Month, vicDateTime.Day, vicDateTime.Hour, vicDateTime.Minute, vicDateTime.Second, DateTimeKind.Utc);
var myEnd = new DateTime(vicDateTime.Year, vicDateTime.Month, vicDateTime.Day, vicDateTime.Hour, vicDateTime.Minute, vicDateTime.Second, DateTimeKind.Utc);
var query = new QueryExpression("calendar");
query.Criteria.AddCondition(new ConditionExpression("calendarid", ConditionOperator.Equal, calendarId));
var join1 = query.AddLink("calendar", "holidayschedulecalendarid", "calendarid");
var join2 = join1.AddLink("calendarrule", "calendarid", "calendarid");
join2.EntityAlias = "CR";
join2.Columns = new ColumnSet("starttime", "effectiveintervalend");
join2.LinkCriteria.AddCondition(new ConditionExpression("starttime", ConditionOperator.LessEqual, myStart));
join2.LinkCriteria.AddCondition(new ConditionExpression("effectiveintervalend", ConditionOperator.GreaterThan, myStart));
var publicHolidays = XrmService.RetrieveAll(query);
foreach (var holiday in publicHolidays)
{
var start = (DateTime?)((AliasedValue)holiday["CR." + "starttime"]).Value;
var end = (DateTime?)((AliasedValue)holiday["CR." + "effectiveintervalend"]).Value;
if (start <= myStart && end > myEnd)
isPublicHoliday = true;
}
return isPublicHoliday;
}
Mohamed Amine Mahmoudi
83
Super User 2025 Season 1
Community Member
52
Victor Onyebuchi
6