XenApp と組み合わせた .NET タイムゾーン ID に関連する問題に遭遇しまし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 を呼び出します。 - XenApp はクライアントのローカル タイムゾーンを使用するように構成できるため、API 呼び出しは XenApp によってインターセプトされます (「Citrix XenApp がホストするアプリケーションのユーザー タイムゾーンを取得することは可能ですか? 」を参照) 。 /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 は一致しません。返されたドイツ語のタイムゾーン ID をローカル タイムゾーンの「データベース」(英語名) に格納し、(ローカライズされた) 標準名をタイムゾーンのフォールバック ID として使用します。したがって、TimeZoneInfo.Local.Id
「ローカル」タイムゾーンのドイツ語名が含まれています。TimeZoneInfo.FindSystemTimeZoneById
このフォールバック識別子はシステムにとって実際には不明であるため (異なる言語のシステムからのローカライズされた標準名であるため)、失敗します。
では、XenApp でクライアントのタイムゾーンの使用を無効にするよう顧客に伝える以外に、この問題を回避するにはどうすればよいでしょうか?