Giter VIP home page Giter VIP logo

spcalendarrecurrenceexpander's People

Contributors

ronnieholm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

spcalendarrecurrenceexpander's Issues

String was not recognized as a valid Boolean when expanding

I'm trying to use the sample code in your repo's readme, but an error "String was not recognized as a valid Boolean" is thrown on line 37:

using Holm.SPCalendarRecurrenceExpander;
using Microsoft.SharePoint.Client;
using System;
using System.Linq;
using System.Net;
using System.Security;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var web = "...";
            var username = "...";
            var password = "...";
            var calendarTitle = "...";

            var ctx = new ClientContext(web);
            var securePassword = new SecureString();
            password.ToList().ForEach(securePassword.AppendChar);
            ctx.Credentials = new NetworkCredential(username, password);
            var calendar = ctx.Web.Lists.GetByTitle(calendarTitle);
            ctx.Load(ctx.Web.RegionalSettings.TimeZone);
            var tz = ctx.Web.RegionalSettings.TimeZone;
            ctx.ExecuteQuery();

            var query = new CamlQuery();
            var items = calendar.GetItems(query);
            ctx.Load(items);
            ctx.ExecuteQuery();

            var collapsedAppointments = items.ToList().Select(i => i.FieldValues).ToList();
            var expander = new CalendarRecurrenceExpander(
                tz.Information.Bias,
                tz.Information.DaylightBias);
            var recurrenceInstances = expander.Expand(collapsedAppointments);  // LINE 37 

            Func<RecurrenceInstance, Appointment> toDomainObject = (ri => {
                var a = collapsedAppointments.First(i => int.Parse(i["ID"].ToString()) == ri.Id);
                return new Appointment
                {
                    Id = ri.Id,
                    Title = (string)a["Title"],
                    Start = ri.Start,
                    End = ri.End
                };
            });

            var expandedAppointments = recurrenceInstances.Select(toDomainObject).ToList();
        }
    }

    class Appointment
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
        // add any custom columns here
    }
}

I've added a reference to SharePoint CSOM assemblies (Client and Client.Runtime) and FSharp.Core nuget package.

What else do I have to do? We have an on-premise SharePoint 2013.

Modified recurrence instance to whole day recurrence causes wrong expansion

  1. Create a whole day recurrence appointment from May 16, 2016 to May 18, 2016.
  2. Create an exception for May 18, 2016 such that it's no longer a whole day event, but starts at 10am and ends at 1pm.

The series still expands to:

Appointment10 5/16/2016 12:00 AM 5/16/2016 11:59 PM
Appointment10 5/17/2016 12:00 AM 5/17/2016 11:59 PM
Appointment10 5/18/2016 12:00 AM 5/18/2016 11:59 PM

The series ignores the May 18, 2016 exception because the original start time of the exception has been incorrectly timezone corrected from 12am to 2am (UTC+1 + DST). The expander therefore cannot relate original appointment to exception.

Suggestion: Provide optional start/end dates for expansion process

I suggest that the Expander optionally return only instances within a date range.

I find that my users like to create events that are perpetual, using the option "no end date". This is for a group that has monthly meetings in a predictable pattern. So first Monday at 7:00pm, forever.

The result when expanding this type of series is one appointment a month from the start of the series out to the year 2098. That is a lot of Instances (about 900 per appointment) that are way out of range of any normal calendar.

If the Expander took optional start and end parameters, then it could save a lot of processing. Albeit not really a huge amount of time or memory since RecurrenceInstance is a very lightweight object. But that leads me to another suggestion. But rather than muddle the two suggestions together here, I will offer that suggestion separately.

-TrailBear
Frank Long

Column with "Person or Group" and multiselect

First let me preface this with this is SO amazing but I just had one issue come up and I have the field set to allow multiple people but I can't seem to pull back the lookup values with this.

I am basically trying to get the "Participants" field expanded to have the user's email.

