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

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

DateTime :: diff:获取差异并使用该差异确定哪个更古老。

DateTime :: getTimestamp:获取UNIX时间戳并进行比较。

这两种方法在doco中都标记为在版本> = 5.3中可用(并且毫不奇怪,如果我尝试调用它们,我会发现它们不存在)。我找不到5.2.8的任何特定文档,所以不确定我的版本中是否有等效的方法。我已经搜索了这个问题,并找到了不拘一格的解决方案,但没有一个能满足我的简单要求:

如何比较两个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如此有效地说明了这一点)。有一个比较运算符,它很好用,谢谢。有时我真的很想念编译器。该错误在上面的代码中,我相信您会发现它的速度比我快:)。

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

干杯Milen,我会那样做的。

另外,请在您的$_POST变量上使用htmlentities,否则小猫会被杀死。

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

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

以下内容似乎可以确认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 -vPHP 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:~#

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

嗯,这很有趣。也许在某个时候能够在用户定义的类中重载运算符。

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

比较未设置小时和设置时的日期时间(默认构造函数)

@ max4ever如果您比较设置和不设置小时数的DateTime对象,是否会有奇怪的行为?我尝试过,如果未设置小时,则其行为类似于时间00:00:00。因此,如果将2008-08-03 00:00:00与2008-08-03进行比较,则它们相等。

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

@Jason并且由于DateInterval不会像DateTime那样使比较运算符超载(我什至无法理解的PHP内部团队都忽略了这一点),所以您甚至也无法自然地做到这一点:if ($datetimeA->diff($datetimeB) < DateInterval::createFromDateString(4 days)) { …

检查行为并按预期进行猜测("似乎要确认"吗?)会导致非常令人讨厌的错误,尤其是当答案已经在官方文档中并且可能无需费力地引用时。下面有一种更好的答案。

请记住,严格比较(===)会比较对象,而不是值,因此在这种情况下,它始终评估为false。

从官方文档中:

As of PHP 5.2.2, DateTime objects can be compared using comparison operators.

$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

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

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

您还可以比较纪元秒:

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

资料来源:http://laughingmeme.org/2007/02/27/looking-at-php5s-datetime-and-datetimezone/

(有关DateTime的很多有趣的文章)

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

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

@AdrianGnter问题是我们不会在数字上下文中,但是会处理字符串。数字,但仍然是字符串。因此将进行字符串比较。

@MaxArt啊,现在我明白了。在这种情况下,它的作用类似于strcmp。

@MaxArt:根据文档:如果将数字与字符串进行比较或比较涉及数字字符串,则每个字符串都将转换为数字,并以数字方式进行比较。这些规则也适用于switch语句。当比较===或!==时,不会进行类型转换,因为这涉及比较类型和值。

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

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

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

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

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

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

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

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

$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

很高兴知道! 这只是一种比较时间的简单方法。

这可能对您有帮助。

$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

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

我知道,但这不是推荐的方式,(我没有拒绝投票:-))

您能建议一种推荐的方法吗?

当然,$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";}会加油。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值