我遇到了一个与 .NET 时区 ID 结合 XenApp 相关的问题,可以简化为以下代码段,抛出 a 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?)。但是客户端的语言是德语......(更新/澄清:如果客户端和服务器使用相同的语言,则不会出现问题。)
我认为这里发生的是:
- .NET 调用
GetTimeZoneInformation
kernel32.dll 以检索本地时区。 - API 调用被 XenApp 拦截(请参阅是否可以为 Citrix XenApp 托管的应用程序获取用户时区?),因为 XenApp 可以配置为使用客户端的本地时区(请参阅http://mdaslam.wordpress.com/2010 /01/05/xenapp-time-zone-setting/)。
- 生成的
TIME_ZONE_INFORMATION
结构包含一个德语标准名称(我在英语 XenApp 服务器上使用 p/invoke 进行了检查)。 - 由于
TIME_ZONE_INFORMATION
结构(参见http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx)不包含语言中性时区标识符 .NET 无法匹配将德国时区标识符返回到其本地时区“数据库”(带有英文名称),并使用(本地化)标准名称作为时区的后备标识符。因此,TimeZoneInfo.Local.Id
包含“本地”时区的德语名称。 - 然后
TimeZoneInfo.FindSystemTimeZoneById
这个备用标识符失败,因为系统确实不知道它(因为它是来自具有不同语言的系统的本地化标准名称)。
那么除了告诉客户在 XenApp 中禁用客户端时区的使用之外,我还能如何解决这个问题呢?