EWS TimeZone не найдена ошибка - проблема локализации? - PullRequest
1 голос
/ 06 апреля 2020

При синхронизации календаря Exchange с EWS у клиента возникает следующая ситуация:

На клиентском компьютере Win 10 вызов GetTimeZoneInformation возвращает TIME_ZONE_ID_DAYLIGHT, т. Е. Система работает в диапазоне, охватываемом DaylightDate член структуры TIME_ZONE_INFORMATION. ' Стандартное имя: W. Стандартное европейское время DaylightName: W. Europe Daylight Time

IIR C, теперь мне нужно выполнить поиск в Dlt записях HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\, чтобы определить имя ключа root для часового пояса. Но 'В. Световое время в Европе »отсутствует: 139 записей, но ни одна из них не имеет записи Dlt с именем« W ». Europe Daylight Time '

Так что мой код не может преобразоваться в правильное root имя ключа и ставит' W. Europe Daylight Time 'в 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. Европа ', я нахожу одну запись, которая гласит:

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. Идентификатор часового пояса стандартного европейского времени.

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

Как я могу решить эту проблему?

1 Ответ

0 голосов
/ 06 апреля 2020

У вас есть две отдельные концепции, смешанные вместе.

  • Часовой пояс ID равен "W. Europe Standard Time". Он не локализован для других языков и не меняется на летнее время. Одна и та же строка используется для покрытия как стандартного времени, так и дневного времени, несмотря на то, что в нем присутствует слово Стандарт . (Это распространенный источник путаницы, он также описан в теге часового пояса вики .)

  • StandardName, DaylightName и DisplayName локализуются по языку ОС и не являются идентификаторами. Они предназначены только для показа человеком. Например, DisplayName обычно связан с идентификатором в раскрывающихся списках для выбора часового пояса. Отображаемое имя будет показано пользователю, а соответствующий идентификатор будет сохранен в приложении. StandardName и DaylightName используются для показа человеком в сочетании с указанными c датой и временем, в зависимости от того, что действует.

, которые GetTimeZoneInformation возвращает TIME_ZONE_ID_DAYLIGHT не имеет значения. Вам не следует использовать его для изменения имени идентификатора (т. Е. Не заменять «стандартный» на «дневной свет»).

В конечном счете, это звучит так, как будто вам нужен идентификатор часового пояса пользователя. Есть много способов получить это. Будет работать любое из следующего:

  • Используя Win32 API, вы можете вызвать GetDynamicTimeZoneInformation, который возвращает структуру DYNAMIC_TIME_ZONE_INFORMATION , TimeZoneKeyName - это идентификатор, который вы должны использовать.

  • Вы можете получить его непосредственно из реестра по адресу HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation в значении TimeZoneKeyName

  • Если вы пишете. NET код, вы можете получить его из TimeZoneInfo.Local.Id

  • Из командной строки вы можете позвонить tzutil /g

...