Php 使用MySQL CURTIME();ADDTIME()你如何应对午夜过渡?

Php 使用MySQL CURTIME();ADDTIME()你如何应对午夜过渡?,php,mysql,Php,Mysql,我有一个表(flightSched),其中包含航班号、航班到达日期、航班到达或离开时间,最重要的是航班到达时间,如下所示 +-------------+----------------+-----------------+-----------------+ | FlightNo | don | depOrArriv | arrivalTime | +-------------+----------------+-----------------+

我有一个表(flightSched),其中包含航班号、航班到达日期、航班到达或离开时间,最重要的是航班到达时间,如下所示

+-------------+----------------+-----------------+-----------------+
| FlightNo    | don            | depOrArriv      | arrivalTime     | 
+-------------+----------------+-----------------+-----------------+
| ET821       | Daily          | Arrival         | 19:45:24        |
| MS838       | Tuesday        | Arrival         | 00:05:24        |
| H7361       | Tuesday        | Arrival         | 23:15:06        |
+-------------+----------------+-----------------+-----------------+
我想在表中显示当前时间与当前时间提前四小时之间的所有航班

请在下面找到我的查询

SELECT * 
FROM flightSched
WHERE  `arrivalTime` 
BETWEEN CURTIME() 
AND ADDTIME( CURTIME() ,  '04:00:00' ) 
ORDER BY arrivalTime ASC 
LIMIT 0 , 30
在航班午夜后到达/起飞之前,查询工作正常。根据上表,如果当前时间为21:00:00,则不会显示航班号MS838。 我哪里做错了


有人能指出我的问题哪里出了错吗

我认为这是因为
ADDTIME
没有按照您的想法进行操作,请看以下示例:

mysql> SELECT ADDTIME( '19:59:59' ,  '04:00:00' );
+-------------------------------------+
| ADDTIME( '19:59:59' ,  '04:00:00' ) |
+-------------------------------------+
| 23:59:59                            |
+-------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ADDTIME( '20:00:01' ,  '04:00:00' );
+-------------------------------------+
| ADDTIME( '20:00:01' ,  '04:00:00' ) |
+-------------------------------------+
| 24:00:01                            |
+-------------------------------------+
1 row in set (0.00 sec)

mysql>
一种可能的解决方案是将查询
WHERE
子句更改为使用
TIMEDIFF
,然后确保差异在特定范围之间

如果我们以一些时间值为例,将
TIMEDIFF
结果与中午进行比较,我们会得到以下结果:

+----------+---------------------------------+
| time     | TIMEDIFF(MAKETIME(12,0,0),time) |
+----------+---------------------------------+
| 01:00:00 | 11:00:00                        |
| 03:00:00 | 09:00:00                        |
| 05:00:00 | 07:00:00                        |
| 07:00:00 | 05:00:00                        |
| 11:00:00 | 01:00:00                        |
| 13:00:00 | -01:00:00                       |
| 15:00:00 | -03:00:00                       |
| 17:00:00 | -05:00:00                       |
| 19:00:00 | -07:00:00                       |
| 21:00:00 | -09:00:00                       |
| 23:00:00 | -11:00:00                       |
+----------+---------------------------------+
未来的时间会导致负时差(参数按显示的顺序提供),因此对于未结束的时间,我们知道-00:00:00到-04:00:00之间的任何范围都是可以接受的(基于您提前0-4小时的更新)

因此,要检查正常的无包裹时间,应采用以下方法:

TIMEDIFF(CURTIME(),
到达时间
) 在MAKETIME(-4,0,0)和MAKETIME(0,0,0)之间

如果我们随后检查不换行的值:

+----------+----------------------------------+
| time     | TIMEDIFF(MAKETIME(23,30,0),time) |
+----------+----------------------------------+
| 01:00:00 | 22:30:00                         |
| 03:00:00 | 20:30:00                         |
| 05:00:00 | 18:30:00                         |
| 07:00:00 | 16:30:00                         |
| 11:00:00 | 12:30:00                         |
| 13:00:00 | 10:30:00                         |
| 15:00:00 | 08:30:00                         |
| 17:00:00 | 06:30:00                         |
| 19:00:00 | 04:30:00                         |
| 21:00:00 | 02:30:00                         |
| 23:00:00 | 00:30:00                         |
+----------+----------------------------------+
我们认为超过20小时的数值应该是可以接受的

  OR TIMEDIFF( CURTIME() ,  `arrivalTime` ) > MAKETIME(20,0,0)

