59

I would like to check, if a date is today, tomorrow, yesterday or else. But my code doesn't work.

Code:

$timestamp = "2014.09.02T13:34";
$date = date("d.m.Y H:i");
$match_date = date('d.m.Y H:i', strtotime($timestamp));

if($date == $match_date) { 

    //Today

} elseif(strtotime("-1 day", $date) == $match_date) {

    //Yesterday

} elseif(strtotime("+1 day", $date) == $match_date) {

    //Tomorrow

} else {

    //Sometime

}

The Code always goes in the else case.

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
R2D2
  • 743
  • 1
  • 7
  • 14

10 Answers10

60

First. You have mistake in using function strtotime see PHP documentation

int strtotime ( string $time [, int $now = time() ] )

You need modify your code to pass integer timestamp into this function.

Second. You use format d.m.Y H:i that includes time part. If you wish to compare only dates, you must remove time part, e.g. `$date = date("d.m.Y");``

Third. I am not sure if it works in the same way for you, but my PHP doesn't understand date format from $timestamp and returns 01.01.1970 02:00 into $match_date

$timestamp = "2014.09.02T13:34";
date('d.m.Y H:i', strtotime($timestamp)) === "01.01.1970 02:00";

You need to check if strtotime($timestamp) returns correct date string. If no, you need to specify format which is used in $timestamp variable. You can do this using one of functions date_parse_from_format or DateTime::createFromFormat

This is a work example:

$timestamp = "2014.09.02T13:34";

$today = new DateTime("today"); // This object represents current date/time with time set to midnight

$match_date = DateTime::createFromFormat( "Y.m.d\\TH:i", $timestamp );
$match_date->setTime( 0, 0, 0 ); // set time part to midnight, in order to prevent partial comparison

$diff = $today->diff( $match_date );
$diffDays = (integer)$diff->format( "%R%a" ); // Extract days count in interval

switch( $diffDays ) {
    case 0:
        echo "//Today";
        break;
    case -1:
        echo "//Yesterday";
        break;
    case +1:
        echo "//Tomorrow";
        break;
    default:
        echo "//Sometime";
}
Jasom Dotnet
  • 1,225
  • 12
  • 17
Nicolai
  • 5,489
  • 1
  • 24
  • 31
  • What sort of `case` would lead to the "sometimes" in your `switch`? Only when `$today` or `$match_date` don't properly format as dates, maybe? – DACrosby Mar 12 '15 at 20:22
  • 3
    A possible improvement: `$today` can be defined as just `new DateTime("today")`, which means today at midnight -- the time part will be automatically zeroed out. – Jon Jun 27 '15 at 16:07
  • Checking `(integer)$diff->format( "%R%a" ) == 0` on its own is inaccurate. It is true for the same day ten years ago too. Check `$diff->days == 0` for today, and `$diff->days == 1` with `$diff->invert` for yesterday / tomorrow. – MIvanIsten Aug 26 '21 at 09:46
31
<?php 
 $current = strtotime(date("Y-m-d"));
 $date    = strtotime("2014-09-05");

 $datediff = $date - $current;
 $difference = floor($datediff/(60*60*24));
 if($difference==0)
 {
    echo 'today';
 }
 else if($difference > 1)
 {
    echo 'Future Date';
 }
 else if($difference > 0)
 {
    echo 'tomorrow';
 }
 else if($difference < -1)
 {
    echo 'Long Back';
 }
 else
 {
    echo 'yesterday';
 }  
?>
Cyril Jacquart
  • 2,632
  • 3
  • 25
  • 24
Nith
  • 734
  • 4
  • 9
  • 5
    Every time you see the number 86400 (60 * 60 * 24) in code, you know it has a bug. As is true in this case also: http://ideone.com/2D2N8I – Jon Jun 27 '15 at 16:04
  • @Jon : Why this number is considered as a bug? – meDeepakJain Nov 20 '17 at 10:41
  • 4
    @DeepakJain because not all days are 86400 seconds long. There are shorter days and longer days because of daylight savings time, there are leap seconds, all of these are of course rare occurrences but they will break your code when they happen. See for example in the ideone link I gave above how this code reports the wrong result if you pick certain specific dates. – Jon Nov 20 '17 at 13:24
  • Thanks @Jon for the explanation! I'll make a note of it as it seems an important point to remember. – meDeepakJain Nov 20 '17 at 16:40
  • 1
    Are you sure this works? if the date belongs to 17 hours ago and let's say it's 4PM , it belongs to yesterday but your code is gonna show Today – Amin Feb 08 '18 at 12:50
  • This should not have so many upvotes. This is calculating 24 hour periods, not whether the "date" was truly yesterday. Use this with caution as it may lead to unexpected results. – FontFamily Jul 19 '21 at 23:55
16

I think this will help you:

<?php
$date = new DateTime();
$match_date = new DateTime($timestamp);
$interval = $date->diff($match_date);

if($interval->days == 0) {

    //Today

} elseif($interval->days == 1) {
    if($interval->invert == 0) {
        //Yesterday
    } else {
        //Tomorrow
    }
} else {
    //Sometime
}
Zeusarm
  • 1,038
  • 6
  • 14
  • 9
    This works pretty well. Just a warning, it is not always accurate. For example, if the time now is 10:30am and the time yesterday is 10:58am, $interval->days == 0, which makes that date seem to be "Today," which is not true. – Avindra Goolcharan Jan 13 '15 at 15:38
  • 7
    This is not a check for "today", but for "last 24 hrs" – sieppl Mar 29 '17 at 12:52
  • Today is not difference between dates. Today is the same day. – holden321 Nov 01 '21 at 12:40
10

There is no built-in functions to do that in Php (shame ^^). You want to compare a date string to today, you could use a simple substr to achieve it:

if (substr($timestamp, 0, 10) === date('Y.m.d')) { today }
elseif (substr($timestamp, 0, 10) === date('Y.m.d', strtotime('-1 day')) { yesterday }

No date conversion, simple.

Thomas Decaux
  • 21,738
  • 2
  • 113
  • 124
8

Simple one liners for today/yesterday/tomorrow:

$someDate = '2021-11-07'; // date in any format

$isToday = date('Ymd') == date('Ymd', strtotime($someDate));
$isYesterday = date('Ymd') == date('Ymd', strtotime($someDate) + 86400);
$isTomorrow = date('Ymd') == date('Ymd', strtotime($someDate) - 86400);
Shahroq
  • 969
  • 1
  • 8
  • 15
6
function getRangeDateString($timestamp) {
    if ($timestamp) {
        $currentTime=strtotime('today');
        // Reset time to 00:00:00
        $timestamp=strtotime(date('Y-m-d 00:00:00',$timestamp));
        $days=round(($timestamp-$currentTime)/86400);
        switch($days) {
            case '0';
                return 'Today';
                break;
            case '-1';
                return 'Yesterday';
                break;
            case '-2';
                return 'Day before yesterday';
                break;
            case '1';
                return 'Tomorrow';
                break;
            case '2';
                return 'Day after tomorrow';
                break;
            default:
                if ($days > 0) {
                    return 'In '.$days.' days';
                } else {
                    return ($days*-1).' days ago';
                }
                break;
        }
    }
}
BVB Media
  • 307
  • 3
  • 4
2

Pass the date into the function.

            <?php
                function getTheDay($date)
                {
                    $curr_date=strtotime(date("Y-m-d H:i:s"));
                    $the_date=strtotime($date);
                    $diff=floor(($curr_date-$the_date)/(60*60*24));
                    switch($diff)
                    {
                        case 0:
                            return "Today";
                            break;
                        case 1:
                            return "Yesterday";
                            break;
                        default:
                            return $diff." Days ago";
                    }
                }
            ?>
the_haystacker
  • 1,585
  • 18
  • 20
  • Except, this is really looking for more than a difference of 24 hours. If you are checking a time of yesterday afternoon compared to this morning, it should say yesterday. The key is to ignore the time parts, and look at just the dates. If you format each date with `date('Y-m-d')` then it will be comparing midnight on each day and they will either be equal or a multiple of 24 hours apart. Technically, you then wouldn't need the `floor()` function either. – Daniel Skarbek Feb 03 '17 at 22:58
1

Here is a more polished version of the accepted answer. It accepts only timestamps and returns a relative date or a formatted date string for everything +/-2 days

<?php

/**
 * Relative time
 *
 * date Format http://php.net/manual/en/function.date.php
 * strftime Format http://php.net/manual/en/function.strftime.php
 * latter can be used with setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');
 *
 * @param  timestamp $target
 * @param  timestamp $base   start time, defaults to time()
 * @param  string $format use date('Y') or strftime('%Y') format string
 * @return string
 */
function relative_time($target, $base = NULL, $format = 'Y-m-d H:i:s')
{

    if(is_null($base)) {
        $base = time();
    }

    $baseDate = new DateTime();
    $targetDate = new DateTime();

    $baseDate->setTimestamp($base);
    $targetDate->setTimestamp($target);

    // don't modify original dates
    $baseDateTemp = clone $baseDate;
    $targetDateTemp = clone $targetDate;

    // normalize times -> reset to midnight that day
    $baseDateTemp = $baseDateTemp->modify('midnight');
    $targetDateTemp = $targetDateTemp->modify('midnight');

    $interval = (int) $baseDateTemp->diff($targetDateTemp)->format('%R%a');

    d($baseDate->format($format));

    switch($interval) {
        case 0:
            return (string) 'today';
        break;

        case -1:
            return (string) 'yesterday';
        break;

        case 1:
            return (string) 'tomorrow';
        break;

        default:
            if(strpos($format,'%') !== false )
            {
                return (string) strftime($format,  $targetDate->getTimestamp());
            }
            return (string) $targetDate->format($format);
        break;

    }
}

setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');
echo relative_time($weather->time, null, '%A, %#d. %B'); // Montag, 6. August 
echo relative_time($weather->time, null, 'l, j. F'); // Monday, 6. August
marcus
  • 699
  • 11
  • 33
1

This worked for me, where I wanted to display keyword "today" or "yesterday" only if date was today and previous day otherwise display date in d-M-Y format

<?php
function findDayDiff($date){
   $param_date=date('d-m-Y',strtotime($date);
   $response  = $param_date;
   if($param_date==date('d-m-Y',strtotime("now"))){
       $response = 'Today';
   }else if($param_date==date('d-m-Y',strtotime("-1 days"))){
       $response = 'Yesterday'; 
   }
   return $response;
}
?>
Pooja
  • 356
  • 2
  • 11
1
function get_when($date) {

    $current = strtotime(date('Y-m-d H:i'));

    $date_diff = $date - $current;
    $difference = round($date_diff/(60*60*24));

    if($difference >= 0) {
            return 'Today';
    } else if($difference == -1) {
            return 'Yesterday';
    } else if($difference == -2 || $difference == -3  || $difference == -4 || $difference == -5) {
            return date('l', $date);
    } else {
            return ('on ' . date('jS/m/y', $date));
    }

}

get_when(date('Y-m-d H:i', strtotime($your_targeted_date)));
  • While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Alessio Oct 14 '19 at 14:56