95

I'm trying to work out if an account expires in less than 30 days. Am I using DateTime Compare correctly?

if (DateTime.Compare(expiryDate, now) < 30)

{
     matchFound = true;
}
David Basarab
  • 72,212
  • 42
  • 129
  • 156

15 Answers15

261

Am I using DateTime Compare correctly?

No. Compare only offers information about the relative position of two dates: less, equal or greater. What you want is something like this:

if ((expiryDate - DateTime.Now).TotalDays < 30)
    matchFound = true;

This subtracts two DateTimes. The result is a TimeSpan object which has a TotalDays property.

Additionally, the conditional can be written directly as:

bool matchFound = (expiryDate - DateTime.Now).TotalDays < 30;

No if needed.

Alternatively, you can avoid naked numbers by using TimeSpan.FromDays:

bool matchFound = (expiryDate - DateTime.Now) < TimeSpan.FromDays(30);

This is slightly more verbose but I generally recommend using the appropriate types, and the appropriate type in this case is a TimeSpan, not an int.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
16

should be

matchFound = (expiryDate - DateTime.Now).TotalDays < 30;

note the total days otherwise you'll get werid behaviour

Luke
  • 3,375
  • 2
  • 22
  • 22
  • this answer was over a year after the last edit to accepted answer! – Mitch Wheat Jan 12 '13 at 01:23
  • @Mitch - This is the correct answer, notice he is using TotalDays rather than Days. – Marcelo Mason Jan 20 '13 at 22:42
  • The accepted answer is correct. TotalDays returns a fractional portion as well, which is redundant when comparing to an integer. – Mitch Wheat Jan 20 '13 at 23:57
  • 1
    @MitchWheat `TotalDays` is **conceptually** correct field to use. In practice they give the same result but only because `Days` is the biggest component of `TimeSpan`, had there been a Months or Years component and this would have been a different story. Just try with `Hours`, `Seconds` or `Milliseconds` to see how they work. – João Portela Feb 20 '13 at 10:40
7

Well I would do it like this instead:

TimeSpan diff = expiryDate - DateTime.Today;
if (diff.Days > 30) 
   matchFound = true;

Compare only responds with an integer indicating weather the first is earlier, same or later...

haqwin
  • 377
  • 3
  • 12
5

Try this instead

if ( (expiryDate - DateTime.Now ).TotalDays < 30 ) { 
  matchFound = true;
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 1
    Hmm, you need to either invert the order of your dates or take the absolute value, unless the expiration date is already passed. – Konrad Rudolph Feb 09 '09 at 14:45
3

Compare returns 1, 0, -1 for greater than, equal to, less than, respectively.

You want:

    if (DateTime.Compare(expiryDate, DateTime.Now.AddDays(30)) <= 0) 
    { 
        bool matchFound = true;
    }
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
1

Assuming you want to assign false (if applicable) to matchtime, a simpler way of writing it would be..

matchtime = ((expiryDate - DateTime.Now).TotalDays < 30);
Magic Mick
  • 1,475
  • 1
  • 21
  • 32
  • The ternary operator here is completely redundant as ((expiryDate - DateTime.Now).TotalDays < 30) already returns a boolean. – Fabio Aug 30 '19 at 12:35
  • @Fabio Thanks buddy removed them to assign the Boolean value via the return type. – Magic Mick Sep 03 '19 at 04:10
1

This will give you accurate result :

if ((expiryDate.Date - DateTime.Now.Date).Days < 30)
    matchFound = true;
JPBlanc
  • 70,406
  • 17
  • 130
  • 175
Jayant
  • 11
  • 1
  • actually what happens hr is eg.expryDte is 28/4/2011 if U rite (expiryDate-DateTime.now) it will take the time as well (28/4/2011 12:00:00 AM - 26/4/2011 11:47:00 AM) & above code takes value as 28/4/2011 12:00:00 AM -26/4/2011 12:00:00 AM which ill give accurate difference. – Jayant May 03 '11 at 09:29
0
// this isn't set up for good processing.  
//I don't know what data set has the expiration 
//dates of your accounts.  I assume a list.
// matchfound is a single variablethat returns true if any 1 record is expired.

bool matchFound = false;
            DateTime dateOfExpiration = DateTime.Today.AddDays(-30);
            List<DateTime> accountExpireDates = new List<DateTime>();
            foreach (DateTime date in accountExpireDates)
            {
                if (DateTime.Compare(dateOfExpiration, date) != -1)
                {
                    matchFound = true;
            }
            }
Alex
  • 1
  • 1
    Isn't that a bit complicated? – Max Sep 27 '12 at 12:28
  • Where is the mention of accountExpireDates in the question? You copy pasted a bad solution. matchFound almost sounds like you're mixing Pattern or RegEx. Btw, you need to break when a match is found or it continues to loop. Also what if it is -2? MSDN does not say the possible values are -1, 0 and 1. – Mukus Feb 11 '14 at 01:19
0

No, the Compare function will return either 1, 0, or -1. 0 when the two values are equal, -1 and 1 mean less than and greater than, I believe in that order, but I often mix them up.

Timothy Carter
  • 15,459
  • 7
  • 44
  • 62
0

No you are not using it correctly.

See here for details.

DateTime t1 = new DateTime(100);
DateTime t2 = new DateTime(20);

if (DateTime.Compare(t1, t2) >  0) Console.WriteLine("t1 > t2"); 
if (DateTime.Compare(t1, t2) == 0) Console.WriteLine("t1 == t2"); 
if (DateTime.Compare(t1, t2) <  0) Console.WriteLine("t1 < t2");
David Basarab
  • 72,212
  • 42
  • 129
  • 156
0

What you want to do is subtract the two DateTimes (expiryDate and DateTime.Now). This will return an object of type TimeSpan. The TimeSpan has a property "Days". Compare that number to 30 for your answer.

GWLlosa
  • 23,995
  • 17
  • 79
  • 116
0

No it's not correct, try this :

DateTime expiryDate = DateTime.Now.AddDays(-31);
if (DateTime.Compare(expiryDate, DateTime.Now.AddDays(-30)) < 1)
{
    matchFound = true;
}
Canavar
  • 47,715
  • 17
  • 91
  • 122
0

You can try to do like this:

var daysPassed = (DateTime.UtcNow - expiryDate).Days;
if (daysPassed > 30)
{ 
    // ...
}
vlad
  • 11
  • 2
0

Actually none of these answers worked for me. I solved it by doing like this:

  if ((expireDate.Date - DateTime.Now).Days > -30)
  {
    matchFound = true;
  }

When i tried doing this:

matchFound = (expiryDate - DateTime.Now).Days < 30;

Today, 2011-11-14 and my expiryDate was 2011-10-17 i got that matchFound = -28. Instead of 28. So i inversed the last check.

SBergstrom
  • 59
  • 1
  • 5
-1

Compare is unnecessary, Days / TotalDays are unnecessary.

All you need is

if (expireDate < DateTime.Now) {
    // has expired
} else {
    // not expired
}

note this will work if you decide to use minutes or months or even years as your expiry criteria.

rob
  • 8,134
  • 8
  • 58
  • 68
  • 1
    Not a great answer because now you are also factoring in hours, minutes and seconds. DateTime.Today would be more correct for the OPs situation. – JL. Nov 07 '11 at 13:59