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

发布于 2024-11-29 06:19:29 字数 458 浏览 1 评论 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;
}

I am comparing the LastWriteTime of two files, however it is always failing because the file I downloaded off the net always has milliseconds set at 0, and my original file has an actual value. Is there a simple way to ignore the milliseconds when comparing?

Here's my function:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

做个ˇ局外人 2024-12-06 06:19:29

我建议您使用扩展方法:

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

那么它只是:

if (dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds())

I recommend you use an extension method:

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

then its just:

if (dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds())
神仙妹妹 2024-12-06 06:19:29

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

dt = dt.AddTicks(-dt.Ticks % TimeSpan.TicksPerSecond); // TimeSpan.TicksPerSecond=10000000

Care should be taken, if dt has non-zero microseconds (fractions of millis). Setting only milliseconds to zero is not enough.
To set millis and below to zero (and get a succesfull comparison), the code would be:

dt = dt.AddTicks(-dt.Ticks % TimeSpan.TicksPerSecond); // TimeSpan.TicksPerSecond=10000000
离不开的别离 2024-12-06 06:19:29

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

dt = dt.AddMilliseconds(-dt.Millisecond);

Create a new DateTime value with the milliseconds component set to 0:

dt = dt.AddMilliseconds(-dt.Millisecond);
我最亲爱的 2024-12-06 06:19:29
TimeSpan difference = dtNew - dtOrig;
if (difference >= TimeSpan.FromSeconds(1))
{
    ...
}
TimeSpan difference = dtNew - dtOrig;
if (difference >= TimeSpan.FromSeconds(1))
{
    ...
}
与往事干杯 2024-12-06 06:19:29

您可以将它们相减,以获得TimeSpan

然后使用TimeSpan.totalSeconds()

You can subtract them, to get a TimeSpan.

Then use TimeSpan.totalSeconds()

无妨# 2024-12-06 06:19:29

对于单个截断来说,这有点过分了,但是如果您有多个不同类型的截断,则可以使用下面的通用扩展方法来执行此操作:

DateTime dtSecs = DateTime.Now.TruncateTo(Extensions.DateTruncate.Second);
DateTime dtHrs  = DateTime.Now.TruncateTo(Extensions.DateTruncate.Hour);

更通用 使用扩展方法:

    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
    }

This is overkill for a single Truncate, but if you have several and of various types you could do this using the generalized Extension Method below:

DateTime dtSecs = DateTime.Now.TruncateTo(Extensions.DateTruncate.Second);
DateTime dtHrs  = DateTime.Now.TruncateTo(Extensions.DateTruncate.Hour);

More general Use Extension method:

    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
    }
一片旧的回忆 2024-12-06 06:19:29

这是执行此操作的最简单方法。您可以根据需要控制精度

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

并且用法是不言自明的

var _ = AreEqual(a, b, precision: TimeSpan.FromSeconds(1));

Here is the simplest way of doing this. You can control precision as you want.

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

and usage is pretty self-explanatory

var _ = AreEqual(a, b, precision: TimeSpan.FromSeconds(1));
淡淡離愁欲言轉身 2024-12-06 06:19:29

一种方法是创建新日期,将年、月、日、小时、分钟、秒输入到构造函数中。或者,您可以简单地分别比较每个值。

One way would be to create new dates, inputting the year, month, day, hour, minute, second into the constructor. Alternatively, you could simply compare each value separately.

折戟 2024-12-06 06:19:29

不要通过创建新的 DateTime 来修剪不相关的 DateTime 部分,而是仅比较相关的部分:

public static class Extensions
{
    public static bool CompareWith(this DateTime dt1, DateTime dt2)
    {
        return
            dt1.Second == dt2.Second && // 1 of 60 match chance
            dt1.Minute == dt2.Minute && // 1 of 60 chance
            dt1.Day == dt2.Day &&       // 1 of 28-31 chance
            dt1.Hour == dt2.Hour &&     // 1 of 24 chance
            dt1.Month == dt2.Month &&   // 1 of 12 chance
            dt1.Year == dt2.Year;       // depends on dataset
    }
}

