しばらく前にMicrosoftConnectでこのバグを報告しましたが、修正されないためクローズされました。
絶対有効期限を現地時間で指定した場合、.NET2.0でも問題が発生します。
夏時間の終わりの1時間の間、現地時間はあいまいであるため、予期しない結果が生じる可能性があります。つまり、絶対有効期限が予想より1時間長くなる可能性があります。
ヨーロッパでは、夏時間は2009年10月25日の02:00に終了しました。以下のサンプルは、アイテムを01:59に2分の有効期限でキャッシュに配置した場合、1時間キャッシュに残り、 2分。
DateTime startTime = new DateTime(2009, 10, 25, 1, 59,0);
DateTime endTime = startTime.AddMinutes(2);
// end time is two minutes after start time
DateTime startUtcTime = startTime.ToUniversalTime();
DateTime endUtcTime = endTime.ToUniversalTime();
// end UTC time is one hour and two minutes after start UTC time
Console.WriteLine("Start UTC time = " + startUtcTime.ToString());
Console.WriteLine("End UTC time = " + endUtcTime.ToString());
.NET 2.0以降の回避策は、Rubenが指摘したUTCでの絶対有効期限を指定することです。
Microsoftは、絶対有効期限の例でUTCを使用することを推奨しているはずですが、この推奨は.NET 2.0以降でのみ有効であるため、混乱する可能性があると思います。
編集
コメントから:
ただし、露出は、オーバーラップ中に変換が発生した場合にのみ発生します。実際に行われる単一の変換は、Cache.Addを使用してアイテムを提出するときです。
この問題は、夏時間の終わりのあいまいな1時間の間に、現地時間のAbsoluteExpiration時刻でアイテムをキャッシュに挿入した場合にのみ発生します。
たとえば、ローカルタイムゾーンが中央ヨーロッパ(冬はGMT + 1、夏はGMT + 2)で、2009年10月25日の01:59:00に次のコードを実行するとします。
DateTime absoluteExpiration = DateTime.Now.AddMinutes(2);
Cache.Add(... absoluteExpiration ...)
その後、アイテムは、通常予想される2分間ではなく、1時間2分間キャッシュに残ります。これは、非常にタイムクリティカルなアプリケーション(株式相場表示、航空会社の出発ボードなど)では問題になる可能性があります。
ここで起こっていることは次のとおりです(ヨーロッパの時間を想定していますが、原則はどのタイムゾーンでも同じです)。
DateTime.Now =2009-10-2501:59:00ローカル。local = GMT + 2、つまりUTC = 2009-10-24 23:59:00
.AddMinutes(2)=2009-10-2502:01:00ローカル。ローカル=GMT+ 1、つまりUTC = 2009-11-25 01:01:00
Cache.Addは、有効期限を内部でUTC(2009-11-25 01:01:00)に変換するため、有効期限は現在のUTC時刻(23:59:00)より1時間2分早くなります。
DateTime.Nowの代わりにDateTime.UtcNowを使用する場合、キャッシュの有効期限は2分になります(.NET 2.0以降)。
DateTime absoluteExpiration = DateTime.UtcNow.AddMinutes(2);
Cache.Add(... absoluteExpiration ...)
コメントから:
それとも私は何かが足りないのですか?
いいえ、違います。分析は的確であり、アプリケーションがタイムクリティカルであり、DSTの終了時にその期間中に実行される場合は、DateTime.UtcNowを使用する権利があります。
ルーベンの答えの声明は次のとおりです。
供給時の種類が設定されている限り、どちらでも安全に使用できます
間違っている。