Как проверить, находится ли дата в заданном диапазоне?

Если у вас есть $start_date и $end_date , как вы можете проверить, попадает ли дата, заданная пользователем, в этот диапазон?

например

 $start_date = '2009-06-17'; $end_date = '2009-09-05'; $date_from_user = '2009-08-28'; 

На данный момент даты являются строками, поможет ли это преобразовать их в числовые метки?

    Преобразование их в метку времени – это способ пойти в порядке, используя strtotime , например

     $start_date = '2009-06-17'; $end_date = '2009-09-05'; $date_from_user = '2009-08-28'; check_in_range($start_date, $end_date, $date_from_user); function check_in_range($start_date, $end_date, $date_from_user) { // Convert to timestamp $start_ts = strtotime($start_date); $end_ts = strtotime($end_date); $user_ts = strtotime($date_from_user); // Check that user date is between start & end return (($user_ts >= $start_ts) && ($user_ts <= $end_ts)); } 

    Нет необходимости преобразовывать в timestamp для сравнения, учитывая, что строки проверяются как даты в каноническом формате «YYYY-MM-DD».

    Этот тест будет работать:

     ( ( $date_from_user >= $start_date ) && ( $date_from_user <= $end_date ) ) 

    данный:

     $start_date = '2009-06-17'; $end_date = '2009-09-05'; $date_from_user = '2009-08-28'; 

    ПРИМЕЧАНИЕ. Сравнение строк, подобных этому, позволяет использовать «недействительные» даты, например (32 декабря) «2009-13-32» и для странно отформатированных строк «2009/3/3», так что сравнение строк НЕ будет эквивалентно сравнение даты или времени. Это работает ТОЛЬКО, если значения даты в строках находятся в формате CONSISTENT и CANONICAL .

    РЕДАКТИРОВАТЬ, чтобы добавить здесь примечание, в котором излагается очевидное.

    По CONSISTENT я имею в виду, например, что сравниваемые строки должны быть в одинаковом формате: месяц должен всегда быть двумя символами, день должен быть всегда двух символов, а символ разделителя всегда должен быть тире. Мы не можем надежно сравнить «строки», которые не являются символом четыре года, двухсимвольным месяцем, двумя символами. Если бы у нас было сочетание одного символа и двух месяцев символа в строках, например, мы получили бы неожиданный результат, когда мы сравнивали: '2009-9-30''2009-10-11' . Мы по-человечески видим, что «9» меньше «10», но сравнение строк будет '2009-9' больше, чем '2009-1' . Мы не обязательно должны иметь символы разделителя тире; мы могли бы надежно сравнить строки в формате 'YYYYMMDD' ; если есть разделительный символ, он всегда должен быть там и всегда быть одинаковым.

    По CANONICAL я имею в виду формат, который приведет к строкам, которые будут отсортированы в порядке даты. То есть строка будет иметь представление «год» сначала, затем «месяц», затем «день». Мы не можем достоверно сравнивать строки в 'MM-DD-YYYY' , потому что это не канонически. Сравнение строк сравнивало бы MM (месяц), прежде чем оно сравнивало YYYY (год), поскольку сравнение строк работает слева направо.) Большим преимуществом строкового формата «YYYY-MM-DD» является то, что он является каноническим; даты, представленные в этом формате, могут быть надежно сопоставлены как строки.

    [ДОПОЛНЕНИЕ]

    Если вы переходите на преобразование timestamp php, помните об ограничениях.

    На некоторых платформах php не поддерживает значения временных меток ранее 1970-01-01 и / или позже 2038-01-19. (Это характер 32-разрядного целого числа unix timestamp.) Более поздние версии pf php (5.3?) Должны адресовать это.

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

    НТН

    Используйте класс DateTime, если у вас есть PHP 5.3+. Простота использования, улучшенная функциональность.

    DateTime внутренне поддерживает часовые пояса, а другие решения помогут вам справиться с этим.

     <?php /** * @param DateTime $date Date that is to be checked if it falls between $startDate and $endDate * @param DateTime $startDate Date should be after this date to return true * @param DateTime $endDate Date should be before this date to return true * return bool */ function isDateBetweenDates(DateTime $date, DateTime $startDate, DateTime $endDate) { return $date > $startDate && $date < $endDate; } $fromUser = new DateTime("2012-03-01"); $startDate = new DateTime("2012-02-01 00:00:00"); $endDate = new DateTime("2012-04-30 23:59:59"); echo isDateBetweenDates($fromUser, $startDate, $endDate); 
     $startDatedt = strtotime($start_date) $endDatedt = strtotime($end_date) $usrDatedt = strtotime($date_from_user) if( $usrDatedt >= $startDatedt && $usrDatedt <= $endDatedt) { //..falls within range } 

    Преобразуйте обе даты в метки времени, затем выполните

    псевдокод:

     if date_from_user > start_date && date_from_user < end_date return true 

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

     $start_date="17/02/2012"; $end_date="21/02/2012"; $date_from_user="19/02/2012"; function geraTimestamp($data) { $partes = explode('/', $data); return mktime(0, 0, 0, $partes[1], $partes[0], $partes[2]); } $startDatedt = geraTimestamp($start_date); $endDatedt = geraTimestamp($end_date); $usrDatedt = geraTimestamp($date_from_user); if (($usrDatedt >= $startDatedt) && ($usrDatedt <= $endDatedt)) { echo "Dentro"; } else { echo "Fora"; } 

    Преобразуйте их в даты или целые числа времени, а затем просто проверьте значение $ date_from_user <= $ end_date и> = $ start_date

    Вы можете попробовать следующее:

     //custom date for example $d1 = new DateTime("2012-07-08"); $d2 = new DateTime("2012-07-11"); $d3 = new DateTime("2012-07-08"); $d4 = new DateTime("2012-07-15"); //create a date period object $interval = new DateInterval('P1D'); $daterange = iterator_to_array(new DatePeriod($d1, $interval, $d2)); $daterange1 = iterator_to_array(new DatePeriod($d3, $interval, $d4)); array_map(function($v) use ($daterange1) { if(in_array($v, $daterange1)) print "Bingo!";}, $daterange); 

    Я нашел этот метод самым простым:

     $start_date = '2009-06-17'; $end_date = '2009-09-05'; $date_from_user = '2009-08-28'; $start_date = date_create($start_date); $date_from_user = date_create($date_from_user); $end_date = date_create($end_date); $interval1 = date_diff($start_date, $date_from_user); $interval2 = date_diff($end_date, $date_from_user); if($interval1->invert == 0){ if($interval2->invert == 1){ // if it lies between start date and end date execute this code } }