PHP: How to check if a date is today, yesterday or tomorrow
Asked Answered
S

10

63

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.

Savino answered 2/9, 2014 at 11:30 Comment(4)
How is $timestamp defined and where?Vladamar
check date using strtotimeLilithe
I would advice you to take a look at Datetime object.. And most likely your $timestamp isn't being converted correctly.Hepzi
The $timestamp is Like "2014.09.02T13:34"Savino
P
61

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";
}
Phony answered 2/9, 2014 at 12:15 Comment(4)
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?Justification
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.Womera
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.Jenkins
You have to set the time zone ahead of all of this code otherwise it uses UTC time and may mean "now" is a day ahead of your saved date, which appears to be the same. ex. date_default_timezone_set('America/Chicago');Inward
M
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';
 }  
?>
Marcosmarcotte answered 2/9, 2014 at 12:7 Comment(6)
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: ideone.com/2D2N8IWomera
@Womera : Why this number is considered as a bug?Hoseahoseia
@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.Womera
Thanks @Womera for the explanation! I'll make a note of it as it seems an important point to remember.Hoseahoseia
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 TodayAcidity
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.Someway
C
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
}
Carner answered 2/9, 2014 at 11:45 Comment(3)
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.Congener
This is not a check for "today", but for "last 24 hrs"Chlorothiazide
Today is not difference between dates. Today is the same day.Kick
U
11

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);
Unselfish answered 7/11, 2021 at 9:52 Comment(0)
X
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.

Xenocryst answered 19/8, 2016 at 9:8 Comment(2)
If you have the integers, why would you compare the strings? :D Btw which language has such function?Silvie
@IvankaTodorova Swift does!Pawl
S
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;
        }
    }
}
Shocking answered 26/3, 2017 at 13:30 Comment(0)
I
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";
                    }
                }
            ?>
Impasto answered 15/3, 2016 at 7:19 Comment(1)
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.Saguaro
A
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
Aideaidedecamp answered 4/8, 2018 at 9:14 Comment(0)
S
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;
}
?>
Sandler answered 27/8, 2019 at 4:44 Comment(0)
S
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)));
Semi answered 14/10, 2019 at 14:30 Comment(1)
While this code snippet may solve the question, including an explanation 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.Avictor

© 2022 - 2024 — McMap. All rights reserved.