在C#中比较两个DateTime的相等性的最佳方法是什么?但只有一定的精度?

我有两个日期时间,一个来自时间戳,另一个是我在代码中生成的。 我需要测试他们的平等,并希望在没有太多表达的情况下做到这一点。 这是我的两个日期的一个例子:

DateTime expireTimeStampUTC = DateTime.Parse(UTCValueFromDatabase)); DateTime expectedExpireTime = DateTime.UtcNow.AddHours(NumberOfExpectedHoursInConfig); 

这是一个测试精度太高:

if(expireTimeStampUTC.Equals(expectedExpireTime)){}

我不在乎他们是否与第二小时一样精确。

它可能是做这样复合的最佳解决方案:

 if (expireTimeStampUTC.Date.Equals(expectedExpireTime.Date)) { if (!expireTimeStampUTC.Hour.Equals(expectedExpireTime.Hour)) { pass = false; } } 

我不是最有经验的C#…是否有一些优雅的方法来做到这一点?

如果您遇到的问题是因为它们是数据库类型,您可以转换为该类型并进行比较,我们会在大约1/3的数据库保存中丢失/获得大约一毫秒的转换为SQLDateTimes。

如果没有,请比较您实际关注的单位:

 DateTime dt1 = DateTime.UtcNow; DateTime dt2 = DateTime.UtcNow.AddMinutes(59); // or 1 or 61 for test values; // if the dates are in the same hour (12:10 == 12:50, 1:58 != 2:02) if(dt1.Hour == dt2.Hour) // result 

或者如果你关心它们是在一小时的时间范围内

 // if the dates are within one hour of each other (1:58 == 2:02, 3:30 != 4:45) if((dt1 - dt2).Duration() < TimeSpan.FromHours(1)) // result 

这里减去日期会产生一个时间跨度,持续时间是'绝对值',然后我们从我们关心的单位(FromHours)明确地创建限制并进行比较。

最后一行是尽可能干净的,我认为在特定的时间跨度内做平等。

如何找到两小时之间的差异,并查看它是否低于某个阈值(例如一小时3600秒)?

 var diff = expireTimeStamp.Subtract(expectedExpireTime).TotalSeconds; pass = Math.Abs(diff) < 3600; 

减去它们。 检查生成的TimeSpan是否在特定的最大范围内。

构造新的DateTime对象并进行比较。 在C#中,以这种方式构造“一次性”对象的惩罚很小。

我在尝试编写提交然后检索的业务对象的unit testing时遇到了问题。 我试图使用我的对象的“StartTime”属性来确保可以检索对象并遇到此问题。 数据库中提交的“StartTime”值在Ticks值中丢失了6位精度!

以下是我重写测试条件的方法,以便我的测试能够正确执行并通过。 相关行是块的倒数第二行。

 DateTime start = DateTime.Now; NewEventInfo testEvent1 = FakeEvent("test01action", start); //plus other params for testing mServiceClient.AddEvent(testEvent1); EventInfo[] eventInfos = null; //code to get back events within time window Assert.IsNotEmpty(eventInfos); Assert.GreaterOrEqual(eventInfos.Length, 1); EventInfo resultEvent1 = eventInfos.FirstOrDefault(e => e.Action == "test01action" && Math.Abs(e.StartTime.Subtract(testEvent1.StartTime).TotalMilliseconds) < 1000); //checks dates are within 1 sec Assert.IsNotNull(resultEvent1); 

这样我可以确定该对象是unit testing提交的对象,因为EventInfo.StartTime属性仅使用精度为1秒的日期时间。

编辑:添加Math.Abs​​(围绕DateTime差异)以确保将绝对值与1000进行比较。