如何比较PHP 5.2.8中的两个DateTime对象?


299

看一下PHP文档,DateTime对象的以下两种方法似乎都可以解决我的问题:

这两种方法在doco中都标记为在版本=> 5.3中可用(并且毫不奇怪,如果我尝试调用它们,我会发现它们不存在)。我找不到5.2.8的任何特定文档,所以不确定我的版本中是否有等效的方法。我曾经用Google搜索这个问题,并找到解决方案,其中没有回答我很简单的要求,兼收并蓄的范围:

  • 如何比较两个DateTime对象?
  • 在哪里可以找到先前PHP版本的doco?特别是版本5.2.8?

在某些情况下,我有以下代码:

$st_dt = new DateTime(verifyParam ('start_date'));
$end_dt = new DateTime(verifyParam ('end_date'));

// is the end date more ancient than the start date?
if ($end_dt < $start_dt) 

显然,此人没有比较运算符。

编辑

显然我的假设是完全错误的(感谢Milen如此有效地说明了这一点)。有一个比较运算符,它很好用,谢谢。有时候我真的很想念编译器。该错误位于上面的代码中,我相信您会发现它的速度比我快:)。


1
关于缺少编译器-将“ error_reporting”设置为“ E_ALL”,您将收到诸如“ Notice:Undefined variable:start_dt in ...”之类的通知。
Milen A. Radev

5
另外,请在您的$_POSTvar上使用htmlentities ,否则小猫会被杀死。
克莱门特·赫雷曼

2
错误在哪里?:p,我也在做U_U。提前致谢!
castarco

2
@castarco我初始化$ st_dt,但是我将其与未初始化的$ start_dt进行比较。检查您的变量名,并可能遵循Milen的建议,并将error_reporting设置为E_ALL以获取未定义的变量警告。:)
RedBlueThing

Answers:


442

以下内容似乎可以确认DateTime类具有比较运算符:

dev:~# php
<?php
date_default_timezone_set('Europe/London');

$d1 = new DateTime('2008-08-03 14:52:10');
$d2 = new DateTime('2008-01-03 11:11:10');
var_dump($d1 == $d2);
var_dump($d1 > $d2);
var_dump($d1 < $d2);
?>
bool(false)
bool(true)
bool(false)
dev:~# php -v
PHP 5.2.6-1+lenny3 with Suhosin-Patch 0.9.6.2 (cli) (built: Apr 26 2009 20:09:03)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
dev:~#

7
谢谢Milen,看起来我只需要删除我的错误假设,突然我的代码中的明显错误对我来说变得显而易见。
RedBlueThing

2
嗯,这很有趣。也许到某个时候,我们将能够在用户定义的类中重载运算符。
Ionuț G. Stan,2009年

1
php.net/manual/en/language.operators.comparison.php内置的类可以定义自己的比较,不同的类是不可比的,同一类-比较属性的方式与数组相同(PHP 4),PHP 5具有自己的解释
扫罗(Saul)2010年

7
当比较没有设置小时数和设置了小时数的日期时间时要
当心

1
TiMESPLiNTER,我相信警告是,如果您仅对比较日期感兴趣,您可能会忽略小时数不同的事实,因此,DateTime具有相同日期的两个s在您认为应该比较时不会相等。您可以通过在比较之前将对象的时间分量显式设置为零来对此进行补救。
杰森

55

官方文档中

从PHP 5.2.2开始,可以使用比较运算符比较DateTime对象。

$date1 = new DateTime("now");
$date2 = new DateTime("tomorrow");

var_dump($date1 == $date2); // false
var_dump($date1 < $date2); // true
var_dump($date1 > $date2); // false

对于5.2.2之前的PHP版本(实际上适用于任何版本),可以使用diff

$datetime1 = new DateTime('2009-10-11'); // 11 October 2013
$datetime2 = new DateTime('2009-10-13'); // 13 October 2013

$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days'); // +2 days

