Есть ли надежный способ обработки часовых поясов, когда приложения.NET используются с XenApp?
Я столкнулся с проблемой, связанной с идентификаторами часовых поясов.NET в сочетании с XenApp, которая может быть уменьшена до следующего фрагмента TimeZoneNotFoundException
(т.е. призыв к TimeZoneInfo.FindSystemTimeZoneById
):
var tzLocal = TimeZoneInfo.Local;
var tzId = tzLocal.Id;
var tz = TimeZoneInfo.FindSystemTimeZoneById(tzId);
Точный текст исключения:
System.TimeZoneNotFoundException:
The time zone ID 'Mitteleuropäische Zeit' was not found on the local computer.
at System.TimeZoneInfo.GetTimeZone(String id)
at System.TimeZoneInfo.FindSystemTimeZoneById(String id)
(Нечто подобное происходит в NodaTime 1.1, например, внутри вызова NodaTime.DateTimeZoneProviders.Bcl.GetSystemDefault()
).
Странно то, что TimeZoneInfo.Local.Id
похоже, возвращает немецкое имя часового пояса, хотя сервер работает с языком, установленным на английский, и идентификатор часового пояса должен быть независимым от языка (см. ID.Net TimeZoneInfo - это зависит от языка Windows?). Но язык клиента - немецкий... (Обновление / уточнение: проблема не возникнет, если клиент и сервер используют один и тот же язык.)
Я думаю, что здесь происходит:
- .NET звонки
GetTimeZoneInformation
в kernel32.dll для получения местного часового пояса. - Вызов API перехватывается XenApp (см. Возможно ли получить часовой пояс пользователя для приложения, размещенного в Citrix XenApp?), Поскольку XenApp можно настроить на использование локального часового пояса клиента (см. http://mdaslam.wordpress.com/2010/01/05/xenapp-time-zone-setting/).
- Результирующий
TIME_ZONE_INFORMATION
структура содержит стандартное немецкое имя (я проверил это с помощью p/invoke на английском сервере XenApp). - Так как
TIME_ZONE_INFORMATION
структура (см. http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx) не содержит независимого от языка идентификатора часового пояса.NET не соответствует возвращенному Немецкий идентификатор часового пояса к его локальной базе данных часовых поясов (с английскими именами) и использует (локализованное) стандартное имя в качестве запасного идентификатора для часового пояса. ErgoTimeZoneInfo.Local.Id
содержит немецкое название "местного" часового пояса. - затем
TimeZoneInfo.FindSystemTimeZoneById
происходит сбой для этого резервного идентификатора, потому что он действительно неизвестен системе (потому что это локализованное стандартное имя из системы с другим языком).
Итак, как я могу обойти эту проблему, кроме как сказать клиенту отключить использование часового пояса клиента в XenApp?
1 ответ
Это всего лишь предположение, но, вероятно, когда XenApp отображает часовой пояс клиента, он использует GetTimeZoneInformation
функция из Win32 API. Это возвращает TIME_ZONE_INFORMATION
структура, которая не включает в себя идентификатор часового пояса. Он возвращает только информацию о часовом поясе, такую как смещение и текущая информация о летнем времени, вместе с локализованными именами.
Вероятно, вместо этого следует использовать GetDynamicTimeZoneInformation
, который возвращает DYNAMIC_TIME_ZONE_INFORMATION
состав. Одним из элементов которого является TimeZoneKeyName
, который будет сопоставлен с.NET TimeZoneInfo.Id
без локализации.
Теперь я очень мало знаю о XenApp, но вполне возможно, что Citrix уже знает об этой проблеме и либо исправил ее в последней версии, либо работает над ней. Если возможно, вы должны обновиться до последней версии, и если она все еще не работает, то посмотрите, есть ли она в их списке ошибок. Если нет, то сообщите об этом и сделайте ссылку на этот пост.