我采用了 Dean Chalk 的回答作为性能比较的基础,结果是:

  • CompareWithTrimMilliseconds 快一点在相同日期的情况下

  • CompareWith 比日期不相等

我的性能测试(在控制台项目中运行)

static void Main(string[] args)
{
    var dtOrig = new DateTime(2018, 03, 1, 10, 10, 10);
    var dtNew = dtOrig.AddMilliseconds(100);

    //// perf run for not-equal dates comparison
    //dtNew = dtNew.AddDays(1);
    //dtNew = dtNew.AddMinutes(1);

    int N = 1000000;

    bool isEqual = false;

    var sw = Stopwatch.StartNew();
    for (int i = 0; i < N; i++)
    {
        // TrimMilliseconds comes from 
        // https://stackoverflow.com/a/7029046/1506454 
        // answer by Dean Chalk
        isEqual = dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds();
    }
    var ms = sw.ElapsedMilliseconds;
    Console.WriteLine("DateTime trim: " + ms + " ms");

    sw = Stopwatch.StartNew();
    for (int i = 0; i < N; i++)
    {
        isEqual = dtOrig.CompareWith(dtNew);
    }
    ms = sw.ElapsedMilliseconds;
    Console.WriteLine("DateTime partial compare: " + ms + " ms");

    Console.ReadKey();
}

instead of trimming unrelevant DateTime parts via creating new DateTimes, compare only relevant parts:

public static class Extensions
{
    public static bool CompareWith(this DateTime dt1, DateTime dt2)
    {
        return
            dt1.Second == dt2.Second && // 1 of 60 match chance
            dt1.Minute == dt2.Minute && // 1 of 60 chance
            dt1.Day == dt2.Day &&       // 1 of 28-31 chance
            dt1.Hour == dt2.Hour &&     // 1 of 24 chance
            dt1.Month == dt2.Month &&   // 1 of 12 chance
            dt1.Year == dt2.Year;       // depends on dataset
    }
}

I took answer by Dean Chalk as base for performance comparison, and results are:

  • CompareWith is a bit faster than TrimMilliseconds in case of equal dates

  • CompareWith is a faster than dates are not equal

my perf test (run in Console project)

static void Main(string[] args)
{
    var dtOrig = new DateTime(2018, 03, 1, 10, 10, 10);
    var dtNew = dtOrig.AddMilliseconds(100);

    //// perf run for not-equal dates comparison
    //dtNew = dtNew.AddDays(1);
    //dtNew = dtNew.AddMinutes(1);

    int N = 1000000;

    bool isEqual = false;

    var sw = Stopwatch.StartNew();
    for (int i = 0; i < N; i++)
    {
        // TrimMilliseconds comes from 
        // https://stackoverflow.com/a/7029046/1506454 
        // answer by Dean Chalk
        isEqual = dtOrig.TrimMilliseconds() == dtNew.TrimMilliseconds();
    }
    var ms = sw.ElapsedMilliseconds;
    Console.WriteLine("DateTime trim: " + ms + " ms");

    sw = Stopwatch.StartNew();
    for (int i = 0; i < N; i++)
    {
        isEqual = dtOrig.CompareWith(dtNew);
    }
    ms = sw.ElapsedMilliseconds;
    Console.WriteLine("DateTime partial compare: " + ms + " ms");

    Console.ReadKey();
}
聆听风音 2024-12-06 06:19:29

Ether 将其他日期时间中的毫秒设置为零,或者从另一个日期中减去一个日期,然后仅检查结果时间跨度的 TotalMinutes 属性。

Ether set the milliseconds in your other datetime to zero, or subtract one date from the other and just check the TotalMinutes property of the resulting time span.

药祭#氼 2024-12-06 06:19:29

您可以创建一个扩展方法,将 DateTime 对象的毫秒设置为零