this is my code:
` List expandedAppointments = new List();

        using (var cc = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, appId, appSecret))
        {
            cc.Load(cc.Web, p => p.Title);
            cc.Load(cc.Web.Lists);
            cc.Load(cc.Web.RegionalSettings.TimeZone);
            cc.ExecuteQuery();

            ViewBag.test = cc.Web.Title;

            var tz = cc.Web.RegionalSettings.TimeZone;

            foreach (var list in cc.Web.Lists.Where(e => e.Title == listName))
            {
                if (list.Title == listName)
                {
                    ViewBag.test = list.Title;
                    CamlQuery cQuery = new CamlQuery();

                    ListItemCollection colListItem = list.GetItems(cQuery);
                    cc.Load(colListItem);
                    cc.ExecuteQuery();

                    var collapsedAppointments = colListItem.ToList().Select(i => i.FieldValues).ToList();
                    var expander = new CalendarRecurrenceExpander(
                            tz.Information.Bias,
                            tz.Information.DaylightBias
                        );

                    

                    var recurrenceInstances = expander.Expand(collapsedAppointments);

                    Func<RecurrenceInstance, Appointment> toDomainObject = (ri => {
                        var a = collapsedAppointments.First(i => int.Parse(i["ID"].ToString()) == ri.Id);
                        return new Appointment
                        {
                            Id = ri.Id,
                            Title = (string)a["Title"],
                            Start = ri.Start,
                            Category = (string)a["Category"],
                            End = ri.End,
                            Start_string = ri.Start.ToLongDateString(),
                            End_string = ri.End.ToLongDateString(),
                        };
                    });

                    expandedAppointments = recurrenceInstances.Select(toDomainObject).Where(e => e.Start >= DateTime.Now).ToList();
                    return Json(collapsedAppointments, JsonRequestBehavior.AllowGet);
                    //ViewBag.test = expandedAppointments.Count();
                }
            }
        };

        return Json(expandedAppointments, JsonRequestBehavior.AllowGet);`

But how do I add the "Person or Group" field with their email and not IDs?

'Unable to Parse end' error while calling expander.Expand

Description

I am facing this error while calling expander.Expand. i was able to zero down to the records which are causing this issue, however i am unable to identify the fields in records which are causing this. here is the raw data of one such record causing this issue. Can you help me identify the root cause?

