Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTime Comparison Precision

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 DateTime, then they are seldom equal due to ticks differences.

like image 265
akif Avatar asked Jun 02 '10 10:06

akif


People also ask

Can we compare time in python?

When you have two datetime objects, the date and time one of them represent could be earlier or latest than that of other, or equal. To compare datetime objects, you can use comparison operators like greater than, less than or equal to.

How do you compare hours in Python?

You can use datetime. timedelta to do the comparisons reliably. You can specify a delta in different units of time (hours, minutes, seconds, etc.) Then you don't have to worry about converting to hours, minutes, etc.


7 Answers

What about using a timespan.

if (Math.Truncate((A - B).TotalMinutes) == 0)
{
    //There is less than one minute between them
}

Probably not the most elegant way, but it allows for cases which are one second apart and yet have different days/hours/minutes parts such as going over midnight.

Edit: it occured to me that the truncate is unecessary...

if (Math.Abs((A - B).TotalMinutes) < 1)
{
    //There is less than one minute between them
}

Personally I think this is more elegant...

like image 85
James Barrass Avatar answered Oct 13 '22 11:10

James Barrass


One approach could be to create two new DateTimes from your values you want to compare, but ignore anything from the seconds on down and then compare those:

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);

I'd be the first to admit it's not elegant, but it solves the problem.

like image 34
ChrisF Avatar answered Oct 13 '22 10:10

ChrisF


Using a TimeSpan you get all the granularity you want :

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;
like image 24
hoang Avatar answered Oct 13 '22 09:10

hoang


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)
like image 29
ALZ Avatar answered Oct 13 '22 09:10

ALZ


How about this ComparerClass?

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);
    }
}

This can be used by

List.Sort(new DateTimeComparer("hh:mm"));
like image 42
Oliver Avatar answered Oct 13 '22 09:10

Oliver


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
}
like image 33
The King Avatar answered Oct 13 '22 11:10

The King


I've written this to help myself:

    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);
    }
}

Tolerance can be set to (10d/3d) to account for SQL servers 1/300th of a ms. If tolerance is exceeded, delegate to default comparer.

like image 30
Sprague Avatar answered Oct 13 '22 09:10

Sprague