Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing equal datetimes returns false

Tags:

c#

datetime

I have a query with how datetimes are compared/stored in C#. Consider the following code:

var createdDate = DateTime.Now;
using (cr = new LanguageDictionaryRepository(ds)) {
    cr.Add(new Sybrin10.Data.DTO.LanguageDictionary() {
        Active = true,
        CreatedDate = createdDate,
        CultureCode = cultureCode,
        Data = new System.Text.UTF8Encoding().GetBytes("Test")
    });
    cr.Save();

    var y = cr.FindBy(x => x.CultureCode == cultureCode && x.CreatedDate == createdDate).FirstOrDefault();
    Assert.IsNotNull(y);

The Assert.IsNotNull is failing because of the datetime check. I would expect that as the LanguageDictionary instance is created with the variable's value that the two would be equal. This is using Telerik.OpenAccess and MSSQL as a DB layer so I'm assuming the problem comes in there. Can anyone tell me if there is anything I'm missing with this and how to correctly compare these values.

EDIT: The tick values are different but I don't know why as they both come from the same variable which I only assign to once.

like image 661
Ash Avatar asked Apr 17 '13 08:04

Ash


People also ask

Can you compare Datetimes?

Compare() method in C# is used for comparison of two DateTime instances. It returns an integer value, <0 − If date1 is earlier than date2. 0 − If date1 is the same as date2.

How to check 2 dates are equal in C#?

The DateTime. Equals() method in C# is used check whether two DateTime objects or instances are equal or not. TRUE is returned if both are equal, else FALSE would be the return value.

How does Python compare hours and minutes?

You can use datetime. timedelta to do the comparisons reliably. You can specify a delta in different units of time (hours, minutes, seconds, etc.) Then you don't have to worry about converting to hours, minutes, etc.


2 Answers

Try using DateTime.Equals(x.CreatedDate, createdDate), it might help.

Other than that, proper DateTime comparing is a massively complicated subject with timezones, offsets, utc, local time and whatnot. I wouldn't at all be suprised at a simple == compare between two seemingly identical dates to return false.

If the Ticks value differs on write and read, you're might be facing a DateTimeKind problem, where you're writing a DateTimeKind.Local to the database, but getting back an DateTimeKind.Unspecified.

The other option could be (if the difference is small enough) that the DateTime field in your database is not significant enough to store the same amount of milliseconds as the .net DateTime:

A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.

Depending on your data storage, it might not be as detailed as this. Your DateTime values do not come from the same source, one is read from memory, the other is read from database.

like image 191
Willem Avatar answered Oct 10 '22 05:10

Willem


SqlServer stores a datetime in (about) 3-millisecond increments.

datetime values are rounded to increments of .000, .003, or .007 seconds

A roundtrip of a DateTime through the database could thus be off by a few ms.

So you should not test for "exactly equal", but for "close enough"

var y = cr.FindBy(x => x.CultureCode == cultureCode && 
                    x.CreatedDate >= createdDate.AddMilliseconds(-5) && 
                    x.CreatedDate <= createdDate.AddMilliseconds(5))
     .FirstOrDefault();
like image 38
Hans Kesting Avatar answered Oct 10 '22 05:10

Hans Kesting