97

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!";  
}
Papa De Beau
  • 3,744
  • 18
  • 79
  • 137
  • 2
    if youre on php5, check out datetime.diff on http://no2.php.net/manual/en/datetime.diff.php – Tom Sep 28 '13 at 18:12
  • Then you should read the [formats](http://www.php.net/manual/en/datetime.formats.date.php) that strtotime() accepts.... but date() is definitely the wrong function to use – Mark Baker Sep 28 '13 at 18:17

17 Answers17

223

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

Note: Use <= or >= to count today's date.

Dharman
  • 30,962
  • 25
  • 85
  • 135
g.m.ashaduzzaman
  • 2,269
  • 1
  • 14
  • 10
  • Thank you good sir! Maybe it might be good to remove your answer that you added at the top and just leave the one that works for me. Not sure. – Papa De Beau Sep 28 '13 at 18:35
  • 8
    @PapaDeBeau: You have to keep in mind that those `01/01/2001` dates in this solution are in `m/d/Y` format, not `d/m/Y`. – Jon Sep 28 '13 at 20:43
  • 5
    I would not use stric comparison, so this is the best $paymentDate >= $contractDateBegin and $paymentDate <= $contractDateEnd – pollux1er Aug 14 '14 at 08:39
  • if (($paymentDate > $contractDateBegin) && ($paymentDate < $contractDateEnd)) can be if (($paymentDate >= $contractDateBegin) && ($paymentDate <= $contractDateEnd)) So that it can check greater than equal to and less than equal to. – Kamesh Jungi Jul 15 '15 at 11:18
  • 3
    This solution, and every other solution on this page fails when you provide a date that starts before the unix epoch. Try it with 1942/07/28 and see what happens. – Alex Barker Jan 04 '16 at 20:53
  • @AlexBarker you're right! I'm having this issue and I need to solve it, any idea of how to do it for all cases? – Roberto Sepúlveda Bravo Apr 26 '17 at 17:42
  • @RobertoSepúlvedaBravo I believe I used the [DateTime](http://php.net/manual/en/datetime.construct.php) object's [::sub](http://php.net/manual/en/datetime.sub.php) method. The same boolean logic should work +/- an abs() call. – Alex Barker Apr 27 '17 at 17:46
  • This solution only works if you know which date is the earlier one and which date is the later one. If you grab those dates from a database and you don't know that, it will fail – Thomas Weller Feb 07 '19 at 09:33
41

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!";  
}
luttkens
  • 1,272
  • 8
  • 16
  • 2
    If you print `$paymentDate->getTimestamp() and $contractDateEnd->getTimestamp()` when $contractDateEnd is same as current date it will produce wrong result. example today is 01/05/2015 but if you change $contractDateEnd = new DateTime('2015-05-01'); then it will produce wrong timestamp. Instead of just `$paymentDate = new DateTime();` you should use `$paymentDate = new DateTime('2015-05-01') ` ie. pass current date to it – RN Kushwaha May 01 '15 at 10:01
  • 1
    I am always wondering why people do not use DateTime more often? – vaso123 Nov 25 '20 at 03:15
  • 1
    You don't need `getTimestamp()` here – But those new buttons though.. Jun 30 '22 at 18:07
19

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!";  
}    
Rizier123
  • 58,877
  • 16
  • 101
  • 156
6

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!";
Vigintas Labakojis
  • 1,039
  • 1
  • 15
  • 21
5

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.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • I must not be using php5? I got this error: Call to undefined function date_create_from_format() – Papa De Beau Sep 28 '13 at 18:14
  • Try just `date_create` – Ofir Baruch Sep 28 '13 at 18:15
  • 2
    @PapaDeBeau: `date_create_from_format` was introduced in PHP 5.3, which has [already reached end of life](http://php.net/archive/2013.php#id2013-07-11-1) -- yet you are using an even earlier version. I suggest upgrading *today* if possible. – Jon Sep 28 '13 at 18:16
  • @OfirBaruch: Won't work because `d/m/Y` is not one of the [supported formats](http://www.php.net/manual/en/datetime.formats.date.php). – Jon Sep 28 '13 at 18:17
  • Downvoter: Is there something wrong with this answer? Please help me improve it by leaving a comment. – Jon Sep 28 '13 at 18:21
  • @Jon I got a downvote too for my question. I thought it was a good question and met the requirements of stack. – Papa De Beau Sep 28 '13 at 18:22
  • @Tom: If that's not possible then a supported format will have to be used, such as `d-m-Y`. – Jon Sep 28 '13 at 18:24
  • date_create_from_format('01/01/2001', 'd/m/Y'); is wrong. date_create_from_format('d/m/Y', '01/01/2001'); the right way. – borayeris Dec 29 '17 at 01:42
4

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).

Richard Erickson
  • 2,568
  • 8
  • 26
  • 39
ChtiSeb
  • 69
  • 1
  • 4
3

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)
B. Clincy
  • 126
  • 1
  • 4
2

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
}
0

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";  
}
Jim Turner
  • 19
  • 5
0

Simple solution:

function betweenDates($cmpDate,$startDate,$endDate){ 
   return (date($cmpDate) > date($startDate)) && (date($cmpDate) < date($endDate));
}
Spock
  • 69
  • 7
0

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!";  
}
0

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
}
Nicky Kouffeld
  • 321
  • 2
  • 7
-1

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.

Example:

<?php

//$paymentDate = strtotime(date("d-m-Y"));
$paymentDate = strtotime("21-06-2023");
$contractDateBegin = strtotime("01-01-2023");
$contractDateEnd = strtotime("01-01-2024");

echo $paymentDate . PHP_EOL;
echo $contractDateBegin . PHP_EOL;
echo $contractDateEnd . PHP_EOL;

if ($paymentDate >= $contractDateBegin && $paymentDate <= $contractDateEnd) {
    echo "Valid" . PHP_EOL;
} else {
    echo "Expired" . PHP_EOL;
}

exit();

WARNING! DO NOT USE strtotime() within the following condition:

in_array($paymentDate, range($contractDateBegin, $contractDateEnd), true)

even on 1 year interval, it will eat all available memory (for example in 3v4l.org online PHP shell, it gives this fatal error:

Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 536870920 bytes)

1000Gbps
  • 1,455
  • 1
  • 29
  • 34
-1

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.

Watts Epherson
  • 692
  • 5
  • 9
-1

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.

wscourge
  • 10,657
  • 14
  • 59
  • 80
-1

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("29.07.2022")){
Hebe
  • 661
  • 1
  • 7
  • 13
-3
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);
Sebastian Kaczmarek
  • 8,120
  • 4
  • 20
  • 38