我正在进行DateTime比较,但我不想在秒、毫秒和ticks级别上进行比较。最优雅的方法是什么?
如果我只是简单地比较DateTime,由于ticks差异,它们很少相等。
我正在进行DateTime比较,但我不想在秒、毫秒和ticks级别上进行比较。最优雅的方法是什么?
如果我只是简单地比较DateTime,由于ticks差异,它们很少相等。
使用 TimeSpan 怎么样?
if (Math.Truncate((A - B).TotalMinutes) == 0)
{
//There is less than one minute between them
}
可能不是最优雅的方式,但它允许处理相隔一秒钟但具有不同天/小时/分钟部分(例如越过午夜)的情况。
编辑: 我意识到截断是不必要的...
if (Math.Abs((A - B).TotalMinutes) < 1)
{
//There is less than one minute between them
}
就我个人而言,我认为这更加优雅...
Math.Abs
,否则您可能会在两个 DateTime
值之间有一个巨大的差异。例如 (DateTime.Now - DateTime.Now.AddMinutes(10)).TotalMinutes
将小于 1,但总时间差为 10 分钟。 - Dan HerbertDateTime A = new DateTime(2016, 10, 26, 10, 59, 40), B = new DateTime(2016, 10, 26, 11, 00, 20);
。 - Dmytro Shevchenko一种方法是从你要比较的值中创建两个新的DateTime,但忽略从秒开始以下的任何内容,然后进行比较:
DateTime compare1 = new DateTime(year1, month1, day1, hour1, minute1, 0);
DateTime compare2 = new DateTime(year2, month2, day2, hour2, minute2, 0);
int result = DateTime.Compare(compare1, compare2);
我首先承认这不是优雅的解决方案,但它能解决问题。
public class DateTimeComparer : Comparer<DateTime>
{
private Prescision _Prescision;
public enum Prescision : sbyte
{
Millisecons,
Seconds,
Minutes,
Hour,
Day,
Month,
Year,
Ticks
}
Func<DateTime, DateTime>[] actions = new Func<DateTime, DateTime>[]
{
(x) => { return x.AddMilliseconds(-x.Millisecond);},
(x) => { return x.AddSeconds(-x.Second);},
(x) => { return x.AddMinutes(-x.Minute);},
(x) => { return x.AddHours(-x.Hour);},
(x) => { return x.AddDays(-x.Day);},
(x) => { return x.AddMonths(-x.Month);},
};
public DateTimeComparer(Prescision prescision = Prescision.Ticks)
{
_Prescision = prescision;
}
public override int Compare(DateTime x, DateTime y)
{
if (_Prescision == Prescision.Ticks)
{
return x.CompareTo(y);
}
for (sbyte i = (sbyte)(_Prescision - 1); i >= 0; i--)
{
x = actions[i](x);
y = actions[i](y);
}
return x.CompareTo(y);
}
}
使用示例:
new DateTimeComparer(DateTimeComparer.Prescision.Day).Compare(Date1, Date2)
DateTime dt1, dt2;
double d = (dt2 - dt1).TotalDays;
double h = (dt2 - dt1).TotalHours;
double m = (dt2 - dt1).TotalMinutes;
double s = (dt2 - dt1).TotalSeconds;
double ms = (dt2 - dt1).TotalMilliseconds;
double ticks = (dt2 - dt1).Ticks;
public class DateTimeComparer : Comparer<DateTime>
{
private string _Format;
public DateTimeComparer(string format)
{
_Format = format;
}
public override int Compare(DateTime x, DateTime y)
{
if(x.ToString(_Format) == y.ToString(_Format))
return 0;
return x.CompareTo(y);
}
}
这可以被以下人员使用:
List.Sort(new DateTimeComparer("hh:mm"));
if (String.Format("{0:ddMMyyyyHHmmss}", date1) == String.Format("{0:ddMMyyyyHHmmss}", date2))
{
// success
}
date1.ToString("ddMMyyyyHHmmss") == date2.ToString("ddMMyyyyHHmmss")
。 - Jérôme MEVEL internal class ImpreciseCompareDate : IComparer<DateTime>
{
private readonly double _Tolerance;
public ImpreciseCompareDate(double MillisecondsTolerance)
{
_Tolerance = MillisecondsTolerance;
}
public int Compare(DateTime x, DateTime y)
{
return Math.Abs((x - y).TotalMilliseconds) < _Tolerance ? 0 : x.CompareTo(y);
}
}
公差可以设置为(10d/3d),以考虑 SQL 服务器的1/300毫秒。如果超过公差,则委托给默认比较器。
TimeSpan timeDifference = presentLastSavedDate.Subtract(previousLastSavedDate);
if (timeDifference.Seconds > 0)
{
return Content(HttpStatusCode.Conflict, ALREADY_CHANGED_MSG);
}
var now = DateTime.UtcNow;
// 636340541021531973, 2017-06-26T06:08:22.1531973Z
var millisecondsPrecision = new DateTime(now.Ticks / 10000 * 10000, now.Kind);
// 636340541021530000, 2017-06-26T06:08:22.1530000Z
var secondsPrecision = new DateTime(now.Ticks / 10000000 * 10000000, now.Kind);
// 636340541020000000, 2017-06-26T06:08:22.0000000Z
var minutePrecision = new DateTime(now.Ticks / (10000000*60) * (10000000*60), now.Kind);
// 636340541000000000, 2017-06-26T06:08:00.0000000Z
我已经创建了一个非常快速的比较函数,用于比较不同精度的DateTime。所有计算都是算术计算,没有创建新对象。
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