PHP:如何检查日期是否为今天、昨天或明天

62

我想检查一个日期是否是今天、明天、昨天或其他日期。 但我的代码不起作用。

代码:

$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

}

代码始终位于else情况中。


$timestamp 是如何定义的,它在哪里定义的? - Funk Forty Niner
使用strtotime检查日期 - Khushboo
我建议您查看Datetime对象。很可能您的$timestamp没有被正确转换。 - Naruto
$timestamp 就像是 "2014.09.02T13:34"。 - R2D2
10个回答

62
首先,你在使用函数strtotime时犯了一个错误,请参考PHP文档
int strtotime ( string $time [, int $now = time() ] )

你需要修改你的代码,将整数时间戳传递给这个函数。
第二点,你使用的格式是"d.m.Y H:i",包括时间部分。如果你只想比较日期,你必须去掉时间部分,例如 `$date = date("d.m.Y");`。
第三点,我不确定它是否对你起作用,但是我的PHP无法理解来自`$timestamp`的日期格式,并且返回`01.01.1970 02:00`到`$match_date`。
$timestamp = "2014.09.02T13:34";
date('d.m.Y H:i', strtotime($timestamp)) === "01.01.1970 02:00";

你需要检查strtotime($timestamp)是否返回正确的日期字符串。如果不是,你需要指定$timestamp变量中使用的格式。你可以使用以下其中一种函数来完成这个任务:date_parse_from_formatDateTime::createFromFormat
这是一个工作示例:
$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";
}

你的 switch 语句中什么样的 case 会导致 "sometimes" 的情况?只有当 $today$match_date 没有正确格式化为日期时才会出现这种情况吗? - DACrosby
3
一种可能的改进:$today 可以被定义为 new DateTime("today"),这意味着是今天的午夜时间点 -- 时间部分会自动归零。 - Jon
仅检查 (integer)$diff->format( "%R%a" ) == 0 是不准确的。这也适用于十年前的同一天。对于今天,请检查 $diff->days == 0,对于昨天/明天,请检查 $diff->days == 1$diff->invert - MIvanIsten

32
<?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';
 }  
?>

5
每当你在代码中看到数字86400(60 * 60 * 24),就知道它有一个漏洞。这在这个例子中也是正确的:http://ideone.com/2D2N8I - Jon
@Jon:为什么这个数字被认为是一个 bug? - meDeepakJain
4
@DeepakJain 因为并非所有的日子都是86400秒长。由于夏令时,有些日子较短,有些日子较长;此外还有闰秒。这些事件当然很罕见,但它们在发生时会破坏你的代码。例如,在我上面提供的ideone链接中,如果选择某些特定日期,这段代码会报告错误的结果。 - Jon
感谢@Jon的解释!我会记下来,因为它似乎是一个重要的需要记住的点。 - meDeepakJain
1
你确定这个代码能正常工作吗?如果日期属于17小时前,比如说现在是下午4点,那么它属于昨天,但是你的代码会显示今天。 - Amin
这个不应该有这么多赞。它计算的是24小时的时间段,而不是“日期”是否真的是昨天。请谨慎使用,因为它可能会导致意外的结果。 - FontFamily

16

我认为这会对你有所帮助:

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

9
这个功能相当不错。只是需要注意的是,它并不总是准确的。例如,如果现在的时间是上午10:30,昨天的时间是上午10:58,$interval->days == 0,这会让那个日期看起来是“今天”,但实际上不是。 - Avindra Goolcharan
7
这不是针对“今天”的检查,而是针对“过去24小时”的。 - sieppl
今天日期没有差异。今天是同一天。 - holden321

10

Php中没有内置函数可以做到这一点(有点遗憾^^)。如果您想将日期字符串与今天进行比较,您可以使用简单的substr 来实现:

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

不进行日期转换,简单明了。


如果你已经有整数,为什么要比较字符串呢? :D 顺便问一下,哪种语言有这样的函数? - Ivanka Todorova
2
@IvankaTodorova Swift可以! - Balázs Vincze

10

今天/昨天/明天的简单一句话:

$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);

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

2
将日期传递到函数中。
            <?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";
                    }
                }
            ?>

除此之外,这实际上需要比24小时的差异更多。如果您正在比较昨天下午和今天早上的时间,则应该显示昨天。关键是忽略时间部分,只看日期。如果您使用date('Y-m-d')格式化每个日期,则将比较每天的午夜,并且它们将相等或相差24小时的倍数。从技术上讲,您也不需要floor()函数。 - Daniel Skarbek

1
这是被接受的答案的更加精细的版本。它只接受时间戳,并为+/-2天内的所有内容返回一个相对日期或格式化的日期字符串。
<?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

1
这对我很有帮助,我的目的是仅在日期为今天和昨天时显示关键词“今天”或“昨天”,否则以d-M-Y格式显示日期。
<?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;
}
?>

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

虽然这段代码片段可能解决了问题,但包括解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议原因。 - Alessio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接