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 для своего ответа.


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. Я перевернул последний чек.


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

1
Разве это не сложно?
Макс,

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

0

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

var daysPassed = (DateTime.UtcNow - expiryDate).Days;
if (daysPassed > 30)
{ 
    // ...
}

6
Пожалуйста, постарайтесь дать более подробное объяснение.
borchvm
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.