繁体   English   中英

C#DateTime比较准确性和舍入

[英]C# DateTime comparisons accuracy and rounding

我有两个约会。 一个由用户提供并准确到第二个和一个从数据库并准确到刻度级别。 这意味着当他们都代表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);

是否有更优雅的方式来实现这一目标?

最明显的重构是删除重复:

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)
   ...

相信这会奏效,因为刻度0是在一秒的开始。

当然,你应该小心所有这些的时区方面。 您可能需要考虑使用DateTimeOffset

你能试一下吗

UserDateTime.Substract(dbDateTime).TotalSeconds == 0

我减去它们,得到一个TimeSpan对象。 然后取该差值的值(或差值的绝对值,以适合您的为准),并将其与小阈值(如0.002s)进行比较。

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...
}

与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;
}

它将帮助您解决问题,应该在基本库中:-)

您可以使用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下

暂无
暂无

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

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