简体   繁体   中英

PHP check if date between two dates

I got this code from Stackoverflow and changed it slightly to work with today's date.

I want to check if today fits between two dates. But this is not working. What am I missing?

$paymentDate = date('d/m/Y');
echo $paymentDate; // echos today! 
$contractDateBegin = date('d/m/Y', '01/01/2001');
$contractDateEnd = date('d/m/Y', '01/01/2015');

if ($paymentDate > $contractDateBegin && $paymentDate < $contractDateEnd)
{
  echo "is between";
}
else
{
echo "NO GO!";  
}

Edit: use <= or >= to count today's date.

This is the right answer for your code. Just use the strtotime() php function.

$paymentDate = date('Y-m-d');
$paymentDate=date('Y-m-d', strtotime($paymentDate));
//echo $paymentDate; // echos today! 
$contractDateBegin = date('Y-m-d', strtotime("01/01/2001"));
$contractDateEnd = date('Y-m-d', strtotime("01/01/2012"));
    
if (($paymentDate >= $contractDateBegin) && ($paymentDate <= $contractDateEnd)){
    echo "is between";
}else{
    echo "NO GO!";  
}

You cannot compare date-strings. It is good habit to use PHP's DateTime object instead:

$paymentDate = new DateTime(); // Today
echo $paymentDate->format('d/m/Y'); // echos today! 
$contractDateBegin = new DateTime('2001-01-01');
$contractDateEnd  = new DateTime('2015-01-01');

if (
  $paymentDate->getTimestamp() > $contractDateBegin->getTimestamp() && 
  $paymentDate->getTimestamp() < $contractDateEnd->getTimestamp()){
  echo "is between";
}else{
   echo "NO GO!";  
}

If hours matter:

$paymentDate = strtotime(date("Y-m-d H:i:s"));
$contractDateBegin = strtotime("2014-01-22 12:42:00");
$contractDateEnd = strtotime("2014-01-22 12:50:00");

if($paymentDate > $contractDateBegin && $paymentDate < $contractDateEnd) {
   echo "is between";
} else {
    echo "NO GO!";  
}    

Based on luttken's answer. Thought I'd add my twist :)

function dateIsInBetween(\DateTime $from, \DateTime $to, \DateTime $subject)
{
    return $subject->getTimestamp() > $from->getTimestamp() && $subject->getTimestamp() < $to->getTimestamp() ? true : false;
}

$paymentDate       = new \DateTime('now');
$contractDateBegin = new \DateTime('01/01/2001');
$contractDateEnd   = new \DateTime('01/01/2016');

echo dateIsInBetween($contractDateBegin, $contractDateEnd, $paymentDate) ? "is between" : "NO GO!";

You are comparing the dates as strings, which won't work because the comparison is lexicographical. It's the same issue as when sorting a text file, where a line 20 would appear after a line 100 because the contents are not treated as numbers but as sequences of ASCII codes. In addition, the dates created are all wrong because you are using a string format string where a timestamp is expected (second argument).

Instead of this you should be comparing timestamps of DateTime objects, for instance:

 $paymentDate = date_create();
 $contractDateBegin = date_create_from_format('d/m/Y', '01/01/2001');
 $contractDateEnd = date_create_from_format('d/m/Y', '01/01/2015');

Your existing conditions will then work correctly.

Another solution would have been to consider date written as Ymd.

Written in this "format" this is much easy to compare dates.

$paymentDate       = date('Ymd'); // on 4th may 2016, would have been 20160504
$contractBegin     = 20010101;
$contractEnd       = 20160101;
echo ($paymentDate >= $contractBegin && $paymentDate <= $contractEnd) ? "Between" : "Not Between";

It will always work for every day of the year and do not depends on any function or conversion (PHP will consider the int value of $paymentDate to compare with the int value of contractBegin and contractEnd ).

Because I'm lazy:

$paymentDate = new DateTime();
$contractStartDate = new Datetime('01/01/2001');
$contractEndDate = new Datetime('01/01/2015');
$payable = $paymentDate < $contractEndDate && $contractStartDate > $paymentDate; //bool

var_dump($payable)

Display:

bool(false)

As a function

function isPayable(DateTime $payDate, DateTime $startDate, DateTime $endDate):bool 
{
    return $payDate > $startDate && $payDate < $endDate;
}

var_dump(isPayable(new DateTime(), new Datetime('01/01/2001'), new DateTime('01/01/2015')));
var_dump(isPayable(new DateTime('2003-03-15'), new Datetime('2001-01-01'), new DateTime('2015-03-01')));



Display:

bool(false)
bool(True)

If you need bracket dates to be dynamic ..

$todayStr = date('Y-m-d');
$todayObj=date('Y-m-d', strtotime($todayStr));
$currentYrStr =  date('Y');
$DateBegin = date('Y-m-d', strtotime("06/01/$currentYrStr"));
$DateEnd = date('Y-m-d', strtotime("10/01/$currentYrStr"));
if (($todayObj > $contractDateBegin) && ($paymentDate < $contractDateEnd)){
    $period="summer";
}else{
   $period="winter";  
}

