简体   繁体   English

如何检查日期是否在给定范围内?

[英]How to check if a date is in a given range?

If you have a $start_date and $end_date , how can you check if a date given by the user falls within that range? 如果您有$start_date$end_date ,那么如何检查用户给出的日期是否在该范围内?

eg 例如

$start_date = '2009-06-17';

$end_date = '2009-09-05';

$date_from_user = '2009-08-28'; 

At the moment the dates are strings, would it help to convert them to timestamp integers? 目前日期是字符串,是否有助于将它们转换为时间戳整数?

Converting them to timestamps is the way to go alright, using strtotime , eg 将它们转换为时间戳是可行的,使用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));
}

It's not necessary to convert to timestamp to do the comparison, given that the strings are validated as dates in 'YYYY-MM-DD' canonical format. 没有必要转换为时间戳来进行比较,因为字符串被验证为“YYYY-MM-DD”规范格式的日期。

This test will work: 该测试将起作用:

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

given: 给定:

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

NOTE: Comparing strings like this does allow for "non-valid" dates eg (December 32nd ) '2009-13-32' and for weirdly formatted strings '2009/3/3', such that a string comparison will NOT be equivalent to a date or timestamp comparison. 注意:比较像这样的字符串确实允许“无效”日期,例如(12月32日)'2009-13-32'和格式奇怪的字符串'2009/3/3',这样字符串比较将不等同于日期或时间戳比较。 This works ONLY if the date values in the strings are in a CONSISTENT and CANONICAL format. 仅当字符串中的日期值采用CONSISTENTCANONICAL格式时,此方法才有效。

EDIT to add a note here, elaborating on the obvious. 编辑在这里添加注释,详细阐述。

By CONSISTENT , I mean for example that the strings being compared must be in identical format: the month must always be two characters, the day must always be two characters, and the separator character must always be a dash. 通过CONSISTENT ,我的意思是例如被比较的字符串必须采用相同的格式:月份必须始终为两个字符,日期必须始终为两个字符,分隔符必须始终为破折号。 We can't reliably compare "strings" that aren't four character year, two character month, two character day. 我们无法可靠地比较不是四个字符年,两个字符月,两个字符日的“字符串”。 If we had a mix of one character and two character months in the strings, for example, we'd get unexpected result when we compared, '2009-9-30' to '2009-10-11' . 例如,如果我们在字符串中混合使用一个字符和两个字符,那么当我们将'2009-9-30''2009-10-11'进行比较时,我们会得到意想不到的结果。 We humanly see "9" as being less than "10", but a string comparison will see '2009-9' as greater than '2009-1' . 我们人性地认为“9”小于“10”,但字符串比较将看到'2009-9'大于'2009-1' We don't necessarily need to have a dash separator characters; 我们不一定需要一个破折号分隔符; we could just as reliably compare strings in 'YYYYMMDD' format; 我们可以可靠地比较'YYYYMMDD'格式的字符串; if there is a separator character, it has to always be there and always be the same. 如果有一个分隔符,它必须始终存在并始终相同。

By CANONICAL , I mean that a format that will result in strings that will be sorted in date order. 通过CANONICAL ,我的意思是一种格式,它将导致字符串按日期顺序排序。 That is, the string will have a representation of "year" first, then "month", then "day". 也就是说,字符串首先表示“年”,然后是“月”,然后是“日”。 We can't reliably compare strings in 'MM-DD-YYYY' format, because that's not canonical. 我们无法可靠地比较'MM-DD-YYYY'格式的字符串,因为这不是规范的。 A string comparison would compare the MM (month) before it compared YYYY (year) since the string comparison works from left to right.) A big benefit of the 'YYYY-MM-DD' string format is that it is canonical; 字符串比较将比较YYYY (年)之前的MM (月份),因为字符串比较从左到右工作。)'YYYY-MM-DD'字符串格式的一大好处是它是规范的; dates represented in this format can reliably be compared as strings. 以这种格式表示的日期可以可靠地比较为字符串。

[ADDENDUM] [附录]

If you do go for the php timestamp conversion, be aware of the limitations. 如果您确实要进行php时间戳转换,请注意这些限制。

On some platforms, php does not support timestamp values earlier than 1970-01-01 and/or later than 2038-01-19. 在某些平台上,php不支持早于1970-01-01和/或晚于2038-01-19的时间戳值。 (That's the nature of the unix timestamp 32-bit integer.) Later versions pf php (5.3?) are supposed to address that. (这是unix时间戳32位整数的本质。)后来的版本pf php(5.3?)应该解决这个问题。

The timezone can also be an issue, if you aren't careful to use the same timezone when converting from string to timestamp and from timestamp back to string. 如果在从字符串转换为时间戳并从时间戳转换回字符串时不小心使用相同的时区,则时区也可能是个问题。

HTH HTH

Use the DateTime class if you have PHP 5.3+. 如果你有PHP 5.3+,请使用DateTime类。 Easier to use, better functionality. 易于使用,功能更强大。

DateTime internally supports timezones, with the other solutions is up to you to handle that. 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
}
$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";
}

Convert both dates to timestamps then do 然后将两个日期转换为时间戳

pseudocode: 伪代码:

if date_from_user > start_date && date_from_user < end_date
    return true

在您提供的格式中,假设用户足够聪明地为您提供有效日期,您不需要先转换为日期,您可以将它们作为字符串进行比较。

将它们转换为日期或时间戳整数,然后检查$ date_from_user是否为<= $ end_date和> = $ start_date

You can try this: 你可以试试这个:

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

I found this method the easiest: 我发现这种方法最简单:

$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

  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM