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 中也有介绍。)
StandardName
、DaylightName
和 DisplayName
由 OS 语言本地化,不是标识符。它们仅供人类展示。例如,DisplayName
通常与下拉列表中的 ID 配对以选择时区。显示名称将显示给用户,相应的 ID 将保存在应用程序中。 StandardName
和 DaylightName
与特定日期和时间一起用于人为显示,具体取决于哪个日期和时间有效。
那个GetTimeZoneInformation
returnsTIME_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
我们在用 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 中也有介绍。)StandardName
、DaylightName
和DisplayName
由 OS 语言本地化,不是标识符。它们仅供人类展示。例如,DisplayName
通常与下拉列表中的 ID 配对以选择时区。显示名称将显示给用户,相应的 ID 将保存在应用程序中。StandardName
和DaylightName
与特定日期和时间一起用于人为显示,具体取决于哪个日期和时间有效。
那个GetTimeZoneInformation
returnsTIME_ZONE_ID_DAYLIGHT
是无关紧要的。您不应该使用它来改变 ID 的名称(即,不要将 "standard" 替换为 "daylight")。
最终听起来您只需要用户的时区 ID。有很多方法可以做到这一点。以下任何一项都有效:
使用Win32 API,可以调用
GetDynamicTimeZoneInformation
, which returns aDYNAMIC_TIME_ZONE_INFORMATION
结构。TimeZoneKeyName
是您应该使用的 ID。您可以在
TimeZoneKeyName
值 中的 如果您正在编写 .NET 代码,您可以从
TimeZoneInfo.Local.Id
获取它
从命令行,您可以调用
tzutil /g
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation
处直接从注册表中获取此信息