4
我发现这个答案是最好的,因为它引用了手册,而不是仅仅检查行为并假设结果是预期的。所以不是一个猜测的地方。布拉沃·罗伯托(Bravo Roberto)。
cprn

4
@roberto DateTime :: diff仅在PHP 5.3中添加
NeXuS

32

您还可以比较纪元秒:

$d1->format('U') < $d2->format('U')

来源:http : //laughingmeme.org/2007/02/27/looking-at-php5s-datetime-and-datetimezone/ (有关DateTime的有趣文章)


16
当心format产生一个string,所以这是一个字符串比较。在10亿个纪元时间(大约是2001年9月9日)之后,这几乎不是问题,但是如果您必须之前处理日期,则由于数字长度不同,可能会引起问题。可以将结果转换为数字(减去也可以),或者使用真正可排序的格式,例如c
MaxArt

1
@MaxArt您能否详细说明由于字符串长度不同而引起的问题?该手册涉及数字上下文中的字符串“如果字符串不包含任何字符'。','e'或'E',并且数值适合整数类型限制(由PHP_INT_MAX定义),则该字符串将被评估为整数。在所有其他情况下,将被评估为浮点数。” 将来的日期(大约2038年)可能会溢出带符号的32位整数,但是较早的日期有什么问题?
阿德里安·昆特

1
@AdrianGünter问题是我们不会处于数字上下文中,但是会处理string。数字,但仍然是字符串。因此将进行字符串比较。
MaxArt 2015年


2
@FrédéricMarchal是的,后来我确实得知我以前的评论实际上是错误的。PHP有一种非常邪恶的方式来处理这些情况,当您要比较两个字符串时,没有其他语言(据我所知)会强制转换为数字。如果您确实想进行词典比较,这确实会弄乱您的代码。
MaxArt 2016年

21

如果要比较日期而不是时间,可以使用以下方法:

$d1->format("Y-m-d") == $d2->format("Y-m-d")

5
您还可以设置重置时间。$d1->setTime(0, 0, 0);
阿斯兰

3

从PHP 7.x开始,您可以使用以下代码:

$aDate = new \DateTime('@'.(time()));
$bDate = new \DateTime('@'.(time() - 3600));

$aDate <=> $bDate; // => 1, `$aDate` is newer than `$bDate`

1
$elapsed = '2592000';
// Time in the past
$time_past = '2014-07-16 11:35:33';
$time_past = strtotime($time_past);

// Add a month to that time
$time_past = $time_past + $elapsed;

// Time NOW
$time_now = time();

// Check if its been a month since time past
if($time_past > $time_now){
    echo 'Hasnt been a month';    
}else{
    echo 'Been longer than a month';
}

时间戳有一些限制,您可能需要阅读一下stackoverflow.com/a/7229760/2652018
Steel Brain

很高兴知道!这只是一种比较时间的简单方法。
凯尔·库克斯

-1

这可能对您有帮助。

$today = date("m-d-Y H:i:s");
$thisMonth =date("m");
$thisYear = date("y");
$expectedDate = ($thisMonth+1)."-08-$thisYear 23:58:00";


if (strtotime($expectedDate) > strtotime($today)) {
    echo "Expected date is greater then current date";
    return ;
} else
{
 echo "Expected date is lesser then current date";
}

时间戳有一些限制,您可能需要阅读一下stackoverflow.com/a/7229760/2652018
Steel Brain

@SteelBrain您认为时间戳限制会困扰上面具有所有当前日期时间的代码,请再次阅读该代码,它基本上检查的家伙$ expectedDate总是在当前月份。我不认为,因此在这种情况下,我们应该考虑这里的时间戳限制。
塔伦·古普塔

我知道,但这不是推荐的方法,(我没有拒绝投票:
Steel Brain

您能建议一种推荐的方法吗?
塔伦·古普塔

当然,$today = new DateTime("now"); $time = DateTime::createFromFormat('d-m-Y',"26-October-1998"); if ($today > $time){echo "today is greater";}else{echo "other time is greater";}欢呼。
Steel Brain
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.