Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 缓存。添加绝对过期时间-是否基于UTC?_.net_Asp.net_Datetime_Utc_System.web.caching - Fatal编程技术网

.net 缓存。添加绝对过期时间-是否基于UTC?

.net 缓存。添加绝对过期时间-是否基于UTC?,.net,asp.net,datetime,utc,system.web.caching,.net,Asp.net,Datetime,Utc,System.web.caching,示例使用DateTime.Now.Add计算过期时间,即过期时间: DateTime.Now.AddSeconds(60) 作为绝对过期参数的值 我本以为相对于DateTime.UtcNow计算它会更正确[因为如果夏令时从现在到到期点之间的中间时间开始,就不会有歧义] 在引入DateTimeKind之前,我猜想缓存管理中存在一些丑陋的漏洞,如果时间不是UTC时间,可以让它做一些适当的事情 在.NET2.0及更高版本中,我猜想它应该处理一个DateTime计算为DateTime.UtcNow.

示例使用
DateTime.Now.Add
计算过期时间,即过期时间:

 DateTime.Now.AddSeconds(60)
作为
绝对过期
参数的值

我本以为相对于
DateTime.UtcNow
计算它会更正确[因为如果夏令时从现在到到期点之间的中间时间开始,就不会有歧义]

在引入
DateTimeKind
之前,我猜想缓存管理中存在一些丑陋的漏洞,如果时间不是UTC时间,可以让它做一些适当的事情

在.NET2.0及更高版本中,我猜想它应该处理一个
DateTime
计算为
DateTime.UtcNow.AddSeconds(60)
,因为它有
DateTime.Kind
作为其推断中的输入

多年来,我一直自信地使用
DateTime.UtcNow
作为基础,但在没有任何东西指出文档在4年多的时间里具有高度误导性的情况下,我无法提出这样做绝对正确的理由

问题是什么

  • 尽管使用了很多bingage和Google搜索,我还是无法从微软那里找到任何权威性的讨论——有人能找到与此相关的东西吗
  • 使用UtcNow是否有任何理由不更正确和/或更安全

  • (是的,我可以仔细阅读源代码和/或反射器的源代码,但我正在寻找一个完整的详细信息!)

    缓存。Add
    在存储之前将过期日期转换为UTC

    从Reflector(为了便于阅读,我省略了大部分参数):


    CacheExpires.FlusheExpiredItems
    中,将
    utcAbsoluteExpiration
    DateTime.UtcNow
    进行比较。例如,当缓存项的添加和过期跨越夏时制结束时,这会导致意外行为。

    [从Jeff Sternal的答案中获得的见解高度衍生,我在未完成支付中获得+1 d:d]

    似乎在1.1中(我没有看1.0,但我假设它是类似的),在没有
    DateTime.Kind
    的情况下,并且已经发布了带有
    DateTime.Now
    -相对时间的示例,他们觉得立即调用
    ToUniversalTime()
    很舒服

    因此

  • 在1.x中,如果您[API用户]使用
    DateTime.UtcNow
    (并且在调用
    Cache.Add
    的过程中对DST的启动有敏感度),那么最终会导致混乱

  • 在2.0[和3.x]中,只要设置了所提供时间的
    种类
    [如果您从
    DateTime.Now获得时间,通常情况下是这样的,现在
    UtcNow
    ]。[参见Joe的评论和回答,了解全部理由]对于1小时的DST切换,肯定更喜欢
    UtcNow

  • 这个例子保持原样,所以反对1.x的人不会被误导[而且人们可以继续假装DST是一个古怪的边缘案例:p]。[同上,正如Joe所指出的]但这是一个非常有争议的立场,因为这可能会导致东西在缓存中多呆一个小时

  • 我仍然非常有兴趣听到更多的细节,包括任何小马在那里

    编辑:我从Joe的评论中意识到,我没有明确指出这样一个事实:如果使用2.0或更高版本,使用
    UtcNow肯定更正确,因为在DST“土拨鼠小时”期间,项目可能会被额外缓存一小时。我还认为微软文档应该指出这一事实(附带条件,他们需要提到这不适用于1.1[无论页面是否标记为2.0+特定],谢谢Joe

    编辑:野田佳彦的时间将有一个整洁的包装,使这个万无一失:D

    I前一段时间,但它已被关闭,因为无法修复

    如果在本地时间指定绝对过期时间,则.NET2.0中仍然存在问题

    在夏令时结束时的一小时内,您的本地时间不明确,因此您可能会得到意外的结果,即绝对过期时间可能比预期时间长一小时

    在欧洲,夏令时结束于2009年10月25日02:00。下面的示例说明,如果您在01:59将项目放置在缓存中,过期时间为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及更高版本

    编辑

    从评论中:

    但只有当 转换发生在重叠期间。 实际需要的单个转换 地点是指您将物品寄存在 缓存。添加

    只有在夏时制结束时的一个不明确的小时内,在缓存中插入一个在本地时间中具有绝对过期时间的项时,才会发生此问题

    例如,如果您的本地时区是中欧(冬季为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.local=GMT+2,所以UTC=2009-10-24 23:59:00

    • .AddMinutes(2)=2009-10-25 02:01:00 local.local=GMT+1,所以UTC=2009-11-25 01:01:00

    • Cache.Add在内部将过期时间转换为UTC
      DateTime absoluteExpiration = DateTime.Now.AddMinutes(2);
      Cache.Add(... absoluteExpiration ...)
      
      DateTime absoluteExpiration = DateTime.UtcNow.AddMinutes(2);
      Cache.Add(... absoluteExpiration ...)