Reputation: 1107
I found some code looking like this one:
var obj = new SomeClass();
obj.FirstProperty = Magic.GetFirstProperty();
//...
obj.CreateDate = DateTime.Now;
obj.ModificationDate = obj.CreateDate;
There were plenty of properties so I decided to refactor that code and use object initializer.
var obj = new SomeClass
{
FirstProperty = Magic.GetFirstProperty();
//...
CreateDate = DateTime.UtcNow,
ModificationDate = DateTime.UtcNow
};
Rewriting property from one to another in object initialization block is impossible (as far as I know) and doing it out of block looks bad (in my opinion).
I decide to make a test and for 10 000 000 iterations I got from 600 to 1200 different pairs. This is code:
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; }
}
And here we have some results:
As you can see, some records like highlithed one, have only difference in procesor ticks.
At the same time, javascript was returning always equal values, apart from memory leaks in Google Chrome. Here is code:
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");
}
Do you have any idea how to solve that issue in .NET in proper way and how does DateTime.Now actually works? I'm pretty curious what is going on behind the scenes. I was expecting that both values in one iterations/object intialization will be equal.
Upvotes: 0
Views: 1255
Reputation: 48415
Do you have any idea how to solve that issue in .NET in proper way...
Solution is simple, just call DateTime.UtcNow once...
var dtNow = DateTime.UtcNow;
var obj = new SomeClass
{
FirstProperty = Magic.GetFirstProperty();
//...
CreateDate = dtNow,
ModificationDate = dtNow
};
In the case of a loop, if you want all the values to be exactly the same, then you should assign dtNow
before the loop begins. i.e. only assign it once.
...how does DateTime.Now actually works?
In short, it gets the current value at the point that you call DateTime.UtcNow
.
In long, you should check out the documentation and do further research if you are really interested.
Upvotes: 5
Reputation: 9463
Js Date.now()
method has millisecond resolution. If you need higher resolution, use Performance.now()
. Date.now()
Officially, C# DateTime
uses 100 ns ticks. But it is hard to achieve this resolution under practical circumstances. High-Precision Code Timing in .NET
This means that if more than one tick passes between two calls to DateTime.Now
, the created DateTime
objects will have different values.
For your usecase, the simplest way to get the exact same timestamp would be to call DateTime.Now
only once and assign this value.
var now = DateTime.UtcNow;
var obj = new SomeClass
{
FirstProperty = Magic.GetFirstProperty();
(...)
CreateDate = now,
ModificationDate = now
};
Upvotes: 3
Reputation: 17055
DateTime.Now (and UtcNow) use internal windows functions to return the current time. It will return the current time everytime you call it, so there will be tiny differences between calls of course.
Solutions:
Assign the current time to a variable and use that variable to init the obj properties.
If that is your own class, create a proper constructor that inits the properties automatically.
This is different from JavaScript, where the current time is set once you create the Date object. Calling any of its functions will return the time of the creation of the object.
Upvotes: 1