TimeZoneInfo.ConvertTime在DateTime.MinValue上非常慢

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TimeZoneInfo.ConvertTime在DateTime.MinValue上非常慢相关的知识,希望对你有一定的参考价值。

我刚注意到我们的一个单元测试花了十秒钟。在玩了之后,我创建了一个最小的linqpad示例来重现它:

void Main()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    var timeZone = TimeZoneInfo.Local;
    for(int i=0; i<10000; i++)
    {
      //var dateTime = TimeZoneInfo.ConvertTime(DateTime.UtcNow, timeZone);   
      var dateTime = TimeZoneInfo.ConvertTime(DateTime.MinValue, timeZone);   
    }
    sw.Stop();
    (sw.ElapsedMilliseconds + " ms").Dump();
}

这在我的PC或我们的构建PC上需要40秒。如果我使用DateTime.UtcNow,则需要15 ms。

这有什么原因或解决方法吗?


编辑:正如评论中所建议的,我反编译TimeZoneInfo并且在DateTime.MinValue上有一个特例:

static public DateTime ConvertTime(DateTime dateTime, TimeZoneInfo destinationTimeZone) {
    // Special case to give a way clearing the cache without exposing ClearCachedData()
    if (dateTime.Ticks == 0) {
        ClearCachedData();
    }

看起来像(test?)代码,每次使用DateTime.MinValue调用时都会清除缓存。

留下问题为什么会这样。

答案

没有必要反编译。你可以在the .NET Framework Reference Sourcethe CoreCLR source code on GitHub找到这个。

特殊情况在.NET 4.6中添加为非官方的解决方法,用于清除当时没有暴露ClearCachedData方法的WinRT等环境中的时区缓存。 I describe this further here

偶尔清除时区缓存通常不会产生明显的影响。你看到它是因为环路紧张。如果这是您的用例的问题,那么我建议使用ConvertTimeFromUtc方法,或与ConvertTime一起使用的DateTimeOffset版本。那些代码路径没有遇到特殊情况。

是的,我同意这应该更好地记录。我会看看能不能搞定。

请注意,从逻辑上讲,转换DateTime.MinValue的时区并没有多大意义,因为我们今天所知的时区在第1年并不存在。

以上是关于TimeZoneInfo.ConvertTime在DateTime.MinValue上非常慢的主要内容,如果未能解决你的问题,请参考以下文章

.NET 中 UTC 和 GMT 标准时间之间的差异

分配的变量引用在哪里,在堆栈中还是在堆中?

NOIP 2015 & SDOI 2016 Round1 & CTSC 2016 & SDOI2016 Round2游记

秋的潇洒在啥?在啥在啥?

上传的数据在云端的怎么查看,保存在啥位置?

在 React 应用程序中在哪里转换数据 - 在 Express 中还是在前端使用 React?