• 0

[PHP] if date is in the next 30 days do something?


Question

Hi guys just a quick one that racking my brains.

in php I'm wanting to do a date comparison of two dates to see if they are in the next X days, but I only have "MM/DD" available to me,

so i tried the following code

.....
                     $fan = new Fan($this->fans[$i]);
                     $birthday = $fan->getBirthday()."/1900";
                     $dateNow = date("m/d")."/1900";

                     print ($birthday."----".$dateNow."<br/>");
                     print($this->dateDiff($dateNow,$birthday)  ."- difference";
                     if (($this->dateDiff($dateNow,$birthday) >= 30) && ($this->dateDiff($dateNow,$birthday) < 0))
                     {

                        print($this->dateDiff($dateNow,$birthday)  ."-got HERE");
                        $searchedFans->addFan($fan);
                     }
                     $i++;
                    }
......

    private function dateDiff($endDate, $beginDate)
    {
        $date_parts1=explode("/", $beginDate);
        $date_parts2=explode("/", $endDate);
        $start_date=gregoriantojd($date_parts1[1], $date_parts1[0], $date_parts1[2]);
        $end_date=gregoriantojd($date_parts2[1], $date_parts2[0], $date_parts2[2]);
        return $end_date - $start_date;
    }

but this only seems to be doing a monthly comparision instead of day

as i get the following output

  Quote
05/31/1900----02/20/1900

3 -difference

12/31/1900----02/20/1900

10 -difference

08/02/1900----02/20/1900

6 -difference

11/25/1900----02/20/1900

9 -difference

12/31/1900----02/20/1900

10 -difference

does anyone know how I could do a correct comparison on days?

thanks matt

8 answers to this question

Recommended Posts

  • 0

PHP Is not a platform I use at all so I got this from the PHP website.

The code there gave this example.

Some stuff to help you get started: 

<?php 
// See what's inside 
$oDT = new DateTime(); 
var_dump($oDT); 
?> 

To do a date difference: 

<?php 
$oDT = new DateTime(); //Sets the object to now 
$oDTDiff = $oDT->diff(new DateTime('2009-08-18 00:00:01')); 
var_dump($oDTDiff); 
echo "Days of difference: ". $oDTDiff->days; 
?> 

http://us.php.net/manual/en/datetime.diff.php

Also, you might want to set the year to the current year for both dates and not "1900". Since you'll probably run into leap year issues at the very least that way...

  • 0

Try this...

<?php

function safestrtotime($strInput) {
    $iVal = -1;
    $yearSkew = 0;
    for ($i=1900; $i<=1969; $i++) {
        # Check for this year string in date
        $strYear = (string)$i;
        if (!(strpos($strInput, $strYear)===false)) {
            $replYear = $strYear;
            $yearSkew = 1970 - $i;
            $strInput = str_replace($strYear, "1970", $strInput);
        };
    };
    $iVal = strtotime($strInput);
    if ($yearSkew > 0) {
        $numSecs = (60 * 60 * 24 * 365 * $yearSkew);
        $iVal = $iVal - $numSecs;
        $numLeapYears = 0;        # Work out number of leap years in period
        for ($j=$replYear; $j<=1969; $j++) {
            $thisYear = $j;
            $isLeapYear = false;
            # Is div by 4?
            if (($thisYear % 4) == 0) {
                $isLeapYear = true;
            };
            # Is div by 100?
            if (($thisYear % 100) == 0) {
                $isLeapYear = false;
            };
            # Is div by 1000?
            if (($thisYear % 1000) == 0) {
                $isLeapYear = true;
            };
            if ($isLeapYear == true) {
                $numLeapYears++;
            };
        };
        $iVal = $iVal - (60 * 60 * 24 * $numLeapYears);
    };
    return($iVal);
};

$date1 = '05/31/2001';
$date2 = '02/21/2001';

$date1 = explode('/', $date1);
$date2 = explode('/', $date2);

$date1 = $date1[2] . '/' . $date1[0] . '/' . $date1[1];
$date2 = $date2[2] . '/' . $date2[0] . '/' . $date2[1];

$diff = safestrtotime($date1) - safestrtotime($date2);

$diff = $diff / (60 * 60 * 24);

echo $diff;

?>

You can read more about the function safestrtotime here Strtotime function does not work for dates before 1970 hence a new function safestrtotime.

  • 0

Oops, I forgot to quote the string in my previous answer. Can't edit it anymore. I doubt you'll be echoing it anyway though, so here is a more useful version.

$diff = round((strtotime($fan->getBirthday() . date('/Y')) - time()) / 86400); if ($diff < 0) $diff += 365;

  • Like 1
  • 0
  On 21/02/2010 at 00:36, Hot said:

Oops, I forgot to quote the string in my previous answer. Can't edit it anymore. I doubt you'll be echoing it anyway though, so here is a more useful version.

$diff = round((strtotime($fan->getBirthday() . date('/Y')) - time()) / 86400); if ($diff < 0) $diff += 365;

your a star that's it!! can't believe it was that easy :D thanks a lot.

also thanks to the others for the help!

  • 0

Sorry to bring this back up, but I have to note that there may be a bug where you add 365 days when dealing with leap years. Also, it's better to use ceil() here instead of round() since otherwise you'll already be subtracting one day at noon.

<?php
// Set some variables to keep frequently used items cached
$birthday = $fan->getBirthday(); $now = time(); $year = date('Y');
// Get the next birthday, that means adding a year when you've already had your birthday this year
if( ($date = strtotime($birthday . '/' . $year)) < $now ) {
	$date = strtotime($birthday . '/' . ++$year);
}
// Get the amount of days, rounded up and without possible negative sign
$diff = (int) ceil( ($date - $now) / 86400 );
?>

