SharePoint - 全天事件在CAML查询中的行为不同

时间:2009-10-05 15:04:14

标签: sharepoint

在SharePoint日历列表中,我创建了两个具有今天日期的事件。一个是全天活动,另一个我将开始时间设置为上午12点,结束时间设置为晚上11:55。

当我创建一个CAML查询(在这种情况下是w /“U2U CAML Query Builder”)时,我看到了一些奇怪的行为。当我的查询是一个简单的“OrderBy”时,都返回两个事件。

当我执行以下查询以搜索大于或等于今天的事件时,仅返回标记为“全天事件”的 NOT 事件:

<Where>
    <Geq>
        <FieldRef Name='EventDate' />
        <Value Type='DateTime'>2009-10-05T00:00:00Z</Value>
    </Geq>
</Where>

检查查询构建器工具的结果我看到EventDate的值(“开始时间”列的内部名称)是相同的(2009-10-05 00:00:00)。

为什么SharePoint会同样对待这两个事件?这可能是时区问题吗?

编辑:更多信息,我认为这可能是一个时区问题。我发现了Value元素的“IncludeTimeValue”属性 - 在此描述:MSDN。我在东海岸(目前是GMT - 4小时)。如果我按如下方式编辑Value元素:(注意日期现在是第4个,而不是第5个)

<Value Type='DateTime' IncludeTimeValue='True'>2009-10-04T20:00:00Z</Value>

然后返回两个事件,但如果我上升到20:01那么我将失去全天的事件。当我去20:01时,我也失去了全天活动。有谁知道我在哪里可以找到这种行为的详尽描述?

编辑:我弄糊涂了自己;纠正了第一次编辑。

4 个答案:

答案 0 :(得分:7)

SharePoint以UTC(也称为GMT或Zulu)存储日期/时间,并在显示时首先将其转换为网站本地时区。

但是对于全天活动,它会将时间(00:00到23:59:00)存储在站点LOCAL时区中。

正如您已经想到的那样 - 我相信您发现了SharePoint解释查询的方式存在错误,并且忘记了整天的活动都是当地时间。

我猜你可以通过查询

来做一个讨厌的解决方法

EventDate&gt; = SomeDate 要么 AllDayEvent = True AND EventDate&gt; = SomeDate - 4hrs

这张海报有类似的问题 SO - SharePoint all day event gives obscure result

这将让您更深入地了解SharePoint中的时区是如何进行的 SharePoint Web Services and UTC time fun and games

如果这对你来说不够沮丧,那么请通过对象模型查看创建/修改日期,并惊叹于它们如何被报告为正常事件的本地时间和全天事件的UTC!

答案 1 :(得分:1)

oQuery.Query = "<Where><Geq><FieldRef Name='EventDate' /><Value Type='DateTime'>" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Today.Subtract(new TimeSpan(1))) + "</Value></Geq></Where>"

添加Timespan值,如:

SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Today.Subtract(new TimeSpan(1)))
"2010-08-23T23:59:59Z"

这应解决问题。

答案 2 :(得分:1)

处理CAML查询的结果时,这将解决问题,但并不理想:

foreach (SPListItem item in _items){

     //   ... loop for processing items returned from CAML query, 
     //       code unrelated to UTC conversion excluded

      var localSDate = Convert.ToDateTime(item["StartDate"].ToString());

      if (Convert.ToBoolean(item["fAllDayEvent"])){
            localSDate = localSDate.ToUniversalTime();
      }
}

注意:此修复程序假设您不是按天限制搜索。很明显,在这种情况下它没有帮助,除非你扩展搜索参数以包括比实际需要返回的范围更广的范围。

我知道这不是海报正在寻找的内容,但是这可以帮助其他人找到这个页面......关于这个问题没有很多记录。

具体来说,如果您按月查询,并且仅显示该月份中存在的日历项,则此修复将起作用。在这种情况下,CAML将返回前一个月的最后几天和下个月的前几天,因此您不会丢失被一天抵消的数据。 (使用<Month />

答案 3 :(得分:0)

这对我有用。

<Where>
<Or>
    <Or>
        <And>
            <Eq>
                <FieldRef Name='fAllDayEvent' />
                <Value Type='AllDayEvent'>1</Value>
            </Eq>
            <Geq>
                <FieldRef Name='EndDate' />
                <Value Type='DateTime'>
                    <Today />
                </Value>
            </Geq>
        </And>
        <DateRangesOverlap>
          <FieldRef Name='EventDate' />
          <FieldRef Name='EndDate' />
          <FieldRef Name='RecurrenceID' />
          <Value Type='DateTime' IncludeTimeValue='TRUE'>
            <Today />
          </Value>
        </DateRangesOverlap>
    </Or>
   <Geq>
      <FieldRef Name='EventDate' />
      <Value Type='DateTime' IncludeTimeValue='TRUE'>
         <Today />
      </Value>
   </Geq>
</Or>
</Where>