简体   繁体   中英

Incorrect time zone displayed in Outlook after updating a calendar event through EWS

I'm having an issue with time zones when updating an appointment.

Step 1, create a single event, works fine

First I create a single event, running from 10:00 to 11:00 local time (Amsterdam DST, so UTC+2).
My Exchange server 2010 (SP2) knows the "W. Europe Standard Time" timezone.
No issue there, here's the event in Outlook 2007:

在此处输入图片说明

This is the XML that creates the event:

<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types"
  xmlns:mes="http://schemas.microsoft.com/exchange/services/2006/messages">
<soapenv:Header>
  <typ:RequestServerVersion Version="Exchange2007_SP1"/>
  <typ:MailboxCulture>en-US</typ:MailboxCulture>
  <typ:TimeZoneContext>
     <typ:TimeZoneDefinition Id="W. Europe Standard Time"/>
  </typ:TimeZoneContext>
</soapenv:Header>
<soapenv:Body>
   <mes:CreateItem SendMeetingInvitations="SendToNone">
      <mes:SavedItemFolderId>
         <typ:DistinguishedFolderId Id="calendar">
            <typ:Mailbox>
               <typ:EmailAddress>developer@timetellbv.nl</typ:EmailAddress>
            </typ:Mailbox>
         </typ:DistinguishedFolderId>
      </mes:SavedItemFolderId>
      <mes:Items>
         <typ:CalendarItem>
           <typ:Subject>New event 10:00-11:00</typ:Subject>
           <typ:Body BodyType="Text"></typ:Body>
           <typ:Categories>
             <typ:String>TimeTell</typ:String>
           </typ:Categories>
           <typ:ReminderIsSet>false</typ:ReminderIsSet>
           <typ:Start>2014-08-19T10:00:00.000+02:00</typ:Start>
           <typ:End>2014-08-19T11:00:00.000+02:00</typ:End>
           <typ:IsAllDayEvent>false</typ:IsAllDayEvent>
           <typ:LegacyFreeBusyStatus>Busy</typ:LegacyFreeBusyStatus>
           <typ:Location></typ:Location>
           <typ:MeetingTimeZone TimeZoneName="W. Europe Standard Time"/>
         </typ:CalendarItem>
      </mes:Items>
   </mes:CreateItem>
</soapenv:Body>
</soapenv:Envelope>

Note that I specify the MeetingTimeZone, and give Start/Finish an explicit time zone, so that Exchange Server knows how to convert it to UTC without having to rely on the server time zone (see Best Practices for Using Exchange Web Services for Calendaring Tasks ).
I tried leaving out all time zone info when creating the event, but this immediately gives me the 'Reykjavik effect' of step 2. Anyway, step 1 works fine.

Step 2, update the single event, fails: changes timezone as displayed in Outlook

Now I modify the event caption only; I need to specify all items again (my code has no idea what changed):

<soapenv:Envelope
  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types"
  xmlns:mes="http://schemas.microsoft.com/exchange/services/2006/messages">
<soapenv:Header>
  <typ:RequestServerVersion Version="Exchange2007_SP1"/>
  <typ:MailboxCulture>en-US</typ:MailboxCulture>
  <typ:TimeZoneContext>
     <typ:TimeZoneDefinition Id="W. Europe Standard Time"/>
  </typ:TimeZoneContext>
