【问题标题】:Get the next xx:30 time (the next half-past hour) after a specified time获取指定时间后的下一个 xx:30 时间(下一个半小时)
【发布时间】:2009-10-28 19:37:31
【问题描述】:

我正在尝试查找一个 MySQL 查询,该查询将从指定的日期时间获取下一个半小时的时间。我明确指的是下一个半小时,而不是下一个半小时。

例如:

  • 如果日期时间是“2009-10-27 08:15:24”,答案是 "2009-10-27 08:30:00"
  • 如果 日期时间是“2009-10-27 08:49:02”, 答案是“2009-10-27 09:30:00”。

我遇到了this page,它指的是 SQL Server,并且在该线程的末尾存在类似的问题。但又不太一样,它依赖于一个 MySQL 没有的功能。

以下是示例和预期返回值的完整列表:

2009-10-27 08:15:24  should return  2009-10-27 08:30:00
2009-10-27 08:49:02  should return  2009-10-27 09:30:00
2009-10-27 23:49:10  should return  2009-10-28 00:30:00
2009-10-27 10:30:00(.000001)  should return  2009-10-27 11:30:00

(请注意,在第四个示例中,由于确切的半点 (10:30:00.0000000) 已经过去,因此会找到下一个半点。)

我试过用这种东西:

SELECT IF( (MINUTE(NOW()) < 30), HOUR(NOW()), (HOUR(NOW()) + 1) )

(之后会添加一个 CONCATed 字符串),但它会因为切换到另一天而失败,并且感觉本质上是“hacky”。​​

谁能推荐一种合适的算法?我不希望得到完整的答案(尽管那会很好!),但是关于算法类型的建议会有所帮助。我已经在纸上画了两个小时了!我有一种预感,使用模数可能有用,但我对使用它还不够熟悉。

答案将在稍后提供给 PHP 类,但如果可能的话,我宁愿在 SQL 级别实现它,因为查询的其余部分也有效地执行其他日期比较功能。

【问题讨论】:

    标签: mysql datetime date


    【解决方案1】:

    这有点乱,但有效:

    select from_unixtime( floor((unix_timestamp(MY_DATE)+(30*60))/(60*60))*(60*60) + (30*60) )
    

    它将时间向前推 30 分钟,然后截断到小时的顶部,然后增加 30 分钟。因为它使用的是 unix 时间戳(自 1970 年以来的秒数),所以您不必担心天、月、年等的界限。

    【讨论】:

    • 谢谢 - 我认为这是一个非常优雅的解决方案。在我的脑海中,我想到了 30 分钟换档然后取消换档的想法,但这是我没有考虑到的一个小时的地板。非常感谢!
    【解决方案2】:

    我不禁注意到,这在 PHP 级别会非常更容易 :-) 也就是说,您可以这样做:

    1. 使用DATE_ADD() 为您的日期时间增加 30 分钟;如果已经过了半小时,这将移动到下一个小时
    2. 通过提取日期/小时和硬编码分钟/秒来创建新的日期时间值。 CONVERT()ADDTIME()MAKETIME() 都可以帮忙。

    最终结果是:

    select ADDTIME(
     CONVERT(DATE(DATE_ADD(yourDateTime, INTERVAL 30 MINUTE)), DATETIME), # date part
     MAKETIME(HOUR(DATE_ADD(yourDateTime, INTERVAL 30 MINUTE)), 30, 0) # hour + :30:00
    ) from ...
    

    【讨论】:

    • 也感谢您。我应该补充一点,我想避免在 PHP 级别执行此操作,以便时间绝对与查询中的其他基于日期的计算同步,之后在 PHP 中执行此操作无法确定。
    【解决方案3】:

    使用 MAKETIME(hour,minute,second) 函数构造所需的值。

    【讨论】:

      猜你喜欢
      • 2016-03-19
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多