比较两个日期时间时忽略毫秒

Ero*_*lli 69 c# datetime c#-4.0

这可能是一个愚蠢的问题,但我似乎无法弄明白.我正在比较两个文件的LastWriteTime,但是它总是失败,因为我从网上下载的文件总是将毫秒设置为0,而我的原始文件有一个实际值.在比较时是否有一种忽略毫秒的简单方法?

这是我的功能:

//compare file's dates
public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
{
     DateTime dtOrig = File.GetLastWriteTime(strOrigFile);
     DateTime dtNew = File.GetLastWriteTime(strDownloadedFile);

     if (dtOrig == dtNew)
        return true;
     else
        return false;
}
Run Code Online (Sandbox Code Playgroud)

提前致谢

Dea*_*alk 87

我建议你使用扩展方法:

public static DateTime TrimMilliseconds(this DateTime dt)
{
    return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, 0, dt.Kind);
}
Run Code Online (Sandbox Code Playgroud)

那就是:

if (dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds())
Run Code Online (Sandbox Code Playgroud)

  • 也许通过将`dt.Kind`添加到ctor的结尾来保留`DateTimeKind` (3认同)
  • 返回new DateTime(dt.Year,dt.Month,dt.Day,dt.Hour,dt.Minute,dt.Second,0,dt.Kind); (3认同)

dtb*_*dtb 41

创建一个新的DateTime值,并将毫秒组件设置为0:

dt = dt.AddMilliseconds(-dt.Millisecond);
Run Code Online (Sandbox Code Playgroud)

  • 警告:当`DateTime`具有非零微秒时,这将不起作用.请参阅@ PeterIvan's或@DenielChalk的答案. (22认同)

Pet*_*van 38

如果dt具有非零微秒(毫安分数),则应该小心.仅将毫秒设置为零是不够的.
要将millis和以下设置为零(并获得成功的比较),代码将为:

dt = dt.AddTicks(-dt.Ticks % TimeSpan.TicksPerSecond); // TimeSpan.TicksPerSecond=10000000
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的解决方案。快速,并保留“dt.Kind”。我知道它在所有情况下都会给出相同的结果,但对我来说,使用 `dt = dt.AddTicks(-(dt.Ticks % TimeSpan.TicksPerSecond));` 更自然,即首先使用 `%` 运算符,然后使用否定。这是因为第一个操作数为负的 % 的行为对我来说似乎有点令人困惑,所以我更喜欢我的版本,其中 % 操作两个正操作数。 (2认同)

Pau*_*ane 26

TimeSpan difference = dtNew - dtOrig;
if (difference >= TimeSpan.FromSeconds(1))
{
    ...
}
Run Code Online (Sandbox Code Playgroud)


San*_*har 14

你可以减去它们,得到一个TimeSpan.

然后用 TimeSpan.totalSeconds()


dee*_*ee1 6

对于单个截断来说,这是过分的,但是如果您有多种类型,则可以使用下面的通用扩展方法来做到这一点:

DateTime dtSecs = DateTime.Now.TruncateTo(Extensions.DateTruncate.Second);
DateTime dtHrs  = DateTime.Now.TruncateTo(Extensions.DateTruncate.Hour);
Run Code Online (Sandbox Code Playgroud)

更通用的使用扩展方法:

    public static DateTime TruncateTo(this DateTime dt, DateTruncate TruncateTo)
    {
        if (TruncateTo == DateTruncate.Year)
            return new DateTime(dt.Year, 0, 0);
        else if (TruncateTo == DateTruncate.Month)
            return new DateTime(dt.Year, dt.Month, 0);
        else if (TruncateTo == DateTruncate.Day)
            return new DateTime(dt.Year, dt.Month, dt.Day);
        else if (TruncateTo == DateTruncate.Hour)
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0);
        else if (TruncateTo == DateTruncate.Minute)
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
        else 
            return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);

    }
    public enum DateTruncate
    {
        Year,
        Month,
        Day,
        Hour,
        Minute,
        Second
    }
Run Code Online (Sandbox Code Playgroud)

  • 使用彼得·伊凡(Peter Ivan)的解决方案,很自然就可以`执行公共静态DateTime TruncateTo(此DateTime dt,长truncateResolution){return dt.AddTicks(-(dt.Ticks%truncateResolution))); }`。更短更清晰。然后像这样使用:`DateTime dtSecs = DateTime.Now.TruncateTo(TimeSpan.TicksPerSecond); DateTime dtHrs = DateTime.Now.TruncateTo(TimeSpan.TicksPerHour);等。您甚至可以截断到更奇怪的分辨率,例如3小时的倍数(`3 * TimeSpan.TicksPerHour`)。 (4认同)

小智 5

这是执行此操作的最简单方法。precision你可以随心所欲地控制。

bool AreEqual(DateTime a, DateTime b, TimeSpan precision)
{
    return Math.Abs((a - b).TotalMilliseconds) < precision.TotalMilliseconds;
}
Run Code Online (Sandbox Code Playgroud)

并且用法是不言自明的

var _ = AreEqual(a, b, precision: TimeSpan.FromSeconds(1));
Run Code Online (Sandbox Code Playgroud)