C# DateTime比较的精度和舍入问题

3

我有两个日期。一个由用户提供,精确到秒,另一个来自数据库,精确到滴答级别。这意味着当它们都代表英国时间的13/11/2009 17:22:17时

userTime == dbTime 

返回false

刻度值为633937297368344183和633937297370000000。

要解决此问题,我使用以下代码:

userTime = new DateTime(
                userTime.Year, 
                userTime.Month, 
                userTime.Day, 
                userTime.Hour, 
                userTime.Minute, 
                userTime.Second);

dbTime = new DateTime(
                dbTime.Year, 
                dbTime.Month, 
                dbTime.Day, 
                dbTime.Hour, 
                dbTime.Minute, 
                dbTime.Second);

有没有更优雅的方法实现这个功能?
5个回答

8
最明显的重构是消除重复:
public static DateTime TruncateToSecond(DateTime original)
{
    return new DateTime(original.Year, original.Month, original.Day,
        original.Hour, original.Minute, original.Second);
}

...
if (TruncateToSecond(userTime) == TruncateToSecond(dbTime))
    ...

您可以尝试写成这样:

你可能会这样写:

if (userTime.Ticks / TimeSpan.TicksPerSecond
    == dbTime.Ticks / TimeSpan.TicksPerSecond)
   ...

我相信这会奏效,因为tick 0在一秒钟的开始。

当然,你需要注意所有这些的时区方面。你可能想考虑使用DateTimeOffset


5

你能试一下吗?

UserDateTime.Substract(dbDateTime).TotalSeconds == 0

1
我将它们相减,得到一个TimeSpan对象。然后取该差异的值(或该差异的绝对值,根据您的需要选择),并将其与一个小阈值进行比较,例如0.002秒。
TimeSpan delta = dt1 - dt2;

// get the delta as an absolute value:
if (delta < new TimeSpan(0, 0, 0))
    delta = new TimeSpan(0, 0, 0) - delta;

// My threshold is 1 second.  The difference can be no more than 1 second. 
TimeSpan threshold = new TimeSpan(0, 0, 1);

if (delta > threshold)
{
    // error...
}

1

非常类似于Cheeso,我编写了这个DateTime扩展,特别用于单元测试:

public static bool IsSimilarTo(this DateTime thisDateTime, DateTime otherDateTime, TimeSpan tolerance)
{
    DateTime allowedMinimum = thisDateTime.Subtract(tolerance);
    DateTime allowedMaximum = thisDateTime.Add(tolerance);

    if (otherDateTime < allowedMinimum || otherDateTime > allowedMaximum)
    {
        return false;
    }

    return true;
}

这将有助于您解决问题,应该在基本库中:-)


0
你可以使用 Microsoft.VisualBasic 命名空间,然后
  DateTime a = new DateTime(633937297368344183L);
  DateTime b = new DateTime(633937297370000000L);

  Console.WriteLine(Microsoft.VisualBasic.DateAndTime.DateDiff(DateInterval.Second, a, b,FirstDayOfWeek.Sunday ,FirstWeekOfYear.System) == 0); //true

在 C# 中似乎需要指定 FirstDayOfWeekFirstWeekOfYear

但在 VB.net 中不需要。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接