</soapenv:Header>
<soapenv:Body>
<mes:UpdateItem ConflictResolution="AlwaysOverwrite" SendMeetingInvitationsOrCancellations="SendToNone">
   <mes:ItemChanges>
      <typ:ItemChange>
         <typ:ItemId Id="AQMkAZ[snip]hgAAAA==" ChangeKey="DwAAA[snip]yy5AX"/>
         <typ:Updates>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="item:Subject"/>
               <typ:CalendarItem>
                 <typ:Subject>New event 10:00-11:00 (modified)</typ:Subject>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="item:Sensitivity"/>
               <typ:CalendarItem>
                 <typ:Sensitivity>Normal</typ:Sensitivity>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="item:Categories"/>
               <typ:CalendarItem>
                  <typ:Categories>
                     <typ:String>TimeTell</typ:String>
                  </typ:Categories>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="item:Body"/>
               <typ:CalendarItem>
                 <typ:Body BodyType="Text"></typ:Body>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="calendar:Location"/>
               <typ:CalendarItem>
                 <typ:Location></typ:Location>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="item:ReminderIsSet"/>
               <typ:CalendarItem>
                 <typ:ReminderIsSet>false</typ:ReminderIsSet>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="calendar:IsAllDayEvent"/>
               <typ:CalendarItem>
                 <typ:IsAllDayEvent>false</typ:IsAllDayEvent>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="calendar:Start"/>
               <typ:CalendarItem>
                 <typ:Start>2014-08-19T10:00:00.000+02:00</typ:Start>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="calendar:End"/>
               <typ:CalendarItem>
                 <typ:End>2014-08-19T11:00:00.000+02:00</typ:End>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:FieldURI FieldURI="calendar:LegacyFreeBusyStatus"/>
               <typ:CalendarItem>
                 <typ:LegacyFreeBusyStatus>Busy</typ:LegacyFreeBusyStatus>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellID" PropertyType="Integer"/>
               <typ:CalendarItem>
                  <typ:ExtendedProperty>
                     <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellID" PropertyType="Integer"/>
                     <typ:Value>10722</typ:Value>
                  </typ:ExtendedProperty>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellSyncTime" PropertyType="SystemTime"/>
               <typ:CalendarItem>
                  <typ:ExtendedProperty>
                     <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellSyncTime" PropertyType="SystemTime"/>
                     <typ:Value>2014-08-19T16:22:22.094+02:00</typ:Value>
                  </typ:ExtendedProperty>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellSyncVer" PropertyType="Integer"/>
               <typ:CalendarItem>
                  <typ:ExtendedProperty>
                     <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellSyncVer" PropertyType="Integer"/>
                     <typ:Value>80000</typ:Value>
                  </typ:ExtendedProperty>
               </typ:CalendarItem>
            </typ:SetItemField>
            <typ:SetItemField>
               <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellSyncID" PropertyType="String"/>
               <typ:CalendarItem>
                  <typ:ExtendedProperty>
                     <typ:ExtendedFieldURI DistinguishedPropertySetId="PublicStrings" PropertyName="TimeTellSyncID" PropertyType="String"/>
                     <typ:Value>0000000082ADE26393957649AD9C74BF97109BC2070084A6175871FF6A40850053554066620A000000000021000084A6175871FF6A40850053554066620A000232CB43830000</typ:Value>
                  </typ:ExtendedProperty>
               </typ:CalendarItem>
            </typ:SetItemField>
         </typ:Updates>
      </typ:ItemChange>
   </mes:ItemChanges>
 </mes:UpdateItem>
</soapenv:Body>
</soapenv:Envelope>

but now I get this:
The event shows properly in the calender overview

在此处输入图片说明

but when I open it I suddenly get incorrect 'Reykjavik' times:

在此处输入图片说明

Note that the header of the UpdateItem call still has the

<typ:TimeZoneContext>
   <typ:TimeZoneDefinition Id="W. Europe Standard Time"/>
</typ:TimeZoneContext>

but there is no

<typ:MeetingTimeZone TimeZoneName="W. Europe Standard Time"/>

in the call, as there was in the CreateItem call.

If I try to put it in like this I get an error "The specified object was not found in the store":

<typ:SetItemField>
   <typ:FieldURI FieldURI="calendar:Start"/>
   <typ:CalendarItem>
     <typ:Start>2014-08-19T10:00:00.000+02:00</typ:Start>
     <typ:MeetingTimeZone TimeZoneName="W. Europe Standard Time"/>
   </typ:CalendarItem>
</typ:SetItemField>
<typ:SetItemField>
   <typ:FieldURI FieldURI="calendar:End"/>
   <typ:CalendarItem>
     <typ:End>2014-08-19T11:00:00.000+02:00</typ:End>
     <typ:MeetingTimeZone TimeZoneName="W. Europe Standard Time"/>
   </typ:CalendarItem>
</typ:SetItemField>

I have tried placing MeetingTimeZone at other locations in the file but keep getting syntax errors.

Leaving the TimeZoneContext out of the header of the UpdateItem does not solve the issue (and from what I understand in TimeZoneContext documentation I should use it).

I need to use MeetingTimeZone for backward compatibility to Exchange Server 2007 SP1 (for later versions MeetingTimeZone is deprecated and we should use StartImeZone/EndTimeZone).

Question: How can I change the UpdateItem call to make sure my Outlook events keep having the correct time(zone)?

Background information:

  • Exchange server version returns:

<ServerVersionInfo MajorVersion="14" MinorVersion="3" MajorBuildNumber="195" MinorBuildNumber="1" Version="Exchange2010_SP2"/>

I got it! Thanks to this EWS Calendar Recurrence Item Update - TimeZone problem post.

Indeed you cannot just insert a

<typ:MeetingTimeZone TimeZoneName="W. Europe Standard Time"/>

line somewhere in the SOAP request, but you also have to specify MeetingTimeZone as a CalendarItem element that you want to change .
So this additional item has to be inserted into the call:

<typ:SetItemField>
   <typ:FieldURI FieldURI="calendar:MeetingTimeZone"/>
   <typ:CalendarItem>
      <typ:MeetingTimeZone TimeZoneName="W. Europe Standard Time" />
   </typ:CalendarItem>               
</typ:SetItemField>

And make sure to put it at the right place, because the items have to be specified in the order as defined in the CalendarItem type

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM