EWS TimeZone not found error - 本地化问题?

EWS TimeZone not found error - localization issue?

我们在用 EWS 同步 Exchange 日历时,客户端出现以下情况:

在Win 10客户端电脑上,调用GetTimeZoneInformationreturnsTIME_ZONE_ID_DAYLIGHT,即'The system is operating in the range covered by the DaylightDate member of the TIME_ZONE_INFORMATION structure.'
StandardName 是:W. Europe Standard Time
DaylightName 是:W. Europe 夏令时

IIRC 正确,我现在需要搜索 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Dlt 条目以确定时区的根密钥名称。
但是 'W. Europe Daylight Time' 不存在:有 139 个条目,但其中 none 有一个名为 'W. Europe Daylight Time'

Dlt 条目

因此我的代码无法转换为正确的根密钥名称并在 EWS SOAP 调用中放入 'W. Europe Daylight Time',如下所示:

<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="Exchange2013"/>
  <typ:MailboxCulture>en-US</typ:MailboxCulture>
  <typ:TimeZoneContext>
     <typ:TimeZoneDefinition Id="W. Europe Daylight Time"/>
  </typ:TimeZoneContext>
</soapenv:Header>
<soapenv:Body>
  <mes:ResolveNames ReturnFullContactData="1" SearchScope="ActiveDirectory">
    <mes:UnresolvedEntry>someone@somewhere.com</mes:UnresolvedEntry>
  </mes:ResolveNames>
</soapenv:Body>
</soapenv:Envelope>

... 这些失败并出现如下错误:

GetCalendarFolder (calendar): FaultInBody: A time zone with the specified ID could not be found.
Details: ErrorTimeZone Id: W. Europe Daylight Time

在客户端计算机上,搜索 'W. Europe' 的注册表,我找到 一个 条目,上面写着:

RootKeyName: W. Europe Standard Time
  DisplayName: (UTC+01:00) Amsterdam, Berlijn, Bern, Rome, Stockholm, Wenen
  StandardName: West-Europa (standaardtijd)
  DaylightName: West-Europa (zomertijd)

这台机器有以下语言设置:

Default system UI language : en-US
System locale : nl-NL
Default time zone : W. Europe Standard Time
Installed language(s): en-US
  Type : Fully localized language.
Installed language(s): nl-NL
  Type : Partially localized language, MUI type.
  Fallback Languages en-US

我怀疑这些 'localized'(?) StandardName/DaylightName 注册表值阻止我正确查找 'W. Europe Standard Time' 时区 ID。

FWIW,Exchange 服务器有:

TIME_ZONE_ID_DAYLIGHT
StandardName: W. Europe Standard Time
DaylightName: W. Europe Daylight Time

是否有注册表项

RootKeyName: W. Europe Standard Time
  DisplayName: (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna
  StandardName: W. Europe Standard Time
  DaylightName: W. Europe Daylight Time

我该如何解决?

你把两个不同的概念混在一起了。

  • 时区ID"W. Europe Standard Time"。它没有针对其他语言进行本地化,也不会因夏令时而改变。同一个字符串用于涵盖标准时间和夏令时,尽管其中包含单词 Standard。 (这是一个常见的混淆来源,the timezone tag wiki 中也有介绍。)

  • StandardNameDaylightNameDisplayName 由 OS 语言本地化,不是标识符。它们仅供人类展示。例如,DisplayName 通常与下拉列表中的 ID 配对以选择时区。显示名称将显示给用户,相应的 ID 将保存在应用程序中。 StandardNameDaylightName 与特定日期和时间一起用于人为显示,具体取决于哪个日期和时间有效。

那个GetTimeZoneInformationreturnsTIME_ZONE_ID_DAYLIGHT是无关紧要的。您不应该使用它来改变 ID 的名称(即,不要将 "standard" 替换为 "daylight")。

最终听起来您只需要用户的时区 ID。有很多方法可以做到这一点。以下任何一项都有效:

  • 使用Win32 API,可以调用GetDynamicTimeZoneInformation, which returns a DYNAMIC_TIME_ZONE_INFORMATION结构。 TimeZoneKeyName 是您应该使用的 ID。

  • 您可以在 TimeZoneKeyName

  • 中的 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation 处直接从注册表中获取此信息
  • 如果您正在编写 .NET 代码,您可以从 TimeZoneInfo.Local.Id

  • 获取它
  • 从命令行,您可以调用 tzutil /g