DateTime.Compare, как проверить, что дате меньше 30 дней?

86

Я пытаюсь выяснить, истекает ли срок действия учетной записи менее чем через 30 дней. Правильно ли я использую DateTime Compare?

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

{
     matchFound = true;
}
Давид Басараб
источник

Ответы:

234

Правильно ли я использую DateTime Compare?

Нет. CompareПредлагает только информацию об относительном положении двух дат: меньше, равно или больше. Вам нужно что-то вроде этого:

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

Это вычитает два DateTimes. Результатом является TimeSpanобъект, у которого есть TotalDaysсвойство.

Кроме того, условное выражение можно записать прямо как:

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

Нет ifнеобходимости.

Конрад Рудольф
источник
2
Должно быть разрешено дать вам 2+;) один за ответ и один за краткий способ его выражения
CheGueVerra
4
Э ... Я просто увеличил свой ответ, так что не стесняйтесь вычесть один воображаемый голос. ;-)
Конрад Рудольф
1
Пожалуйста, используйте TotalDaysвместо дней.
João Portela,
2
Это концептуально более точно. Это не имеет значения, потому что Daysэто самый большой компонент TimeSpan. Люди, читающие это, могут экстраполировать это на мысль, что Secondsсвойство работает таким же образом.
Жуан Портела
2
Если добавить к мысли Жоау Портела, то даже он Daysсам тоже может ошибаться. Daysи TotalDaysздесь то же самое только потому, что условие есть < 30, но если бы это было так <= 30, была бы очевидная разница , потому что TotalDaysmay возвращает что-то вроде 30.421while Daysвсе еще возвращается 30.
Racil Hilan
15

должно быть

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

отметьте общее количество дней, иначе вы получите странное поведение

Люк
источник
этот ответ был получен через год после последнего редактирования принятого ответа!
Mitch Wheat
@Mitch - это правильный ответ, обратите внимание, что он использует TotalDays, а не Days.
Марсело Мейсон
Принятый ответ правильный. TotalDays также возвращает дробную часть, которая является избыточной по сравнению с целым числом.
Mitch Wheat
1
@MitchWheat TotalDays- это концептуально правильное поле для использования. На практике они дают тот же результат, но только потому, что Daysэто самый большой компонент TimeSpan, если бы был компонент «Месяцы или годы», и это было бы совсем другое дело. Просто попробуйте Hours, Secondsи Millisecondsпосмотреть , как они работают.
João Portela,
7

Что ж, я бы сделал это так:

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

Compare отвечает только целым числом, указывающим на погоду: первый - раньше, тот же или позже ...

Хаквин
источник
6

Попробуйте вместо этого

if ( (expiryDate - DateTime.Now ).TotalDays < 30 ) { 
  matchFound = true;
}
ДжаредПар
источник
1
Хм, вам нужно либо инвертировать порядок ваших дат, либо взять абсолютное значение, если срок годности еще не прошел.
Конрад Рудольф
3

Compare возвращает 1, 0, -1 для значений больше, равно, меньше чем соответственно.

Вы хотите:

    if (DateTime.Compare(expiryDate, DateTime.Now.AddDays(30)) <= 0) 
    { 
        bool matchFound = true;
    }
Митч Уит
источник
1

Это даст вам точный результат:

if ((expiryDate.Date - DateTime.Now.Date).Days < 30)
    matchFound = true;
Джаянт
источник
на самом деле, то, что происходит, например, expryDte - 28/4/2011, если U rite (expiryDate-DateTime.now), это также займет время (28/4/2011 12:00:00 AM - 26/4/2011 11 : 47: 00 AM) и указанный выше код принимает значение 28/4/2011 12:00:00 AM -26.04.2011 12:00:00 AM, что дает точную разницу.
Jayant
1

Сравнивать не нужно, дни / общие дни не нужны.

Все, что тебе нужно

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

обратите внимание, это сработает, если вы решите использовать минуты, месяцы или даже годы в качестве критерия истечения срока действия.

грабить
источник
1
Не лучший ответ, потому что теперь вы также учитываете часы, минуты и секунды. DateTime.Today было бы более правильным для ситуации с OP.
JL.
1

Предполагая, что вы хотите назначить false(если применимо) matchtime, более простой способ написать это будет ..

matchtime = ((expiryDate - DateTime.Now).TotalDays < 30);
Волшебный Мик
источник
Тернарный оператор здесь полностью избыточен, поскольку ((expiryDate - DateTime.Now) .TotalDays <30) уже возвращает логическое значение.
Fabio
@Fabio Спасибо, приятель, удалил их, чтобы присвоить логическое значение через тип возврата.
Magic Mick
0

Нет, функция сравнения вернет 1, 0 или -1. 0, когда два значения равны, -1 и 1 означают меньше и больше чем, я верю в этом порядке, но я часто их путаю.

Тимоти Картер
источник
0

Нет, вы не используете его правильно.

Подробности смотрите здесь .

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");
Давид Басараб
источник
0

Что вы хотите сделать, так это вычесть два DateTimes (expiryDate и DateTime.Now). Это вернет объект типа TimeSpan. TimeSpan имеет свойство «Дни». Сравните это число с 30 для своего ответа.

GWLlosa
источник
0

Нет, это неправильно, попробуйте следующее:

DateTime expiryDate = DateTime.Now.AddDays(-31);
if (DateTime.Compare(expiryDate, DateTime.Now.AddDays(-30)) < 1)
{
    matchFound = true;
}
Канавар
источник
0

На самом деле ни один из этих ответов не помог мне. Я решил это следующим образом:

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

Когда я попробовал это сделать:

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

Сегодня, 2011-11-14, и мой expiryDate был 2011-10-17, я получил matchFound = -28. Вместо 28. Я перевернул последний чек.

SBergstrom
источник
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
Разве это не сложно?
Макс,
Где в вопросе упоминание accountExpireDates? Вы копируете вставленное плохое решение. matchFound звучит почти так, как будто вы смешиваете Pattern или RegEx. Кстати, вам нужно разорвать, когда найдено совпадение, или оно продолжает цикл. И что, если это -2? MSDN не сообщает, что возможные значения: -1, 0 и 1.
Мукус
0

Можно попробовать сделать так:

var daysPassed = (DateTime.UtcNow - expiryDate).Days;
if (daysPassed > 30)
{ 
    // ...
}
влад
источник
6
Пожалуйста, постарайтесь дать более подробное объяснение.
borchvm