EWS托管API时区“无法转换”

时间:2014-05-28 10:28:01

标签: c# timezone exchangewebservices ews-managed-api

我使用EWS Managed API 2.1并使用最新的补丁级别在我的Win 2008 R2(德国)IIS服务器上找到的所有系统时区初始化我的ExchangeService:

EWS ews;
string s = "";
foreach (TimeZoneInfo tz in TimeZoneInfo.GetSystemTimeZones()) {
  try {
    ews = new ExchangeService(ExchangeVersion.Exchange2010, tz);
    ews.Credentials = new WebCredentials("alex@contoso.com", "password");
    ews.AutodiscoverUrl("alex@contoso.com");
    Appointment app = new Appointment(ews);
    app.Start = DateTime.Now;
    app.End = DateTime.Now.AddMinutes(15);
    app.Subject = tz.Id;
    app.Save();
  } catch(Exception ex) { s += ex.Message + "\n"; }
}

我的某些时区出错了。错误消息是:

Unable to convert 2009-01-01T00:00:00.000 from (UTC-03:00) Buenos Aires to UTC.
Unable to convert 2012-01-01T00:00:00.000 from (UTC-03:00) Salvador to UTC.
Unable to convert 2012-01-01T00:00:00.000 from (UTC+02:00) Tripolis to UTC.
Unable to convert 2009-01-01T00:00:00.000 from (UTC+04:00) Port Louis to UTC.
Unable to convert 2009-01-01T00:00:00.000 from (UTC+08:00) Perth to UTC.

有人可以向我解释,尽可能简单,

  • 为什么这些转换是通过dll代码尝试的?
  • 他们为什么会失败?
  • 是否/如何规避这个问题?

2 个答案:

答案 0 :(得分:0)

这只是一个猜测,但可能是由于DateTime.Now具有“本地”类型,而您正在使用不同的时区。考虑指定目标时区的时间:

var now = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz);
app.Start = now;
app.End = now.AddMinutes(15);

您可能还想明确指定开始和结束时区。我不确定它是否重要,但你可以测试一下:

app.StartTimeZone = tz;
app.EndTimeZone = tz;

很抱歉,我没有Exchange服务器来测试这些假设,但您可以尝试看看它是否适合您。

答案 1 :(得分:0)

这是.Net https://connect.microsoft.com/VisualStudio/feedback/details/1027179/timezone-conversion-bug

中的错误

我使用了这种解决方法

        var timeZoneInfo = GetWorkaroundTimeZone(TimeZoneInfo.Local);
        var appointment = new Appointment(service)
                          {
                              Subject = subject,
                              Body = body,
                              Start = start,
                              StartTimeZone =  timeZoneInfo,
                              End = end,
                              EndTimeZone = timeZoneInfo
                          };

    private static TimeZoneInfo GetWorkaroundTimeZone(TimeZoneInfo timeZone)
    {
        try
        {
            TimeZoneInfo.ConvertTime(new DateTime(2014, 1, 1), timeZone, TimeZoneInfo.Utc);
            TimeZoneInfo.ConvertTime(new DateTime(2012, 1, 1), timeZone, TimeZoneInfo.Utc);
            TimeZoneInfo.ConvertTime(new DateTime(2009, 1, 1), timeZone, TimeZoneInfo.Utc);
            return TimeZoneInfo.Local;
        }
        catch (Exception ex)
        {
            return TimeZoneInfo.CreateCustomTimeZone(
                "Time zone to workaround bug",
                timeZone.BaseUtcOffset,
                "Time zone to workaround bug",
                "Time zone to workaround bug");
        }
    }