Как проверить, находится ли дата в заданном диапазоне?
Если у вас есть $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
}
}