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

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

например.

$start_date = '2009-06-17';

$end_date = '2009-09-05';

$date_from_user = '2009-08-28'; 

В настоящий момент даты являются строками, помогло бы ли они конвертировать их в целые числа времени?

Ответ 1

Преобразование их в метку времени - это способ пойти хорошо, используя 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));
}

Ответ 2

Не нужно преобразовывать в 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 (year), поскольку сравнение строк работает слева направо.) Большим преимуществом формата строки "YYYY-MM-DD" является то, что это каноническое; даты, представленные в этом формате, можно достоверно сравнить как строки.

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

Если вы хотите преобразовать временную метку php, помните об ограничениях.

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

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

НТН

Ответ 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);

Ответ 4

$startDatedt = strtotime($start_date)
$endDatedt = strtotime($end_date)
$usrDatedt = strtotime($date_from_user)

if( $usrDatedt >= $startDatedt && $usrDatedt <= $endDatedt)
{
   //..falls within range
}

Ответ 5

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

псевдокод:

if date_from_user > start_date && date_from_user < end_date
    return true

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

//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);

Ответ 10

Я нашел этот метод самым легким:

$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

  }
}