DateTime.Now如何工作?

时间:2017-07-20 08:58:24

标签: javascript c# datetime

我发现一些代码看起来像这样:

var obj = new SomeClass();
obj.FirstProperty = Magic.GetFirstProperty();
//...
obj.CreateDate = DateTime.Now;
obj.ModificationDate = obj.CreateDate;

有很多属性,所以我决定重构该代码并使用对象初始化器。

var obj = new SomeClass
{
    FirstProperty = Magic.GetFirstProperty();
    //...
    CreateDate = DateTime.UtcNow,
    ModificationDate = DateTime.UtcNow
};

在对象初始化块中将属性从一个重写到另一个是不可能的(据我所知)并且在块外看起来很糟糕(在我看来)。

我决定进行测试,并且我从600到1200个不同的对中进行了10 000 000次迭代。这是代码:

class Program
{
    static void Main(string[] args)
    {
        int j = 0;
        for (int i = 0; i < 10000000; i++)
        {
            var obj = new SomeClass
            {
                First = DateTime.UtcNow,
                Second = DateTime.UtcNow
            };

            if (obj.First != obj.Second)
                Console.WriteLine(j++ + "  :  " + GetDateInfo(obj.First) + "  " + GetDateInfo(obj.Second));
        }
        Console.WriteLine("End of work");
        Console.ReadKey();
    }

    static string GetDateInfo(DateTime dateTime) =>
        $"{dateTime.Hour} : {dateTime.Minute} : {dateTime.Second} : {dateTime.Millisecond} -  {dateTime.Ticks}";
}

internal class SomeClass
{
    public DateTime First { get; set; }
    public DateTime Second { get; set; }
}

这里有一些结果:

Screenshot with results

正如你所看到的,一些像高光一样的记录,只有处理器滴答的差异。

与此同时,除了Google Chrome中的内存泄漏, javascript 总是返回相等的值。这是代码:

var d,d2,n,n2;
for(var i=0; i<1000000; i++) {
    d = new Date();
    n = d.getTime();
    d2 = new Date();
    n2 = d.getTime();

    if(n===n2) 
        console.log("equal"); 
    else 
        console.log("not equal");  
}

您是否知道如何以正确的方式在.NET中解决该问题以及DateTime.Now如何实际工作?我非常好奇幕后发生的事情。 我期待一次迭代/对象初始化中的两个值都相等。

3 个答案:

答案 0 :(得分:5)

  

您是否知道如何以适当的方式在.NET中解决该问题...

解决方案很简单,只需调用DateTime.UtcNow一次......

var dtNow = DateTime.UtcNow;
var obj = new SomeClass
{
    FirstProperty = Magic.GetFirstProperty();
    //...
    CreateDate = dtNow,
    ModificationDate = dtNow
};

对于循环,如果您希望所有值完全相同,则应在循环开始之前指定dtNow 。即只分配一次。

  

... DateTime.Now实际上是如何工作的?

简而言之,它会在您调用DateTime.UtcNow时获得当前值。

很长一段时间,你应该查看documentation并进行进一步的研究,如果你真的感兴趣的话。

答案 1 :(得分:3)

Js Date.now()方法具有毫秒级的分辨率。如果您需要更高的分辨率,请使用Performance.now()Date.now()

正式地说,C#DateTime使用100 ns的刻度。但在实际情况下很难实现这一决议。 High-Precision Code Timing in .NET

这意味着如果在两次DateTime.Now调用之间传递多个勾号,则创建的DateTime对象将具有不同的值。

对于您的用例,获取完全相同时间戳的最简单方法是仅调用DateTime.Now一次并分配此值。

var now = DateTime.UtcNow;
var obj = new SomeClass
   {
       FirstProperty = Magic.GetFirstProperty();
       (...)
       CreateDate = now,
       ModificationDate = now 
   };

答案 2 :(得分:1)

DateTime.Now(和UtcNow)使用内部窗口函数返回当前时间。它会在每次调用它时返回当前时间,因此当然在调用之间会有微小的差异。

解决方案:

  • 将当前时间分配给变量并使用该变量初始化obj属性。

  • 如果这是您自己的类,请创建一个自动进入属性的正确构造函数。

这与JavaScript不同,后者在创建Date对象后设置当前时间。调用其任何函数将返回创建对象的时间。