如何在 C# 中比较两个日期的年、月、日、时、分、秒?

发布于 2025-01-10 18:55:23 字数 642 浏览 0 评论 0原文

我有两个日期,我只想确保它们在这 6 个字段上匹配: 年、月、日、时、分、秒。

我注意到,如果我执行一个简单的 equal == 比较 if(d1 == d2) 匹配这些字段,我仍然得到“false”。我假设这与与刻度、毫秒等相关的其他字段有关。我如何忽略所有内容并确保它们与上面的 6 个字段匹配?

我创建了下面的原型函数,但对我来说,这对于生产级代码来说感觉很业余且效率低下。此外,date1 必须是可为空的日期时间。

还有其他人有更好的建议吗?

    private static bool DatesAreEqual(DateTime date1, DateTime date2)
    {

        var d1 = new DateTime(date1.Year, date1.Month, date1.Day,
                    date1.Hour, date1.Minute, date1.Second);

        var d2 = new DateTime(date2.Year, date2.Month, date2.Day,
                    date2.Hour, date2.Minute, date2.Second);

        return d1 == d2;
    }

I have two dates and I only want to make sure they match on these 6 fields:
year, month, day, hour, minute and second.

I have noticed that if I perform a simple equality == comparison if(d1 == d2) that match on these fields, I still get 'false'. I'm assuming this has to do with other fields under the hood that relate to ticks, milliseconds etc. How can I ignore everything and just make sure they match on the 6 fields above?

I have created the prototype function below but to me this feels amateurish and inefficient for production-level code. Furthermore, date1 has to be a nullable datetime.

Does anyone else have any better suggestions?

    private static bool DatesAreEqual(DateTime date1, DateTime date2)
    {

        var d1 = new DateTime(date1.Year, date1.Month, date1.Day,
                    date1.Hour, date1.Minute, date1.Second);

        var d2 = new DateTime(date2.Year, date2.Month, date2.Day,
                    date2.Hour, date2.Minute, date2.Second);

        return d1 == d2;
    }

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

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

发布评论

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

评论(3

永不分离 2025-01-17 18:55:24

您可以删除日期的小数部分(请注意,小数部分比毫秒长):

DateTime date = DateTime.Now;

// 28 02 2022 22:19:56.3704625 
Console.WriteLine($"{date:dd MM yyyy HH:mm:ss.fffffff}"); 

date -= TimeSpan.FromTicks(date.Ticks % 10_000_000);

// 28 02 2022 22:19:56.0000000
Console.WriteLine($"{date:dd MM yyyy HH:mm:ss.fffffff}");

代码:

DateTime date1 = ...
DateTime date2 = ...

...

if (date1 - TimeSpan.FromTicks(date1.Ticks % 10_000_000) == 
    date2 - TimeSpan.FromTicks(date2.Ticks % 10_000_000)) {
  //TODO: Relevant code here
}

您可以实现< em>扩展类以保持主代码更短、更具可读性:

public partial static class DateTimeExtensions {
  public static DateTime TrimToSeconds(this DateTime value) => 
    value - TimeSpan.FromTicks(value.Ticks % 10_000_000)
}

然后

DateTime date1 = ...
DateTime date2 = ...

...

if (date1.TrimToSeconds() == date2.TrimToSeconds()) {
  //TODO: Relevant code here
}

You can remove fractional part of the dates (please, note, that fractional part is longer then just milliseconds):

DateTime date = DateTime.Now;

// 28 02 2022 22:19:56.3704625 
Console.WriteLine(
quot;{date:dd MM yyyy HH:mm:ss.fffffff}"); 

date -= TimeSpan.FromTicks(date.Ticks % 10_000_000);

// 28 02 2022 22:19:56.0000000
Console.WriteLine(
quot;{date:dd MM yyyy HH:mm:ss.fffffff}");

Code:

DateTime date1 = ...
DateTime date2 = ...

...

if (date1 - TimeSpan.FromTicks(date1.Ticks % 10_000_000) == 
    date2 - TimeSpan.FromTicks(date2.Ticks % 10_000_000)) {
  //TODO: Relevant code here
}

You can implement extension class to keep main code shorter and more readable:

public partial static class DateTimeExtensions {
  public static DateTime TrimToSeconds(this DateTime value) => 
    value - TimeSpan.FromTicks(value.Ticks % 10_000_000)
}

And then

DateTime date1 = ...
DateTime date2 = ...

...

if (date1.TrimToSeconds() == date2.TrimToSeconds()) {
  //TODO: Relevant code here
}
荆棘i 2025-01-17 18:55:24

如果您检查 TimeSpam,我们会发现 TimeSpan.TicksPerSecond 这是您希望相同的最小值(秒),因此我们将该部分重置为零,并使用刻度进行比较(更快)为:

pubic static bool DatesAreEqual(DateTime d1, DateTime d2)
{
    return (d1.Ticks - (d1.Ticks % TimeSpan.TicksPerSecond)) == (d2.Ticks - (d2.Ticks % TimeSpan.TicksPerSecond));
}

通过这种方式,您只需进行一些数字比较,这是更快的方式。

不仅如此,

基于上面的代码,我还使用选定的 Precision 和 Equal 或 Compare 函数创建了另外两个函数

public enum DateTimeComparePrecision : long
{
    Millisecond  = TimeSpan.TicksPerMillisecond,
    Second = TimeSpan.TicksPerSecond,
    Minute = TimeSpan.TicksPerMinute,
    Hour = TimeSpan.TicksPerHour,
    Day = TimeSpan.TicksPerDay,
}


public static bool DatesAreEqual(DateTime d1, DateTime d2, DateTimeComparePrecision Precision)
{
    return (d1.Ticks - (d1.Ticks % (long)Precision)) == (d2.Ticks - (d2.Ticks % (long)Precision));
}        


public static int DatesCompare(DateTime d1, DateTime d2, DateTimeComparePrecision Precision)
{
    long Day1 = (d1.Ticks - (d1.Ticks % (long)Precision));
    long Day2 = (d2.Ticks - (d2.Ticks % (long)Precision));

    if (Day2 > Day1) 
        return 1;            

    if (Day2 < Day1)            
        return -1;            

    return 0;
}

简单的视觉测试

DateTime NowIs = DateTime.UtcNow;
Console.WriteLine($"{NowIs:dd MM yyyy HH:mm:ss.fffffff}");

DateTime d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerMillisecond)));
Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerSecond)));
Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerMinute)));
Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerHour)));
Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerDay)));
Console.WriteLine($"{d1:dd MM yyyy HH:mm:ss.fffffff}");

