繁体   English   中英

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

[英]What's the best way to compare the equality of two DateTime's in C#… but only to a certain precision?

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

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# 中,以这种方式构造“一次性”对象的惩罚很少。

我在尝试编写提交然后检索业务对象的单元测试时遇到了这个问题。 我试图使用 object 的“StartTime”属性来确保可以检索 object 并遇到此问题。 数据库中提交的“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);

这样我可以确定 object 是单元测试提交的,因为 EventInfo.StartTime 属性仅使用精度为 1 秒的日期时间。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM