我前段时间reported this bug on Microsoft Connect,但由于无法修复而已关闭。
如果您在本地时间指定绝对过期时间,在 .NET 2.0 中仍然存在问题。
在夏令时结束后的一小时内,您的当地时间是不明确的,因此您可能会得到意想不到的结果,即绝对到期时间可能比预期的时间长一小时。
在欧洲,夏令时于 2009 年 10 月 25 日 02:00 结束。下面的示例说明,如果您在 01:59 将项目放入缓存中并过期 2 分钟,它将在缓存中保留 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 及更高版本有效。
编辑
来自cmets:
但只有在
转换发生在重叠期间。
实际占用的单次转换
地点是您提交物品的时间
缓存.添加
仅当您在夏令时结束时的一个模糊小时内将具有 AbsoluteExpiration 时间的项目插入缓存中时,才会出现此问题。
例如,如果您的本地时区是中欧(冬季 GMT+1,夏季 GMT+2),并且您在 2009 年 10 月 25 日 01:59:00 执行以下代码:
DateTime absoluteExpiration = DateTime.Now.AddMinutes(2);
Cache.Add(... absoluteExpiration ...)
那么该项目将在缓存中保留一小时两分钟,而不是您通常期望的两分钟。这对于一些对时间要求非常严格的应用程序(例如股票行情、航空公司出发板)来说可能是个问题。
这里发生的事情是(假设欧洲时间,但任何时区的原则都是相同的):
DateTime.Now = 2009-10-25 01:59:00 本地。 local=GMT+2,所以 UTC = 2009-10-24 23:59:00
.AddMinutes(2) = 2009-10-25 02:01:00 本地。本地 = GMT+1,所以 UTC = 2009-11-25 01:01:00
Cache.Add 在内部将过期时间转换为 UTC (2009-11-25 01:01:00),因此过期时间比当前 UTC 时间 (23:59:00) 提前一小时两分钟.
如果您使用 DateTime.UtcNow 代替 DateTime.Now,则缓存到期时间为两分钟(.NET 2.0 或更高版本):
DateTime absoluteExpiration = DateTime.UtcNow.AddMinutes(2);
Cache.Add(... absoluteExpiration ...)
来自cmets:
还是我错过了什么?
不,你不是。您的分析是正确的,如果您的应用程序对时间要求严格,并且在 DST 结束时的这段时间内运行,那么您使用 DateTime.UtcNow 是正确的。
鲁本回答中的陈述:
只要设置了您提供的时间的种类,您就可以安全使用
不正确。