使用 Exchange 中的 EWS 更新约会的时区
了解如何使用 Exchange 中的 EWS 托管 API 或 EWS 更新现有约会或会议的时区。
在 Exchange 日历上创建约会或会议时,用于指定开始时间和结束时间的时区将保存为约会的创建时区。 可以使用 EWS 托管 API 或 EWS 更改该时区。 但是,更改约会的时区会对约会的开始和结束时间产生其他影响。
时间值存储在 Exchange 服务器上, (UTC) 坐标世界时。 因此,如果将约会设置为从下午 1:00 开始, (13:00) 东部时区 (UTC-05:00) ,则该值将存储为下午 6:00 (18:00) ,假定时区处于其标准时间阶段。 在其他时区查看该约会时,将从 UTC 值中添加或减去相应的小时数,以确定时区特定的时间。 例如,如果约会的开始时间为东部时间下午 1:00 (UTC) 下午 6:00,并且从太平洋时区 (UTC-08:00) 的客户端查看,则该客户端的时区特定开始时间为上午 10:00 (18:00 - 08:00) 。
在不更新开始和结束时间的情况下更新约会的时区时,服务器将更新服务器上存储的 UTC 值,以将开始和结束时间保留为同一时区特定的时间。 例如,考虑下午 1:00 东部约会。 时间在服务器上存储为 18:00 UTC。 如果约会的时区更改为太平洋时区,服务器会将开始时间更改为下午 1:00 太平洋时间 (UTC) 21:00。
可以通过显式设置开始时间和结束时间来更改此行为。
使用 EWS 托管 API 更新现有约会上的时区
在以下示例中,EWS 托管 API 用于通过更新 Appointment.StartTimeZone 和 Appointment.EndTimeZone 属性,将现有约会上的时区更新为 Central 时区。 如果 shiftAppointnment 参数设置为 true,则代码不会显式设置约会的开始时间和结束时间。 在这种情况下,服务器将移动开始时间和结束时间,以使它们在新时区中保持相同的时区相对时间。 如果设置为 false,则代码将显式转换开始和结束时间,使约会保持 UTC 的同一时间。
此示例假定 ExchangeService 对象已使用凭据的有效值和 Url 属性进行了初始化。
static void UpdateAppointmentTimeZone(ExchangeService service, ItemId apptId, bool shiftAppointment)
{
PropertySet includeTimeZones = new PropertySet(AppointmentSchema.Subject,
AppointmentSchema.Start,
AppointmentSchema.ReminderDueBy,
AppointmentSchema.End,
AppointmentSchema.StartTimeZone,
AppointmentSchema.EndTimeZone);
Appointment apptToUpdate;
// Load the existing appointment.
// This will result in a call to EWS.
try
{
apptToUpdate = Appointment.Bind(service, apptId, includeTimeZones);
}
catch (Exception ex)
{
Console.WriteLine("Error retrieving existing appointment: {0}", ex.Message);
return;
}
Console.WriteLine("Before update:");
// Output the current start, reminder, end, and time zones.
Console.WriteLine(" Start: {0}", apptToUpdate.Start);
Console.WriteLine(" Start time zone: {0}", apptToUpdate.StartTimeZone.DisplayName);
Console.WriteLine(" Reminder: {0}", apptToUpdate.ReminderDueBy);
Console.WriteLine(" End: {0}", apptToUpdate.End);
Console.WriteLine(" End time zone: {0}", apptToUpdate.EndTimeZone.DisplayName);
// Retrieve the Central time zone.
TimeZoneInfo centralTZ = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
// Update the time zones on the appointment.
apptToUpdate.StartTimeZone = centralTZ;
apptToUpdate.EndTimeZone = centralTZ;
if (!shiftAppointment)
{
// Set the start and end times explicitly so that the appointment
// will start and end at the same UTC time.
// Convert the times to then Central time zone. This
// will keep them at the same time in UTC.
// For example, 1:00 PM Eastern becomes 12:00 PM Central.
DateTime newStartTime = TimeZoneInfo.ConvertTime(
apptToUpdate.Start, centralTZ);
DateTime newEndTime = TimeZoneInfo.ConvertTime(
apptToUpdate.End, centralTZ);
apptToUpdate.Start = newStartTime;
apptToUpdate.End = newEndTime;
}
try
{
// Save the changes. This will result in a call to EWS.
apptToUpdate.Update(ConflictResolutionMode.AlwaysOverwrite,
SendInvitationsOrCancellationsMode.SendToNone);
}
catch (Exception ex)
{
Console.WriteLine("Error updating appointment: {0}", ex.Message);
return;
}
// Now rebind to the appointment to get the new values.
Appointment apptAfterUpdate;
try
{
// This will result in a call to EWS.
apptAfterUpdate = Appointment.Bind(service, apptId, includeTimeZones);
}
catch (Exception ex)
{
Console.WriteLine("Error retrieving existing appointment: {0}", ex.Message);
return;
}
Console.WriteLine("After update:");
// Output the current start, reminder, end, and time zones.
Console.WriteLine(" Start: {0}", apptAfterUpdate.Start);
Console.WriteLine(" Start time zone: {0}", apptAfterUpdate.StartTimeZone.DisplayName);
Console.WriteLine(" Reminder: {0}", apptAfterUpdate.ReminderDueBy);
Console.WriteLine(" End: {0}", apptAfterUpdate.End);
Console.WriteLine(" End time zone: {0}", apptAfterUpdate.EndTimeZone.DisplayName);
}
当此示例用于更新东部下午 1:00 开始、东部下午 2:00 结束的约会时, 将 shiftAppointment 参数设置为 true,并将 ExchangeService.TimeZone 属性设置为东部时区,输出如下所示。
Before update:
Start: 6/20/2014 1:00:00 PM
Start time zone: (UTC-05:00) Eastern Time (US & Canada)
Reminder: 6/20/2014 1:00:00 PM
End: 6/20/2014 2:00:00 PM
End time zone: (UTC-05:00) Eastern Time (US & Canada)
After update:
Start: 6/20/2014 2:00:00 PM
Start time zone: (UTC-06:00) Central Time (US & Canada)
Reminder: 6/20/2014 2:00:00 PM
End: 6/20/2014 3:00:00 PM
End time zone: (UTC-06:00) Central Time (US & Canada)
使用示例更新 shiftAppointment 参数设置为 false 的同一约会,并将 TimeZone 属性再次设置为东部时区时,输出看起来稍有不同。
Before update:
Start: 6/20/2014 1:00:00 PM
Start time zone: (UTC-05:00) Eastern Time (US & Canada)
Reminder: 6/20/2014 1:00:00 PM
End: 6/20/2014 2:00:00 PM
End time zone: (UTC-05:00) Eastern Time (US & Canada)
After update:
Start: 6/20/2014 1:00:00 PM
Start time zone: (UTC-06:00) Central Time (US & Canada)
Reminder: 6/20/2014 1:00:00 PM
End: 6/20/2014 2:00:00 PM
End time zone: (UTC-06:00) Central Time (US & Canada)
请注意,开始和结束时间没有更改。 这是因为在东部时区中解释时间 (因为 TimeZone 属性设置为东部时区) ,并且时间值已更新以防止约会转移。
使用 EWS 更新现有约会上的时区
以下示例 EWS UpdateItem 操作 请求更新约会上的时区。 本示例仅更新 StartTimeZone 和 EndTimeZone 元素,因此服务器将移动约会的开始时间和结束时间,使其保持新时区中的时区相对时间。 为了提高可读性, 将缩短 ItemId 元素的值。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010" />
</soap:Header>
<soap:Body>
<m:UpdateItem ConflictResolution="AlwaysOverwrite" SendMeetingInvitationsOrCancellations="SendToNone">
<m:ItemChanges>
<t:ItemChange>
<t:ItemId Id="AAMkADA5..." ChangeKey="DwAAABYA..." />
<t:Updates>
<t:SetItemField>
<t:FieldURI FieldURI="calendar:StartTimeZone" />
<t:CalendarItem>
<t:StartTimeZone Id="Central Standard Time" />
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:FieldURI FieldURI="calendar:EndTimeZone" />
<t:CalendarItem>
<t:EndTimeZone Id="Central Standard Time" />
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
以下示例请求更新约会的时区,并通过显式设置 Start 和 End 元素来更新 开始 和 结束 时间。 为了提高可读性, 将缩短 ItemId 元素的值。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2010" />
</soap:Header>
<soap:Body>
<m:UpdateItem ConflictResolution="AlwaysOverwrite" SendMeetingInvitationsOrCancellations="SendToNone">
<m:ItemChanges>
<t:ItemChange>
<t:ItemId Id="AAMkADA5..." ChangeKey="DwAAABYA..." />
<t:Updates>
<t:SetItemField>
<t:FieldURI FieldURI="calendar:StartTimeZone" />
<t:CalendarItem>
<t:StartTimeZone Id="Central Standard Time" />
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:FieldURI FieldURI="calendar:EndTimeZone" />
<t:CalendarItem>
<t:EndTimeZone Id="Central Standard Time" />
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:FieldURI FieldURI="calendar:Start" />
<t:CalendarItem>
<t:Start>2014-06-20T17:00:00.000Z</t:Start>
</t:CalendarItem>
</t:SetItemField>
<t:SetItemField>
<t:FieldURI FieldURI="calendar:End" />
<t:CalendarItem>
<t:End>2014-06-20T18:00:00.000Z</t:End>
</t:CalendarItem>
</t:SetItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>