Archive for February, 2014

It would appear that, when it comes to querying calendar events in SharePoint 2013, the CAML required does not seem to recognise <Now/> as its predecessors did.

To retrieve all future events in 2007 the CAML was as follows:

2007 Events CAML
  1. var query = new SPQuery
  2.                 {
  3.                     Query = @"<Where>
  4.                                  <DateRangesOverlap>
  5.                                     <FieldRef Name='EventDate'/>
  6.                                     <FieldRef Name='EndDate'/>
  7.                                     <FieldRef Name='RecurrenceID'/>
  8.                                     <Value IncludeTimeValue='TRUE' Type='DateTime'>
  9.                                         <Now/>
  10.                                     </Value>
  11.                                  </DateRangesOverlap>
  12.                               </Where>
  13.                               <OrderBy>          
  14.                                 <FieldRef Name='EventDate' Ascending='TRUE'/>      
  15.                               </OrderBy>",
  16.                     ExpandRecurrence = true,
  17.                     RowLimit = Convert.ToUInt32(this.ItemsToDisplay)
  18.                 };

However, when trying this in 2013, only the recurring events are returned.

To fix this,  amend the query as follows:

2013 Events CAML
  1. var query = new SPQuery
  2.                         {
  3.                             Query =
  4.                               string.Format(
  5.                                  @"<Where>
  6.                                   <Or>
  7.                                      <Geq>
  8.                                         <FieldRef Name='EventDate' />
  9.                                             <Value Type='DateTime'  IncludeTimeValue='TRUE'>{0}</Value>
  10.                                     </Geq>
  11.                                       <DateRangesOverlap>
  12.                                         <FieldRef Name='EventDate'/>
  13.                                         <FieldRef Name='EndDate'/>
  14.                                         <FieldRef Name='RecurrenceID'/>
  15.                                         <Value IncludeTimeValue='TRUE' Type='DateTime'><Now/></Value>
  16.                                      </DateRangesOverlap>
  17.                                 </Or>
  18.                               </Where>
  19.                               <OrderBy>          
  20.                                 <FieldRef Name='EventDate' Ascending='TRUE'/>      
  21.                               </OrderBy>",
  22.                                          DateTime.Now.ToCamlDateFormat()),
  23.                             ExpandRecurrence = Convert.ToBoolean(context[ContextKeys.IsRecurringIncluded]),
  24.                             RowLimit = Convert.ToUInt32(context[ContextKeys.ItemsToDisplay])
  25.                         };

 

Firstly, I tried to use the above query using <Now/> instead of the {0} parameter of string.Format, but the non-recurring events were not returned. It turns out that you need to use a Z format date for it to work. For this, I created an extension method of DateTime as follows:

ToCamDateFormat
  1. /// <summary>
  2.       /// To the CAML date format.
  3.       /// </summary>
  4.       /// <param name="dateToConvert">The date to convert.</param>
  5.       /// <returns>The date in the 2012-03-21T12:18:55Z format</returns>
  6.      public static string ToCamlDateFormat(this DateTime dateToConvert)
  7.      {
  8.          return dateToConvert.ToString("u").Replace(" ", "T");
  9.      }

Hope this saves you a few hours Smile