Record data

  • |   | [0] | {[ContentTypeId, 0x0102004B17F3AE6037154AB1D979F750727D03]} | System.Collections.Generic.KeyValuePair<string, object>
    -- | -- | -- | -- | --
  • |   | [1] | {[Title, Quarterly review of Site Assignment document]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [2] | {[_ModerationComments, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [3] | {[File_x0020_Type, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [4] | {[Location, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [5] | {[EventDate, 11/1/2016 4:00:00 PM]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [6] | {[EndDate, 11/1/2016 5:00:00 PM]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [7] | {[Description, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [8] | {[fAllDayEvent, False]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [9] | {[fRecurrence, True]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [10] | {[WorkspaceLink, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [11] | {[EventType, 1]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [12] | {[UID, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [13] | {[RecurrenceID, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [14] | {[EventCanceled, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [15] | {[Duration, 3600]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [16] | {[RecurrenceData, Every 3 month(s) on the first Tuesday]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [17] | {[TimeZone, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [18] | {[XMLTZone, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [19] | {[MasterSeriesItemID, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [20] | {[Workspace, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [21] | {[ParticipantsPicker, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [22] | {[Category, (2) Category2]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [23] | {[FreeBusy, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [24] | {[Overbook, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [25] | {[Participants, ]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [26] | {[_x0025__x0020_Complete, 0]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [27] | {[Assigned_x0020_To, Microsoft.SharePoint.Client.FieldUserValue[]]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [28] | {[Escalation, False]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [29] | {[Status, Not Started]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [30] | {[Reports_x0020_To, Microsoft.SharePoint.Client.FieldUserValue]} | System.Collections.Generic.KeyValuePair<string, object>
  • |   | [31] | {[Actions,
    Go to:
    |   |   |   |   |   |  
 
|   |   |   |   |   |   |   |   |   |   |   |   |   |  
 
|   |   |   |   |   |   |   |  
Review FTEs and Vendors assigned to each site and update as appropriate.
|   |   |   |   |   |  
 
|   |   |   |   |   |   |   |  
To update send an email with required changes to [email protected] and cc Ujwal
]} | System.Collections.Generic.KeyValuePair |   |   |   |   |   |   + |   | [32] | {[Related_x0020_To, N/A]} | System.Collections.Generic.KeyValuePair + |   | [33] | {[ID, 9804]} | System.Collections.Generic.KeyValuePair + |   | [34] | {[Modified, 6/28/2017 11:35:39 AM]} | System.Collections.Generic.KeyValuePair + |   | [35] | {[Created, 6/27/2017 6:27:53 PM]} | System.Collections.Generic.KeyValuePair + |   | [36] | {[Author, Microsoft.SharePoint.Client.FieldUserValue]} | System.Collections.Generic.KeyValuePair + |   | [37] | {[Editor, Microsoft.SharePoint.Client.FieldUserValue]} | System.Collections.Generic.KeyValuePair + |   | [38] | {[_HasCopyDestinations, ]} | System.Collections.Generic.KeyValuePair + |   | [39] | {[_CopySource, ]} | System.Collections.Generic.KeyValuePair + |   | [40] | {[owshiddenversion, 3]} | System.Collections.Generic.KeyValuePair + |   | [41] | {[WorkflowVersion, 1]} | System.Collections.Generic.KeyValuePair + |   | [42] | {[_UIVersion, 512]} | System.Collections.Generic.KeyValuePair + |   | [43] | {[_UIVersionString, 1.0]} | System.Collections.Generic.KeyValuePair + |   | [44] | {[Attachments, False]} | System.Collections.Generic.KeyValuePair + |   | [45] | {[_ModerationStatus, 0]} | System.Collections.Generic.KeyValuePair + |   | [46] | {[InstanceID, ]} | System.Collections.Generic.KeyValuePair + |   | [47] | {[Order, 980400]} | System.Collections.Generic.KeyValuePair + |   | [48] | {[GUID, 1628ce93-e57f-48bd-b1d7-79dde939d9bc]} | System.Collections.Generic.KeyValuePair + |   | [49] | {[WorkflowInstanceID, ]} | System.Collections.Generic.KeyValuePair + |   | [50] | {[FileRef, /teams/physsec/Lists/RoB Tasks/9804_.000]} | System.Collections.Generic.KeyValuePair + |   | [51] | {[FileDirRef, /teams/physsec/Lists/RoB Tasks]} | System.Collections.Generic.KeyValuePair + |   | [52] | {[Last_x0020_Modified, 2017-06-27T18:27:53Z]} | System.Collections.Generic.KeyValuePair + |   | [53] | {[Created_x0020_Date, 2017-06-27T18:27:53Z]} | System.Collections.Generic.KeyValuePair + |   | [54] | {[FSObjType, 0]} | System.Collections.Generic.KeyValuePair + |   | [55] | {[SortBehavior, Microsoft.SharePoint.Client.FieldLookupValue]} | System.Collections.Generic.KeyValuePair + |   | [56] | {[FileLeafRef, 9804_.000]} | System.Collections.Generic.KeyValuePair + |   | [57] | {[UniqueId, deee7386-6e54-482c-b96a-52c29d0d185b]} | System.Collections.Generic.KeyValuePair + |   | [58] | {[SyncClientId, Microsoft.SharePoint.Client.FieldLookupValue]} | System.Collections.Generic.KeyValuePair + |   | [59] | {[ProgId, ]} | System.Collections.Generic.KeyValuePair + |   | [60] | {[ScopeId, {6EA468AC-9BDE-4114-A10E-259D7BA33B65}]} | System.Collections.Generic.KeyValuePair + |   | [61] | {[MetaInfo, ]} | System.Collections.Generic.KeyValuePair + |   | [62] | {[_Level, 1]} | System.Collections.Generic.KeyValuePair + |   | [63] | {[_IsCurrentVersion, True]} | System.Collections.Generic.KeyValuePair + |   | [64] | {[ItemChildCount, 0]} | System.Collections.Generic.KeyValuePair + |   | [65] | {[FolderChildCount, 0]} | System.Collections.Generic.KeyValuePair + |   | [66] | {[Restricted, ]} | System.Collections.Generic.KeyValuePair + |   | [67] | {[OriginatorId, ]} | System.Collections.Generic.KeyValuePair + |   | [68] | {[NoExecute, 0]} | System.Collections.Generic.KeyValuePair + |   | [69] | {[ContentVersion, 0]} | System.Collections.Generic.KeyValuePair + |   | [70] | {[_ComplianceFlags, ]} | System.Collections.Generic.KeyValuePair + |   | [71] | {[_ComplianceTag, ]} | System.Collections.Generic.KeyValuePair + |   | [72] | {[_ComplianceTagWrittenTime, ]} | System.Collections.Generic.KeyValuePair + |   | [73] | {[_ComplianceTagUserId, ]} | System.Collections.Generic.KeyValuePair + |   | [74] | {[AccessPolicy, ]} | System.Collections.Generic.KeyValuePair + |   | [75] | {[_VirusStatus, ]} | System.Collections.Generic.KeyValuePair + |   | [76] | {[_VirusVendorID, ]} | System.Collections.Generic.KeyValuePair + |   | [77] | {[_VirusInfo, ]} | System.Collections.Generic.KeyValuePair + |   | [78] | {[AppAuthor, ]} | System.Collections.Generic.KeyValuePair + |   | [79] | {[AppEditor, ]} | System.Collections.Generic.KeyValuePair + |   | [80] | {[SMTotalSize, Microsoft.SharePoint.Client.FieldLookupValue]} | System.Collections.Generic.KeyValuePair + |   | [81] | {[SMLastModifiedDate, 2017-06-28T11:35:39Z]} | System.Collections.Generic.KeyValuePair + |   | [82] | {[SMTotalFileStreamSize, 0]} | System.Collections.Generic.KeyValuePair + |   | [83] | {[SMTotalFileCount, Microsoft.SharePoint.Client.FieldLookupValue]} | System.Collections.Generic.KeyValuePair

Stack Trace for the Error

at Microsoft.FSharp.Core.Operators.FailWith[T](String message)
at Holm.SPCalendarRecurrenceExpander.Parser.parseRecurrence(Dictionary2 d) in C:\Users\rh\Source\Repos\SPCalendarRecurrenceExpander\Src\SPCalendarRecurrenceExpander\Parser.fs:line 209 at Holm.SPCalendarRecurrenceExpander.Parser.parse(Dictionary2 a) in C:\Users\rh\Source\Repos\SPCalendarRecurrenceExpander\Src\SPCalendarRecurrenceExpander\Parser.fs:line 223
at Holm.SPCalendarRecurrenceExpander.Parser.Parse(Dictionary2 appointment) in C:\Users\rh\Source\Repos\SPCalendarRecurrenceExpander\Src\SPCalendarRecurrenceExpander\Parser.fs:line 230 at <StartupCode$SPCalendarRecurrenceExpander>[email protected](Dictionary2 a) in C:\Users\rh\Source\Repos\SPCalendarRecurrenceExpander\Src\SPCalendarRecurrenceExpander\Expander.fs:line 40
at Microsoft.FSharp.Primitives.Basics.List.map[T,TResult](FSharpFunc2 mapping, FSharpList1 x)
at Microsoft.FSharp.Collections.ListModule.Map[T,TResult](FSharpFunc2 mapping, FSharpList1 list)
at Holm.SPCalendarRecurrenceExpander.CalendarRecurrenceExpander.Expand(List`1 appointments) in C:\Users\rh\Source\Repos\SPCalendarRecurrenceExpander\Src\SPCalendarRecurrenceExpander\Expander.fs:line 36
at RoBDailyReminderSMTP.Program.SendEmail(ListItemCollection listItemColl) in F:\TFS\SPO Migration\Build\Solutions\RoBDailyReminder -SMTP EMAIL\RoBDailyReminder\Program.cs:line 236

Weekly Recurring event with more then 1 recur week fetching wrong data

cal1

I have create one recurring event with recur every 2 week.I have attach screen shot.
So as per event it should get event one after another sunday. like if first event is on 6/5/2018 then second event should be 20/5/2018 and so on.

But it is getting event for every sunday.

Recurrence Data is given below.
<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat><weekly su="TRUE" weekFrequency="2" /></repeat><repeatInstances>10</repeatInstances></rule></recurrence>

Is this a bug or is there any other way to get weekly recur event?

Thanks

unknown recurrence

Hello,

I get the error 'Unknown recurrence'. I think this is what is causing the issue:

su2016-07-17T06:59:00Z

Any ideas?

Thanks,
Mike

DateTime fields parsed as culture specific strings sometimes leading to format exception

Hi,

I am facing below Format Exception error

My System setting is in "dd/MM/yyyy" format but parser.fs code is throwing error:

This is not working even we passed the date format in "MM/dd/yyyy" format.

"An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll
Additional information: String was not recognized as a valid DateTime"

But when I changed the system date/time format to "MM/dd/yyyy", it is working fine.

We want to pass the date time in standard format i.e "dd/MM/yyyy"

Please suggest.

toLocalDateTime does not appear to be aware of daylight time boundaries?

Apologies if I've read the code wrong, but I think there may be an issue with daylight time during expansion.

In Expander.fs on lines 9 and 10, the code appears to use the same daylight bias value regardless of the date it is processing. I think this means that if a series has instances both during standard time and during daylight time, then some will have the incorrect bias applied.

The current bias changes as time progresses out of standard time into daylight time and vice versa. So the bias that is correct for dates in the same period is incorrect for dates in the opposite period. So typically expanded times are correct before the boundary date and incorrect after, but if you look far enough ahead you will see the times are correct again as you pass the next transition. So now, as you approach and pass into the next period of the year, this would reverse, and the times that appeared wrong before would suddenly be correct. But looking far into the future, the ones that were correct would be wrong now. So the test case needs to look at two instances, one on each side of a standard/daylight boundary, but not both in the same type of period, and ensure that the correct bias is applied such that their properties have the same time of day.

The good news...
It seems you can avoid passing in the bias entirely, because SharePoint is already including it for every appointment. The property I see has the key XMLTZone and its value seems to contain all the information needed to make an informed decision about whether daylight time is active.

Here is a sample of the contents of the value for that key:

<timeZoneRule>
    <standardBias>480</standardBias>
    <additionalDaylightBias>-60</additionalDaylightBias>
    <standardDate>
        <transitionRule weekdayOfMonth="first" day="su" month="11"/>
        <transitionTime>2:0:0</transitionTime>
    </standardDate>
    <daylightDate>
        <transitionRule weekdayOfMonth="second" day="su" month="3"/>
        <transitionTime>2:0:0</transitionTime>
    </daylightDate>
</timeZoneRule>

I wonder if using System.TimeZoneInfo.CreateCustomTimeZone in conjunction with this would be an approach that could save some code? https://msdn.microsoft.com/en-us/library/bb381969(v=vs.110).aspx

I'm not sure if the XMLTZone can be different for appointments in the same list, but you could at least avoid having to pass this value in the parameters. And if you reference the property value from each master appointment as you process it you could preemptively avoid the unknown case where it is different for two series in the same list.

And thanks for the work on this project!

-Respectfully
Trailbear (Frank Long)

Properties other than Start and End Date not available

in continuation with #15 , I found that while iterating events in a recurring series, field values like Status, % complete etc. are not retrieved correctly( I always get 0% complete and not started, same values as parent series item).

it seems the changes made for individual events inside a recurring event are not captured and values retrieved are those of recurring event series.

Pulling back data from list gives "System.Exception: 'a.start and a.end'

So if I run:

`
using (var cc = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, appId, appSecret))
{
cc.Load(cc.Web, p => p.Title);
cc.Load(cc.Web.Lists);
cc.Load(cc.Web.RegionalSettings.TimeZone);
cc.ExecuteQuery();

            var tz = cc.Web.RegionalSettings.TimeZone;
            foreach (var list in cc.Web.Lists.Where(e => e.Title == "My Calendar"))
            {
                CamlQuery cQuery = new CamlQuery();

                ListItemCollection colListItem = list.GetItems(cQuery);
                cc.Load(colListItem);
                cc.ExecuteQuery();

                var collapsedAppointments = colListItem.ToList().Select(i => i.FieldValues).ToList();
                var expander = new CalendarRecurrenceExpander(
                        tz.Information.Bias,
                        tz.Information.DaylightBias
                    );

            }

            //ViewBag.test = derp;
        };
        return View();`

it works but the minute I go to expand it using:

var recurrenceInstances = expander.Expand(collapsedAppointments);

I get the error "System.Exception:'a.start and a.end'"

testing uncovered exception in a Daily recurrence

With my testing, when you create a Daily recurrence event with certain conditions, you get an F3 exception in the find method.

The certain conditions are:

  1. Daily recurrence has to be every weekday and
  2. the event must stretch across 1 or more months

The exception happens at the call:
Find[T]
nextWeekDay (Compiler.fs line 98)

I am using SharePoint 2010 and CSOM to collect the calendar event. Once I pass this to the SPCalendarRecurrenceExpander - I get the exception.

Date Time Parse

Dear Ronnieholm,

I'm trying to use your assembly, however, in the code line:

var recurrenceInstances = expander.Expand(collapsedAppointments);

I got a "FormatException; this string was not recognized as a valid DateTime" error.

I already tested the regional settings with Central America and US and Canada, creating a new site collection, and the error still shows up.

I used your example and one of my own and both throws the same error. I saw another similar issue where you stated that error never happened to you, maybe I'm missing something?

I hope you could help me

Thank you, best regards

Incorrect start and end time of event for date not in daylight saving range

The start and end time of an event is incorrect for dates not in the daylight saving range.

To reproduce:

  1. Create a web with Regional Settings set as follows

    Time zone: UTC-08:00 Pacific Time (US and Canada)
    Locale: English (United States)

  2. Create a recurring appointment every day for five days starting Jan 5, 2017 from 6pm to 8pm. The expanded events are as follows:

    3 Test 1/5/2017 7:00 PM 1/5/2017 9:00 PM
    3 Test 1/6/2017 7:00 PM 1/6/2017 9:00 PM
    3 Test 1/7/2017 7:00 PM 1/7/2017 9:00 PM
    3 Test 1/8/2017 7:00 PM 1/8/2017 9:00 PM
    3 Test 1/9/2017 7:00 PM 1/9/2017 9:00 PM

Observe how start and end time is off by one hour.

Looking at ctx.Web.RegionalSettings.TimeZone.Information.Bias, it holds the following values:

Bias: 480
DaylightBias: -60
StandardBias: 0

The expander always applies DaylightBias. When daylight saving time isn't in effect, it should apply StandardBias instead. Determining when to apply daylight saving time can be inferred from the XMLTimeZone field value:

<timeZoneRule>
    <standardBias>480</standardBias>
    <additionalDaylightBias>-60</additionalDaylightBias>
    <standardDate>
        <transitionRule  month='11' day='su' weekdayOfMonth='first' />
        <transitionTime>2:0:0</transitionTime>
    </standardDate>
    <daylightDate><transitionRule  month='3' day='su' weekdayOfMonth='second' />
        <transitionTime>2:0:0</transitionTime>
    </daylightDate>
</timeZoneRule>

For non-recurring events, however, SharePoint doesn't set this field.

Scenario: Accessing FieldValues for Recurrence Exceptions is straightforward

In the example code, the FieldValues Dictionary used to populate the title is always the first or master appointment. The expander applies date updates appropriately. However other properties can be altered in the user interface, not to mention custom columns (we have a couple). To maintain these edits the code needs to access the values from the exception appointment as opposed to the series master appointment.

It seems like there should be a way to find the exception appointment for a given instance's ID and date, if one exists, and use that appointment instead of the master. But I am unsure how to code this in a lambda function. I have a feeling that it would end up being a bit cryptic in any case. Seemingly a good candidate for putting that logic into the assembly if everyone will end up having to do it.

If there is no limit on how many instances are created and there are no exceptions, then copying the rather weighty dictionary onto the instance before converting to a domain object seems wasteful. However where start and end dates are provided (Issue #4), the number of instances won't be any larger than a properly expanded result set from SharePoint.

My initial preference was to see the FieldValues dictionary added to each RecurrenceInstance. By providing the entire dictionary any custom columns are maintained along with changes that may be part of the exception appointment. If it is on every Instance, the process of converting to a domain object becomes a simple mapping exercise.

-TrailBear
Frank Long

URL of expanded items missing

I am unable to retrieve the URL of expanded events. 'FileRef' property gives URL of the Series and not individual events. How to get the URL for each occurrence?

The string was not recognized as a valid DateTime.

Dear Ronnieholm,
we test your project with the example code against a sharepoint online calendar.
We have german local settings.
on the code row " var recurrenceInstances = expander.Expand(collapsedAppointments);"
we get a FormatException; this string was not recognized as a valid DateTime.
In debug mode we found our problem.
with german local settings sharepoint use the date time format dd.mm.yyyy
you use mm/dd/yyyy so we get a problem with all days greater then 12.

So you have a new improvement proposal: Please regard local date formats in your next Version

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.