public static DateTime ZeroMilliseconds(this DateTime value) {
  return new DateTime(value.Year, value.Month, value.Day, 
    value.Hours, value.Minutes, value.Seconds);
}

然后在您的函数中

 if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds())
        return true;
     else
        return false;

You could create an extension method that would set the milliseconds to zero for a DateTime object

public static DateTime ZeroMilliseconds(this DateTime value) {
  return new DateTime(value.Year, value.Month, value.Day, 
    value.Hours, value.Minutes, value.Seconds);
}

Then in your function

 if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds())
        return true;
     else
        return false;
德意的啸 2024-12-06 06:19:29

只需将日期时间格式与您想要的格式一起使用,然后将其再次转换为日期时间,如下所示,

//compare file's dates
        
        String format1 = @"yyyy-MM-dd HH:mm:ss"; // you also can avoid seconds if you want

        public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
        {
            
            //.here we will use the format

            DateTime dtOrig = Convert.ToDateTime(File.GetLastWriteTime(strOrigFile).ToString(format1));
            DateTime dtNew = Convert.ToDateTime(File.GetLastWriteTime(strDownloadedFile).ToString(format1));

            if (dtOrig == dtNew)
                return true;
            else
                return false;
        }

Simply you can use datetime format with the format you want, and convert it again to datetime as below,

//compare file's dates
        
        String format1 = @"yyyy-MM-dd HH:mm:ss"; // you also can avoid seconds if you want

        public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
        {
            
            //.here we will use the format

            DateTime dtOrig = Convert.ToDateTime(File.GetLastWriteTime(strOrigFile).ToString(format1));
            DateTime dtNew = Convert.ToDateTime(File.GetLastWriteTime(strDownloadedFile).ToString(format1));

            if (dtOrig == dtNew)
                return true;
            else
                return false;
        }
尽揽少女心 2024-12-06 06:19:29

转换可排序字符串并进行比较。简单且运行良好。

    return string.Compare(dtOrig.ToString("s"), dtNew.ToString("s"), 
StringComparison.Ordinal) == 0;

cast sortable strings and compare. simple and run well.

    return string.Compare(dtOrig.ToString("s"), dtNew.ToString("s"), 
StringComparison.Ordinal) == 0;
反目相谮 2024-12-06 06:19:29

截断时间最直接的方法是对其进行格式化并解析所需的单位:

var myDate = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"));

重写 DOK 的方法

public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
    {
         DateTime dtOrig = DateTime.Parse(File.GetLastWriteTime(strOrigFile).ToString("MM/dd/yyyy hh:mm:ss"));
         DateTime dtNew = DateTime.Parse(File.GetLastWriteTime(strDownloadedFile).ToString("MM/dd/yyyy hh:mm:ss"));

         if (dtOrig == dtNew)
            return true;
         else
            return false;
    }

The most straightforward way to truncate time is to format it and parse on the units that you want:

var myDate = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss"));

DOK's method re-written

public bool CompareByModifiedDate(string strOrigFile, string strDownloadedFile)
    {
         DateTime dtOrig = DateTime.Parse(File.GetLastWriteTime(strOrigFile).ToString("MM/dd/yyyy hh:mm:ss"));
         DateTime dtNew = DateTime.Parse(File.GetLastWriteTime(strDownloadedFile).ToString("MM/dd/yyyy hh:mm:ss"));

         if (dtOrig == dtNew)
            return true;
         else
            return false;
    }
就此别过 2024-12-06 06:19:29

不知道为什么几乎所有程序员都需要额外的行来从带有 bool 表达式的函数返回 bool 值。

相反,

if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds())
    return true;
 else
    return false;

您始终可以只使用

return dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds()

if 表达式为 true 则返回 true else false。

Don't know why almost all programmers needs extra lines to return a bool value from a function with a bool expression.

instead

if (dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds())
    return true;
 else
    return false;

you can always just use

return dtOrig.ZeroMilliseconds() == dtNew.ZeroMilliseconds()

if the expression is true it returns true else false.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文