如何在 C# 中比较两个日期的年、月、日、时、分、秒?
How to compare two dates in C# on just year, month, day, hour, minute, second?
我有两个日期,我只想确保它们在这 6 个字段上匹配:
年月日时分秒
我注意到,如果我对这些字段进行匹配的简单相等 == 比较 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;
}
这可能会稍微快一些:
var sameDateTime = ((date1 - date2).Milliseconds < 1000);
您可以删除日期的小数部分(请注意,小数部分比毫秒长):
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
}
您可以实施 扩展 class 以保持主要代码更短和更易读:
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
}
如果您检查 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
我有两个日期,我只想确保它们在这 6 个字段上匹配: 年月日时分秒
我注意到,如果我对这些字段进行匹配的简单相等 == 比较 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;
}
这可能会稍微快一些:
var sameDateTime = ((date1 - date2).Milliseconds < 1000);
您可以删除日期的小数部分(请注意,小数部分比毫秒长):
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
}
您可以实施 扩展 class 以保持主要代码更短和更易读:
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
}
如果您检查 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