【问题标题】:SharePoint - all day events behave differently in CAML querySharePoint - 全天事件在 CAML 查询中的行为不同
【发布时间】:2009-10-05 15:04:13
【问题描述】:

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

当我创建 CAML 查询(在本例中为“U2U CAML 查询生成器”)时,我看到了一些奇怪的行为。当我的查询是简单的“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 时,我也输掉了全天活动。有谁知道我在哪里可以找到关于这种行为的详细描述?

EDIT2:我自己搞糊涂了;更正了第一次编辑。

【问题讨论】:

    标签: sharepoint


    【解决方案1】:

    SharePoint 以 UTC(又名 GMT 或 Zulu)存储日期/时间,并在首次显示时将其转换为站点本地时区。

    但是对于全天事件,它将时间(00:00 到 23:59:00)存储在站点本地时区中。

    正如您自己已经弄清楚的那样 - 我相信您发现了 SharePoint 解释查询的方式中的一个错误,它忘记了全天事件都是当地时间。

    我猜你可以通过查询来解决这个问题

    EventDate >= SomeDate 或者 AllDayEvent = True AND EventDate >= SomeDate - 4hrs

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

    这将使您更深入地了解 SharePoint 中时区的混乱程度 SharePoint Web Services and UTC time fun and games

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

    【讨论】:

    【解决方案2】:

    在处理 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 将返回上个月的最后几天和下个月的前几天,因此您不会丢失偏移一天的数据。 (使用&lt;Month /&gt;

    【讨论】:

    • Convert.ToBoolean(item["fAllDayEvent"]) 正是我想要的。谢谢!
    【解决方案3】:
    oQuery.Query = "<Where><Geq><FieldRef Name='EventDate' /><Value Type='DateTime'>" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Today.Subtract(new TimeSpan(1))) + "</Value></Geq></Where>"
    

    添加一个时间跨度值,例如:

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

    这应该可以解决问题。

    【讨论】:

      【解决方案4】:

      这对我有用。

      <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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-06
        相关资源
        最近更新 更多