-1

Using C# here

I have the following set where I want to update createdOn date and save to my db.

 foreach (var person in myData)
 {
   person.CreatedBy = "abc";
   person.CreatedOn = DateTime.UtcNow.ToString("o"); 
 }

 myRepo.Save(myData);

The issue is if I have 5 rows of data all the 5 rows get the same createdOn

For example, all the above get the same

CreatedOn as "2019-01-14T14:48:39.4814925Z" 

What am I missing here, I thought everytime I loop and add createdOn it gets the next tick.

Brenda
  • 510
  • 3
  • 13
  • 36
  • 1
    Maybe it iterates 5 times in one tick?? – Ryan Wilson Jan 14 '19 at 15:00
  • 1
    the cpu could be faster - `Tick` != cpu cycle – Daniel A. White Jan 14 '19 at 15:01
  • Does your program you actually *need* to be able to differentiate which is first down to the tick? I'd think this would mostly be a nonissue, but who am I to know :) – Broots Waymb Jan 14 '19 at 15:04
  • The issue is if I move the saving my repo inside the loop it works as I am saving the individual items. But I want to do a batch save as the number of items could be large so moved it outside and saving my entire data. Is there a better way to handle this or increment tick somehow. – Brenda Jan 14 '19 at 15:05
  • Possible duplicate of https://stackoverflow.com/questions/2143140/c-sharp-datetime-now-precision –  Jan 14 '19 at 15:05
  • @BrootsWaymb each data represents a row of a table. I am displaying the data based on createdOn desc in my table grid. So yes its required to have different time. – Brenda Jan 14 '19 at 15:06
  • 1
    Required to have a different time, even though multiple entities can be created at the same time? –  Jan 14 '19 at 15:07
  • If you require unique times (which seems like an unusual requirement for such a field IMO), you'll need to add some sort of artificial delay. As far as your system is concerned, these *were* created at the same time, so ordering descending isn't going to matter (and is "correct" no matter the order it actually returns these). – Broots Waymb Jan 14 '19 at 15:09
  • OT (doesn't solve your issue) - why store a date as string and not as date? – Hans Kesting Jan 14 '19 at 15:11
  • Little background. Each person is associated with a table and each table can have multiple data (rows which users can edit more like inline editing). The rows can be from 1 to 100. So when a user updates any particular rows I want the updated one to come top so I am getting all these details order by createdOn. If all these rows have same createdOn then there is no sorting on date happening. – Brenda Jan 14 '19 at 15:13
  • @HansKesting I am using dynamo db here so storing as a string. – Brenda Jan 14 '19 at 15:14
  • `DateTime` doesn't have this precision, if you need it you could start a `StopWatch` before the loop and use it's `ElapsedTicks` property. – Tim Schmelter Jan 14 '19 at 15:15

3 Answers3

2

The resolution of this property depends on the system timer, which depends on the underlying operating system. It tends to be between 0.5 and 15 milliseconds. As a result, repeated calls to the Now property in a short time interval, such as in a loop, may return the same value.

https://learn.microsoft.com/en-us/dotnet/api/system.datetime.now?redirectedfrom=MSDN&view=netframework-4.7.2#System_DateTime_Now

Lorentz Vedeler
  • 5,101
  • 2
  • 29
  • 40
1

If you are concerned with having a different value for each Person object you can get the datetime before your loop and add 100 nanoseconds to the value for each, as 1 nanosecond equals 1/1000000000 (billionth) of a second, adding 100 of these per iteration while giving unique times will still stay pretty close in precision for each person object:

//Set a variable to hold the current utc time before the loop starts
DateTime currentUtcTime = DateTime.UtcNow;
foreach (var person in myData)
{
   person.CreatedBy = "abc";
   person.CreatedOn = currentUtcTime.ToString("o");
   //Add 100 nanoseconds to the currentUtcTime variable
   currentUtcTime = currentUtcTime.AddTicks(1); 
}

 myRepo.Save(myData);

Documentation of DateTime.AddTicks (https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addticks?view=netframework-4.7.2)

Ryan Wilson
  • 10,223
  • 2
  • 21
  • 40
1

DateTime doesn't have this precision(tl;dr: "High-precision timings is not at all the purpose of DateTime; as you note, that's the purpose of StopWatch"). But you could start a StopWatch before the loop and add it's Elapsed value to the initial DateTime.UtcNow value:

DateTime now = DateTime.UtcNow;
Stopwatch sw = Stopwatch.StartNew();
foreach (var person in myData)
{
   person.CreatedBy = "abc";
   person.CreatedOn = now.Add(sw.Elapsed).ToString("o"); 
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939