DateTime Comparison Precision

后端 未结 10 527
攒了一身酷
攒了一身酷 2020-12-29 04:24

I\'m doing DateTime comparison but I don\'t want to do comparison at second, millisecond and ticks level. What\'s the most elegant way?

If I simply compare the DateT

相关标签:
10条回答
  • 2020-12-29 04:48

    You can convert them to String format and compare the string with each other.

    This also gives freedom to choose your comparison parameters, like only the time without the date, etc.

    if (String.Format("{0:ddMMyyyyHHmmss}", date1) == String.Format("{0:ddMMyyyyHHmmss}", date2))
    {
         // success
    }
    
    0 讨论(0)
  • 2020-12-29 04:50

    Another way is to convert first by processing on ticks level with a simple (non-rounding) calculation:

    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
    
    0 讨论(0)
  • 2020-12-29 04:52
    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);
        }
    }
    

    Usage example:

    new DateTimeComparer(DateTimeComparer.Prescision.Day).Compare(Date1, Date2)
    
    0 讨论(0)
  • 2020-12-29 04:56

    @ALZ's solution looks nice but it's too complicated and has a bug. So I decided to combine it with @ChrisF's solution.

        public class DateTimeComparer : Comparer<DateTime>
        {
            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);
            }
        }
    
    0 讨论(0)
提交回复
热议问题