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.