Simple solution:

function betweenDates($cmpDate,$startDate,$endDate){ 
   return (date($cmpDate) > date($startDate)) && (date($cmpDate) < date($endDate));
}

You can use the mktime(hour, minute, seconds, month, day, year) function

$paymentDate = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
$contractDateBegin = mktime(0, 0, 0, 1, 1, 2001); 
$contractDateEnd =  mktime(0, 0, 0, 1, 1, 2012);

if ($paymentDate >= $contractDateBegin && $paymentDate <= $contractDateEnd){
    echo "is between";
}else{
    echo "NO GO!";  
}

It should be noted that you can compare Datetime() objects as is. So a simplified and cleaner version of @luttkens answer above:

$paymentDate       = new DateTime(); // Today
$contractDateBegin = new DateTime('2001-01-01');
$contractDateEnd   = new DateTime('2015-01-01');

if ($paymentDate >= $contractDateBegin && $paymentDate < $contractDateEnd) {
  // is in between
}

Use directly

$paymentDate = strtotime(date("d-m-Y"));
$contractDateBegin = strtotime("01-01-2001");
$contractDateEnd = strtotime("01-01-2015");

Then comparison will be ok cause your 01-01-2015 is valid for PHP's 32bit date-range, stated in strtotime's manual.

An other solution (with the assumption you know your date formats are always YYYY/MM/DD with lead zeros) is the max() and min() function. I figure this is okay given all the other answers assume the yyyy-mm-dd format too and it's the common naming convention for folders in file systems if ever you wanted to make sure they sorted in date order.

As others have said, given the order of the numbers you can compare the strings, no need for strtotime() function.

Examples:

$biggest = max("2018/10/01","2018/10/02");

The advantage being you can stick more dates in there instead of just comparing two.

$biggest = max("2018/04/10","2019/12/02","2016/03/20");

To work out if a date is in between two dates you could compare the result of min() and max()

$startDate="2018/04/10";
$endDate="2018/07/24";
$check="2018/05/03";
if(max($startDate,$check)==min($endDate,$check)){
    // It's in the middle
}

It wouldn't work with any other date format, but for that one it does. No need to convert to seconds and no need for date functions.

The above methods are useful but they are not full-proof because it will give error if time is between 12:00 AM/PM and 01:00 AM/PM . It will return the "No Go" in-spite of being in between the timing . Here is the code for the same:

$time = '2019-03-27 12:00 PM';

$date_one = $time; 
$date_one = strtotime($date_one);
$date_one = strtotime("+60 minutes", $date_one);
$date_one =  date('Y-m-d h:i A', $date_one);

$date_ten = strtotime($time); 
$date_ten = strtotime("-12 minutes", $date_ten); 
$date_ten = date('Y-m-d h:i A', $date_ten);

$paymentDate='2019-03-27 12:45 AM';

$contractDateBegin = date('Y-m-d h:i A', strtotime($date_ten)); 
$contractDateEnd = date('Y-m-d h:i A', strtotime($date_one));

echo $paymentDate; 
echo "---------------"; 
echo $contractDateBegin; 
echo "---------------"; 
echo $contractDateEnd; 
echo "---------------";

$contractDateEnd='2019-03-27 01:45 AM';

if($paymentDate > $contractDateBegin && $paymentDate < $contractDateEnd)  
{  
 echo "is between";
} 
else
{  
  echo "NO GO!";  
}

Here you will get output "NO Go" because 12:45 > 01:45 .

To get proper output date in between, make sure that for "AM" values from 01:00 AM to 12:00 AM will get converted to the 24-hour format. This little trick helped me.

I had some glitches due to locale probably. That's worked for me. To be concise variable declaration omitted. Both time() and strtotime() returns int so integers are compared

if (time() >= strtotime("27.07.2022") && time() <= strtotime("28.07.2022")){

Simple approach, works for dates and datetimes:

// Check if today falls between two dates
$start_date = strtotime('01/01/2001');
$end_date = strtotime('01/01/2015');
$today = strtotime('today');

if($today >= $start_date && $today <= $end_date) {
  // Today is between two dates
}
function get_format($df) {

    $str = '';
    $str .= ($df->invert == 1) ? ' - ' : '';
    if ($df->y > 0) {
        // years
        $str .= ($df->y > 1) ? $df->y . ' Years ' : $df->y . ' Year ';
    } if ($df->m > 0) {
        // month
        $str .= ($df->m > 1) ? $df->m . ' Months ' : $df->m . ' Month ';
    } if ($df->d > 0) {
        // days
        $str .= ($df->d > 1) ? $df->d . ' Days ' : $df->d . ' Day ';
    } 

    echo $str;
}

$yr=$year;
$dates=$dor;
$myyear='+'.$yr.' years';
$new_date = date('Y-m-d', strtotime($myyear, strtotime($dates)));
$date1 = new DateTime("$new_date");
$date2 = new DateTime("now");
$diff = $date2->diff($date1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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