2009-06-10 219 views
64

如果您有$start_date$end_date,如何检查用户提供的日期是否在该范围内?如何检查日期是否在给定范围内?

例如

$start_date = '2009-06-17'; 

$end_date = '2009-09-05'; 

$date_from_user = '2009-08-28'; 

现在日期是字符串,它会帮助将它们转换为时间戳整数?

+0

这将帮助,那么你可以访问任何日期操作功能也有。 – ChrisF 2009-06-10 16:22:41

+3

因为Unix时间戳记是在1970年1月1日(1970-01-01)的时代开始,所以你可以在1970年之前对测试日期进行有趣的行为。 – 2009-06-10 16:26:52

+1

@Shadi你知道有这样的事情,比如负数,对吧? – 2009-06-11 06:33:31

回答

96

使用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

将它们转换成日期或时间戳记整数,然后只检查$ date_from_user是< = $ END_DATE和> = $起始日期

+3

您能澄清“将它们转换为日期”吗?你会怎么做?我认为PHP没有日期类型? – meleyal 2009-06-10 16:25:09

3

都转换日期戳,然后做

伪代码:

if date_from_user > start_date && date_from_user < end_date 
    return true 
+0

您可能需要对其进行编辑,以便在范围中包含start_date和end_date。现在,如果date_from_user等于两者,则不会被计算在内。 – TheTXI 2009-06-10 16:24:45

+0

OP没有指定包含范围或独占范围,所以我会让他们选择使用哪种策略 – Glen 2009-06-10 16:27:50

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

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

这不包括与开始日期或结束日期 – TheTXI 2009-06-10 16:25:31

46

这是没有必要转换成时间戳做比较,因为串被验证为“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'; 

注:比较字符串这样确实允许 “非有效” 日期如(12月32日)'2009-13-32'以及格式不正确的字符串'2009/3/3',这样字符串比较不会等同于日期或时间戳比较。这仅适用于字符串中的日期值为CONSISTENTCANONICAL格式。

编辑在这里添加一个注释,详细阐述。

通过一致的,我的意思是比如被比较字符串必须是相同的格式为:每月必须始终是两个字符,这一天必须是两个字符,分隔符必须是一个破折号。我们不能可靠地比较不是四个字符年,两个字符月,两个字符日的“字符串”。例如,如果我们在字符串中混合使用了一个字符和两个字符月份,那么当我们比较'2009-9-30''2009-10-11'时,我们会得到意想不到的结果。我们人为地将“9”看作小于“10”,但字符串比较将看到'2009-9'大于'2009-1'。我们不一定需要有一个破折号分隔符字符;我们可以可靠地比较'YYYYMMDD'格式的字符串;如果有分隔符,它必须始终在那里并且始终保持相同。

通过CANONICAL,我的意思是一种格式,将导致将按日期顺序排序的字符串。也就是说,该字符串将首先具有“年”的表示,然后是“月”,然后是“日”。我们无法可靠地比较'MM-DD-YYYY'格式的字符串,因为这不是规范。字符串比较将比较MM(月),然后比较YYYY(年),因为字符串比较从左到右起作用。)'YYYY-MM-DD'字符串格式的一大优点是它是规范的;以这种格式表示的日期可以可靠地作为字符串比较。

[附录]

如果你去为PHP时间戳转换,要注意的限制。

在某些平台上,php不支持早于1970-01-01和/或晚于2038-01-19的时间戳值。 (这是unix timestamp 32位整数的本质。)后来的版本pf php(5.3?)应该解决这个问题。

如果您在从字符串转换为时间戳和从时间戳转换回字符串时不小心使用相同的时区,则时区也可能成为问题。

HTH

3

在您所提供的格式,假设用户是足够聪明,给你的有效日期,您不需要转换成日期第一,你可以把它们比为字符串。

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

如果您有PHP 5.3+,请使用DateTime类。更易于使用,更好的功能。

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

你可以试试这个:

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

我发现这个方法最简单的:

$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 

    } 
} 
相关问题