PHP:如何将时间字符串与date('H:i')进行比较?

11

我在数据库中保存了一个类似于"7:30pm"的时间字符串,以varchar类型的字段存储。我想要检查这个时间是否大于现在的时间。

我将数据库中的时间字符串转换为'19:30',现在我想做像这样的事情:

$my_time = '19:30';

if($my_time  > date('H:i'))
{
    do something ...
}
以上代码中的问题是,如果 $my_time 是非空字符串,那么上述代码将始终返回 true。
使用 strtotime($my_time) 也不起作用。
strtotime('H:i',$my_time) 将其转换为 00:00。
使用 (int)date('H:i') 得到的结果是 1700,而实际时间是 17:09,因此去除冒号后进行比较也行不通。
在此情况下,更改数据库时间数据是不可行的。
请帮帮我,如果我说错了什么,请纠正我。

你应该使用本地日期时间字段而不是varchar。这将为您解决此问题。 - John Conde
https://dev59.com/JHNA5IYBdhLWcg3wcNbF - Haim Evgi
我认识John...那是最大的问题。 - sri_wb
5个回答

15

你可以使用这个:

$myTime = '19:30';
if (date('H:i') == date('H:i', strtotime($myTime))) {
    // do something
}

7
很多时间过去了,但是它不就是直接比较两个字符串吗?因为 date() 返回一个字符串,所以这就像是在做:if(date('H:i') == '19:30'),对吧?这正是 OP 所尝试的事情。这是因为 date('H:i', strtotime($myTime)) 会返回原始的 $myTime 值作为字符串!因此,这与仅仅将 $myTime 放在 date('H:i', strtotime($myTime)) 的位置上是相同的。那这样做的意义是什么呢?我真的不明白。我错过了什么吗?为什么 OP 建议的 if($my_time > date('H:i')) 似乎不起作用?因为它对我来说确实有效。 - DiegoDD
2
问题涉及如何比较一个数是否大于另一个数,不仅仅是相等比较。 - T.Todua

5

您可以构造一个新的DateTime对象,在随机日期上设置时间,然后比较这两个对象。例如:

$my_time = new DateTime('January 1th 1970 19:30');
$comparable_time = new DateTime('January 1th 1970 '. date('H:i'));
if($my_time < $comparable_time) {
    // do something
} else {
    // do something else
}

请注意更新日志:
Version 5.2.2    DateTime object comparison with the comparison operators changed to work as expected. Previously, all DateTime objects were considered equal (using ==).

2
你不能像那样使用比较运算符来比较字符串,因为这样做会先将字符串转换为数字。如果想要一行代码的解决方案,可以使用strcmp函数。
if(strcmp($my_time, date('H:i')) == 1)
{
    do something ...
}

上述条件在语义上等价于“如果$my_time大于当前时间”,但前提是字符串的格式保持一致! 如果由于任何原因$my_time的格式与H:i模式不直接对应,那么很容易在此代码中引入错误。

将值转换为字符串通常不是使用日期和时间的正确方法。更合适的解决方案是使用PHP 5.2.0引入的本地DateTime类(John Conde已经在他的答案中给出了一个示例)。

然而,将时间视为愚蠢的标量值也有一个可能的优点:结果与人类感知一致,即01:00总是晚于00:00。DateTime方法依赖于本地时区和日期,可能不会始终给您预期的结果。例如:

// assume we are in London
date_default_timezone_set('Europe/London');

// assume that today is March 25, 2012
$date1 = new DateTime("2012-03-25 01:00:00");
$date2 = new DateTime("2012-03-25 02:00:00");

// and...
if ($date1 == $date2) {
    echo "WTF?!? Equal???";
}

在实际操作中查看

这个测试的结果与比较“01:00”和“02:00”的某些标量表示不同,因此考虑比较的适当语义是一个好主意。


它正在使用印度加尔各答时区...运行。我想我可以在实际服务器上使用它。 - sri_wb

1
不要比较代表时间戳的字符串。相反,使用strtotime()将任何这样的字符串转换为Unix时间戳,这只是数字,然后进行比较。您可以使用time()获取当前时间的Unix时间戳:
$my_time = '19:30';

if (strtotime($my_time) > time()) {
    // do something ...
}

这是正确的答案。其他答案不能使用 > 或 <。 - ESP32

1
$date1 = DateTime::createFromFormat('H:i', $my_time1);
$date2 = new DateTime();
if ($date1 > $date2)
{
     // do something   
}

+1,还有必要的免责声明:根据当前日期和时区,此测试结果可能会令人惊讶。 - Jon
我遇到了以下错误:致命错误:在C:\ wamp \ www \ workspace \ bigbite \ index_parallel.php的第...行,未捕获异常'Exception',消息为'DateTime :: __construct()[<a href='datetime.--construct'>datetime.--construct</a>]:在位置1(:)处解析时间字符串(H:i)时出错:意外字符'。同时还有以下警告:在C:\ wamp \ www \ workspace \ bigbite \ index_parallel.php的第...行,异常:DateTime :: __construct()[<a href='datetime.--construct'>datetime.--construct</a>]:在位置1(:)处解析时间字符串(H:i)时出错:意外字符。 - sri_wb

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