随着要求从30米到4米的时差变化,可能需要完全改变方法,将整个时间戳转换为午夜后的秒数,然后比较差异,根据一天中的秒数对其进行模化,并检查结果。

是的!我终于解决了所有问题

因为我需要一个查询来区分当天到达的航班和午夜后第二天到达的航班(基于时间),所以我不得不稍微重新构造表(flightSched)通过将arrivalTime列数据从TIME更改为DATETIME。随后,这意味着此列中的内容将以以下格式保存:YYYY-MM-DD HH:MM:SS或(2013-11-22 12:30:00),而不仅仅是12:30:00,更丰富

然后,我注意到下面的查询以算术方式正确计算了进入第二天/午夜后的日期的时间

如果当前时间为21:00

//################################################
//## Subtract the 30 minutes from the current time
mysql> SELECT SUBTIME(NOW(), '00:30:00' );
+-------------------------------------+
| SUBTIME(NOW(),  '00:30:00' )        |
+-------------------------------------+
| 2013-11-22 20:30:00                 |
+-------------------------------------+
1 row in set (0.00 sec)

//################################################
//## Add the 4 hours to the current time


mysql> SELECT ADDTIME(NOW(),  '04:00:00');
+-------------------------------------+
| ADDTIME(NOW() ,  '04:00:00' )       |
+-------------------------------------+
| 2013-11-23 01:00:00                 |
+-------------------------------------+
1 row in set (0.00 sec)
注意!日期从2013-11-22 21:00:00到2013-11-23 01:00:00的变化是多么完美。 :-)

使用下表

+-------------+----------------+-----------------+---------------------+
| FlightNo    | don            | depOrArriv      | arrivalTime         | 
+-------------+----------------+-----------------+---------------------+
| ET821       | Daily          | Arrival         | 2013-11-22 19:45:24 |
| MS838       | Tuesday        | Arrival         | 2013-11-23 01:05:24 |
| H7361       | Tuesday        | Arrival         | 2013-11-22 23:15:06 |
+-------------+----------------+-----------------+---------------------+
正在运行的查询:

SELECT * FROM flightSched WHERE arrivalTime
                                 BETWEEN  SUBTIME(NOW(), '00:30:00')
                 AND ADDTIME(NOW(),'04:00:00')
                 ORDER BY arrivalTime ASC 
收益率:

+-------------+----------------+-----------------+---------------------+
| MS838       | Tuesday        | Arrival         | 2013-11-23 01:05:24 |
| H7361       | Tuesday        | Arrival         | 2013-11-22 23:15:06 |
+-------------+----------------+-----------------+---------------------+

非常感谢您的时间和努力。

很抱歉对这个答案进行了大量的编辑,我已经测试了这个解决方案,我相信它是有效的。有人有更优雅的解决方案吗?谢谢你指出我错了。我确实尝试过你的查询,但没有得到任何结果。再看看你的解决方案,我希望30分钟前到4小时后的所有结果都能显示出来,而不是4小时前到当前时间。非常感谢您提供更多建议。抱歉,请解释如何解释此时间差(CURTIME(),
arrivalTime
),它将导致小时数:分钟数:秒数的差异。使用selecttimediff('01:00:00','02:00:00')进行实验;然后试着比较>、<和BETWEEN以及MAKETIME(h、m、s),谢谢你的建议。请容忍我,我对PHP和MySQL有点陌生。如果我理解正确,那么MAKETIME(-4,0,0)和MAKETIME(0,0,0)之间的代码表示从4小时前到当前时间之间。我说得对吗?如果是这样的话,我想出了一个更接近原点的方法:在MAKETIME(-4,0,0)和MAKETIME(20,0,0)之间选择*FROM
flightSched
WHERE
arrivalTime