This code won't actually give you "0 days" until your birthday, it'll already count to your next birthday on your birthday. You can get around this by changing the if-condition and add one day as buffer. By doing this, you'll prevent the addition of an extra year.

if( ($date = strtotime($birthday . '/' . $year)) + 86400 < $now ) {

Because of the way ceil() works for negative numbers, you don't even need to change the actual difference calculation for this case. The only nasty thing that ceil() does is rounding numbers between -1 and 0 to -0 (note the negative sign), that's why I added a cast to integer to get rid of the sign. You could also achieve this by adding zero or by using the abs() function (multiplying by 1 doesn't seem to work apparently).

Unfortunately, you can't get much shorter than this. If you really want to, you could get it all on one single line but it would become very unreadable. Therefore, I suggest wrapping this in its own function (e.g. getDaysToBirthday($fan) ) to keep your code clean. ;)

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Because Win7 was beautiful, much faster and more functional. Win10 (glossing over 8 as many do) was slightly faster in some cases, more functional in some cases, but some people such as myself hated how it looked and decided it wasn't worth the upgrade. Some people liked (or were ok with) the look, and thus it is a good upgrade. Win11 is like 10, but is less functional. It literally has nothing going for it, and I use it every day at work so I'm quite familiar with it.
    • I switched my mom from Chrome to Firefox and she had a serious meltdown. She even managed to figure out how to reinstall Chrome, which really surprised me. What finally got her to switch was Chrome no longer being supported on Win7 and me putting a Chrome skin on FF, and setting it up identically.
    • Feels very much like most other gnome based Linux distros. There is minimal amounts that are influenced by Windows 11, maybe just enough to make people who are switching comfortable enough with the idea. As far as I can tell its mainly just turning the 'taskbar' panel as a 100% sized static panel, rather than the default dynamic sized. Turning it from the Mac OS Dock into the Windows taskbar. The Arc Menu - that I assume you're taking not with from the screenshots, is indeed the Windows 11 style one, but it has lots of other options too, from the more traditional gnome, Windows 7 etc. Still free to install what ever Window Manager you want once you're comfortable enough with Linux though.
    • Wow, and here I'm still happily using 1080p...
    • Added an extra filter to Fail2Ban.  I thought about just adding this to my existing aibots filter, but for the time being I'm keeping it separate because it's "possible" real humans may trigger this one so as long as it doesn't start filling my inbox I'd like to get notified about these so I can adjust it as necessary in the future. I'm still holding close to 10k unique IP addresses at any given time that have been banned via the "aibots" filter that looks for certain user agent strings of known AI scrapers.  However, I've been getting an increasing amount of traffic trying to scrape the site with sanitized user agent strings that just look like normal web browsers, however... Because I enabled authentication I can now see that they're racking up lots of 401 (unauthorized) responses in the Apache "access.log" file, but they're not triggering anything in the Apache "error.log" file, which is where failed attempts to log in would appear.  Basically, if an actual human tried to log in with an invalid username and password they don't immediately go into "access.log" as a 401, they go into "error.log" with a status message such as "user FOO not found".  The only way to trigger a 401 simply by visiting the site, as far as I'm aware, is to hit "Cancel" on the login prompt, or otherwise try to access files directly without properly authenticating. So, given the fact I'm getting a few thousand 401 errors a day from sanitized user agent strings that don't show up in "error.log", which means no attempt at logging in properly, I added another jail/filter set to Fail2Ban to immediately ban anybody who triggers a 401.  This feels a bit nuclear so I may need to adjust it in the future, but as far as I'm aware so far no real humans are being inconvenienced so all I'm doing is wasting the time of some AI scraper bots. Example log entry 61.170.149.70 - - [25/Jun/2025:20:01:04 -0400] "GET /content/mdwiki_en_all_maxi_2024-06/A/Neuroregeneration HTTP/1.1" 401 3287 "https://kiwix.marcusadams.me/content/mdwiki_en_all_maxi_2024-06/A/Neuroregeneration" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43" Contents of /etc/fail2ban/filter.d/apache-401repeat.conf #Fail2Ban filter for bots and scrapers that try to access #files directly without entering credentials for apache2-auth #and therefore trigger lots of 401 errors without triggering #the apache-auth jail. # #Marcus Dean Adams [Definition] failregex = ^<HOST> .+\" 401 \d+ .*$ Contents of /etc/fail2ban/jail.d/apache-401repeat.local [apache-401repeat] enabled = true ignoreip = 10.1.1.1 port = 80,443 filter = apache-401repeat maxretry = 1 bantime = 672h findtime = 10m logpath = /var/log/apache2/access.log Oh, and all this traffic is AFTER I explicitly banned Alibaba's IP ranges that were absolutely blowing me up day and night. Observation; two of the IP addresses that have triggered this jail in the 30 or so minutes since I turned it on were owned by Microsoft.  Wonder if they're doing their own AI scraping/probing, or if that's just an Azure VM owned by somebody else.
  • Recent Achievements

    • Rising Star
      Phillip0web went up a rank
      Rising Star
    • One Month Later
      Epaminombas earned a badge
      One Month Later
    • One Year In
      Bert Fershner earned a badge
      One Year In
    • Reacting Well
      ChrisOdinUK earned a badge
      Reacting Well
    • One Year In
      Steviant earned a badge
      One Year In
  • Popular Contributors

    1. 1
      +primortal
      552
    2. 2
      ATLien_0
      208
    3. 3
      +FloatingFatMan
      175
    4. 4
      Michael Scrip
      152
    5. 5
      Som
      139
  • Tell a friend

    Love Neowin? Tell a friend!