输出

01 03 2022 12:51:26.7237323
01 03 2022 12:51:26.7230000
01 03 2022 12:51:26.0000000
01 03 2022 12:51:00.0000000
01 03 2022 12:00:00.0000000
01 03 2022 00:00:00.0000000

If you check on the TimeSpam, we have the TimeSpan.TicksPerSecond that is the minimum that you want to be the same (the seconds), so we reset that part to zero and we make the compare using ticks (that is the faster) as:

pubic static bool DatesAreEqual(DateTime d1, DateTime d2)
{
    return (d1.Ticks - (d1.Ticks % TimeSpan.TicksPerSecond)) == (d2.Ticks - (d2.Ticks % TimeSpan.TicksPerSecond));
}

With this way you just make some number compare and its the faster way.

More Than That

Base on the above code I also make two more functions with selected Precision and Equal, or Compare functions

public enum DateTimeComparePrecision : long
{
    Millisecond  = TimeSpan.TicksPerMillisecond,
    Second = TimeSpan.TicksPerSecond,
    Minute = TimeSpan.TicksPerMinute,
    Hour = TimeSpan.TicksPerHour,
    Day = TimeSpan.TicksPerDay,
}


public static bool DatesAreEqual(DateTime d1, DateTime d2, DateTimeComparePrecision Precision)
{
    return (d1.Ticks - (d1.Ticks % (long)Precision)) == (d2.Ticks - (d2.Ticks % (long)Precision));
}        


public static int DatesCompare(DateTime d1, DateTime d2, DateTimeComparePrecision Precision)
{
    long Day1 = (d1.Ticks - (d1.Ticks % (long)Precision));
    long Day2 = (d2.Ticks - (d2.Ticks % (long)Precision));

    if (Day2 > Day1) 
        return 1;            

    if (Day2 < Day1)            
        return -1;            

    return 0;
}

Simple Visual Test

DateTime NowIs = DateTime.UtcNow;
Console.WriteLine(
quot;{NowIs:dd MM yyyy HH:mm:ss.fffffff}");

DateTime d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerMillisecond)));
Console.WriteLine(
quot;{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerSecond)));
Console.WriteLine(
quot;{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerMinute)));
Console.WriteLine(
quot;{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerHour)));
Console.WriteLine(
quot;{d1:dd MM yyyy HH:mm:ss.fffffff}");

d1 = new DateTime((NowIs.Ticks - (NowIs.Ticks % TimeSpan.TicksPerDay)));
Console.WriteLine(
quot;{d1:dd MM yyyy HH:mm:ss.fffffff}");

output

01 03 2022 12:51:26.7237323
01 03 2022 12:51:26.7230000
01 03 2022 12:51:26.0000000
01 03 2022 12:51:00.0000000
01 03 2022 12:00:00.0000000
01 03 2022 00:00:00.0000000
愿与i 2025-01-17 18:55:24

这可能会稍微快一些:

var sameDateTime = ((date1 - date2).Milliseconds < 1000);

https://stackoverflow.com/a/58173628/759558

This might be slightly quicker:

var sameDateTime = ((date1 - date2).Milliseconds < 1000);

https://stackoverflow.com/a/58173628/759558

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