DateTime比较精度

我正在进行DateTime比较,但我不想在秒,毫秒和刻度级别进行比较。 什么是最优雅的方式?

如果我只是比较DateTime,那么由于刻度差异,它们很少相等。

那么使用时间跨度呢?

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 } 

我个人认为这更优雅......

一种方法可能是从您想要比较的值创建两个新的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); 

我是第一个承认它不优雅的人,但它解决了这个问题。

使用TimeSpan,您可以获得所需的所有粒度:

 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 { private Prescision _Prescision; public enum Prescision : sbyte { Millisecons, Seconds, Minutes, Hour, Day, Month, Year, Ticks } Func[] actions = new Func[] { (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) 

这个ComparerClass怎么样?

 public class DateTimeComparer : Comparer { 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")); 

您可以将它们转换为String格式并将字符串相互比较。

这也可以自由选择比较参数,例如只有没有日期的时间等。

 if (String.Format("{0:ddMMyyyyHHmmss}", date1) == String.Format("{0:ddMMyyyyHHmmss}", date2)) { // success } 

我写这篇文章是为了帮助自己:

  internal class ImpreciseCompareDate : IComparer { 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秒。 如果超出容差,则委托默认比较器。

另一种方法是首先通过简单(非舍入)计算在ticks级别上进行处理:

 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 

@ALZ的解决方案看起来不错,但它太复杂并且有一个bug。 所以我决定将它与@ ChrisF的解决方案结合起来。

  public class DateTimeComparer : Comparer { public enum Precision { Years = 0, Months, Days, Hours, Minutes, Seconds, Millisecons, Ticks } private Precision _precision; public DateTimeComparer(Precision precision = Precision.Ticks) { _precision = precision; } public override int Compare(DateTime x, DateTime y) { if (_precision == Precision.Ticks) { return x.CompareTo(y); } var xx = AssembleValue(x, _precision); var yy = AssembleValue(y, _precision); return xx.CompareTo(yy); } private static DateTime AssembleValue(DateTime input, Precision precision) { var p = (int)precision; var i = 1; return new DateTime(input.Year, p >= i++ ? input.Month : 1, p >= i++ ? input.Day : 1, p >= i++ ? input.Hour : 0, p >= i++ ? input.Minute : 0, p >= i++ ? input.Second : 0, p >= i++ ? input.Millisecond : 0); } } 

我自己的代码非常简单的解决方案:

 TimeSpan timeDifference = presentLastSavedDate.Subtract(previousLastSavedDate); if (timeDifference.Seconds > 0) { return Content(HttpStatusCode.Conflict, ALREADY_CHANGED_MSG); }