当.NET应用程序与XenApp一起使用时,是否有一种强大的方法来处理时区?

时间:2013-11-13 10:27:37

标签: .net localization timezone nodatime xenapp

我遇到了与.NET时区ID相关的问题,结合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 ID - Is it Windows Language Specific? )。但是客户端的语言是德语...(更新/澄清:如果客户端和服务器使用相同的语言,则不会出现问题。)

我的想法是:

  1. .NET调用kernel32.dll中的GetTimeZoneInformation以检索本地时区。
  2. XenApp会拦截API调用(请参阅Is it possible to get a users timezone for an application hosted by Citrix XenApp?),因为可以将XenApp配置为使用客户端的本地时区(请参阅http://mdaslam.wordpress.com/2010/01/05/xenapp-time-zone-setting/)。
  3. 生成的TIME_ZONE_INFORMATION结构包含德语标准名称(我在英语XenApp服务器上使用p / invoke进行了检查)。
  4. 由于TIME_ZONE_INFORMATION结构(请参阅http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx)不包含与语言无关的时区标识符,因此无法将返回的德语时区标识符与其本地时区“数据库”(英文名称)相匹配并使用(本地化)标准名称作为时区的后备标识符。因此,TimeZoneInfo.Local.Id包含“本地”时区的德语名称。
  5. 然后TimeZoneInfo.FindSystemTimeZoneById对此回退标识符失败,因为它确实是系统未知的(因为它是来自具有不同语言的系统的本地化标准名称)。
  6. 那么除了告诉客户禁止在XenApp中使用客户端的时区之外,我该如何解决这个问题呢?

1 个答案:

答案 0 :(得分:1)

这只是一个猜测,但是当XenApp映射客户端时区时,它可能正在使用Win32 API中的GetTimeZoneInformation函数。这将返回TIME_ZONE_INFORMATION结构,包含时区的ID。它仅返回关于时区的信息,例如偏差和当前DST信息,以及本地化的名称。

它可能应该使用GetDynamicTimeZoneInformation,它返回DYNAMIC_TIME_ZONE_INFORMATION结构。其中一个元素是TimeZoneKeyName,它将映射回.NET的TimeZoneInfo.Id而不进行本地化。

现在我对XenApp知之甚少,但完全有可能Citrix已经意识到这个问题并且已经修复了最新版本或正在开发它。如果可能的话,你应该更新到最新的版本,如果它仍然坏了,那么去看它是否列在他们的bug追踪器中。如果没有,请报告并参考这篇文章。