【问题标题】:EWS TimeZone not found error - localization issue?EWS 时区未找到错误 - 本地化问题?
【发布时间】:2020-04-06 09:52:02
【问题描述】:

在将 Exchange 日历与 EWS 同步时,我们的客户遇到以下情况:

在 Win 10 客户端计算机上,调用 GetTimeZoneInformation 会返回 TIME_ZONE_ID_DAYLIGHT,即“系统正在 TIME_ZONE_INFORMATION 结构的 DaylightDate 成员所涵盖的范围内运行。”
标准名称为:西欧标准时间
DaylightName 是:W. Europe Daylight Time

IIRC 正确,我现在需要搜索 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Dlt 条目以确定时区的根键名称。
但是'W.欧洲夏令时”不存在:有 139 个条目,但没有一个有名为“W.欧洲夏令时'

所以我的代码无法转换为正确的根键名称并输入 'W. EWS SOAP 调用中的“欧洲夏令时”如下:

<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

我怀疑这些“本地化”(?) StandardName/DaylightName 注册表值使我无法正确查找“W.欧洲标准时间的时区 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

我该如何解决这个问题?

【问题讨论】:

    标签: localization timezone exchangewebservices


    【解决方案1】:

    您将两个不同的概念混合在一起。

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

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

    GetTimeZoneInformation 返回TIME_ZONE_ID_DAYLIGHT 无关紧要。您不应该使用它来改变 ID 的名称(即,不要将“标准”替换为“日光”)。

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

    • 使用 Win32 API,您可以调用 GetDynamicTimeZoneInformation,它返回一个 DYNAMIC_TIME_ZONE_INFORMATION 结构。 TimeZoneKeyName 是您应该使用的 ID。

    • 您可以在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformationTimeZoneKeyName 值中直接从注册表中获取此信息

    • 如果你正在编写.NET代码,你可以从TimeZoneInfo.Local.Id获取它

    • 可以在命令行调用tzutil /g

    【讨论】:

    • GetDynamicTimeZoneInformation 成功了。使代码更容易;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 2017-12-02
    • 2020-04-30
    • 2014-05-19
    • 2014-10-04
    • 2018-09-23
    相关资源
    最近更新 更多