2009-10-05 2 views
6

In un elenco di calendari di SharePoint creo due eventi con la data odierna. Uno faccio un evento per tutto il giorno, l'altro ho fissato l'ora di inizio alle 12 e l'ora di fine alle 23:55.SharePoint: gli eventi giornalieri si comportano diversamente nella query CAML

Quando creo una query CAML (in questo caso w/"U2U CAML Query Builder") sto osservando un comportamento strano. Quando la mia query è un semplice "OrderBy", vengono restituiti entrambi gli eventi.

Quando eseguo la seguente query che cerca per gli eventi che sono maggiori o uguali a oggi, solo l'evento che è NON contrassegnato come "All Day Event" viene restituito:

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

Esaminando i risultati dallo strumento di creazione di query vedo che i valori di EventDate (il nome interno della colonna Ora inizio) sono identici (2009-10-05 00:00:00).

Perché SharePoint tratta questi due eventi in modo identico? Potrebbe essere un problema di fuso orario?

MODIFICA: ulteriori informazioni, penso che questo potrebbe essere un problema del fuso orario. Ho scoperto l'attributo "IncludeTimeValue" dell'elemento Value, descritto qui: MSDN. Sono sulla costa orientale (attualmente GMT - 4 ore). Se modifico l'elemento Value come segue: (si noti la data è ora il 4 °, 5 ° non)

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

Poi vengono restituiti entrambi gli eventi, ma se vado fino a 20:01 poi perdo il tutto il giorno evento. Quando vado alle 20:01, perdo anche l'evento per tutto il giorno. Qualcuno sa dove posso trovare una descrizione approfondita di questo comportamento?

EDIT2: mi sono confuso; corretto la prima modifica.

risposta

6

SharePoint memorizza la data e l'ora in UTC (ovvero GMT o Zulu) e quando viene visualizzata per la prima volta la converte nel fuso orario locale dei siti.

Tuttavia, per gli eventi Tutto il giorno, memorizza i tempi (dalle 00:00 alle 23:59:00) nel fuso orario dei siti LOCAL.

Come hai già capito da solo - credo che tu abbia trovato un bug nel modo in cui SharePoint interpreta la query e dimentica che tutti gli eventi del giorno sono ora locale.

Credo che si potrebbe fare una soluzione brutto questo facendo una query per

EventDate> = SomeDate OR AllDayEvent = TRUE e EventDate> = SomeDate - 4 ore

Questo poster ha problemi simili SO - SharePoint all day event gives obscure result

E questo vi darà un po 'di comprensione di come BORKED tempo zone sono in SharePoint SharePoint Web Services and UTC time fun and games

E se questo non è abbastanza frustrante per voi allora guardate le date create/modificate tramite il modello a oggetti e meravigliate di come vengono segnalate come ora locale per eventi normali e UTC per tutti gli eventi del giorno!

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

Aggiunta di un valore Timespan come:

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

Questo dovrebbe risolvere il problema.

1

Quando si elaborano i risultati di una query CAML, questo risolverà il problema, ma non è l'ideale:

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(); 
     } 
} 

NOTA: questa correzione presuppone che non si sta limitando la ricerca di giorno. ovviamente in tal caso non sarebbe di aiuto, a meno che non si espandessero i parametri di ricerca per includere un intervallo più ampio di quello che effettivamente si ha bisogno di restituire.

So che non è esattamente quello che il poster sta cercando, ma questo potrebbe aiutare gli altri a trovare questa pagina ... non c'è molto documentato su questo problema.

In particolare questa soluzione funzionerà se si esegue una query per mese e si visualizzano solo gli elementi del calendario esistenti in quel mese. In questo caso, CAML restituirà comunque gli ultimi giorni del mese precedente e i primi del mese successivo, quindi non perderai i dati che vengono compensati di un giorno. (usando <Month />)

+0

Convert.ToBoolean (elemento ["fAllDayEvent"]) era esattamente quello che stavo cercando. Grazie! –

0

Questo ha funzionato per me.

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