MYSQL日期时间四舍五入到最近的小时

MYSQL日期时间四舍五入到最近的小时,mysql,datetime,Mysql,Datetime,我在MySQL数据库中有一个日期时间字段,希望将结果输出到最近的小时 e、 g.2012-04-01 00:00:01应改为2012-04-01 00:00:00 使用datetime数据类型时有点麻烦;一个很好的存储函数候选者 DATE_SUB(DATE_SUB(time, INTERVAL MOD(MINUTE(time),5) MINUTE ), INTERVAL SECOND(time) SECOND) 使用UNIXTIME时间戳会更容易,但仅限于1970-2038

我在MySQL数据库中有一个日期时间字段,希望将结果输出到最近的小时

e、 g.2012-04-01 00:00:01应改为2012-04-01 00:00:00

使用datetime数据类型时有点麻烦;一个很好的存储函数候选者

DATE_SUB(DATE_SUB(time, INTERVAL MOD(MINUTE(time),5) MINUTE ), 
         INTERVAL SECOND(time) SECOND)
使用UNIXTIME时间戳会更容易,但仅限于1970-2038年的日期范围

FROM_UNIXTIME(UNIX_TIMESTAMP(time) - MOD(UNIX_TIMESTAMP(time),300))
祝你好运

更新:我认为这是一个更好的答案

您可以使用一些日期算术:

SELECT some_columns,
    DATE_ADD(
        DATE_FORMAT(the_date, "%Y-%m-%d %H:00:00"),
        INTERVAL IF(MINUTE(the_date) < 30, 0, 1) HOUR
    ) AS the_rounded_date
FROM your_table
说明:

:DATE\u format\u日期,%Y-%m-%d%H:00:00返回被截断为最接近的小时的日期,并将分钟和秒数设置为零

:MINUTEthe_date获取日期的分钟值

:这是有条件的;如果参数1中的值为true,则返回参数2,否则返回参数3。因此,如果minutethe_date<30,0,1表示如果minute值小于30,则返回0,否则返回1。这就是我们将要用来取整的时间——这是要加回去的小时数

:这会将整轮的小时数添加到结果中


soul的第一个解决方案是截断而不是舍入,第二个解决方案不适用于夏令时情况,例如:

select FROM_UNIXTIME(UNIX_TIMESTAMP('2012-03-11 2:14:00') - MOD(UNIX_TIMESTAMP('2012-03-11 2:14:00'),300));
以下是另一种方法1:

DATE_ADD(
    tick,
    INTERVAL (IF((MINUTE(tick)*60)+SECOND(tick) < 1800, 0, 3600) - (MINUTE(tick)*60)+SECOND(tick)) SECOND
)
编辑:我在本地计算机上分析了其中一些查询,发现100000行的平均查询时间如下:

soul的UNIXTIME方法:0.0423毫秒快,但不适用于DST 我的方法3:0.1255 ms 我的方法2:0.1289毫秒 Ben Lee's DATE_格式方法:0.1495 ms 我的方法1:0.1506 ms
这将在下一个小时返回,即“2012-01-02 18:02:30”将转换为“2012-01-02 19:00:00”

您可以使用任意日期代替CURDATE,例如“2000-01-01” 如果系统日期在两次函数调用之间发生变化,不确定使用CURDATE是否会出现问题,不知道Mysql是否会同时调用这两个函数

要获取最近的小时数,请执行以下操作:

TIMESTAMPADD(MINUTE,
    ROUND(TIMESTAMPDIFF(MINUTE,CURDATE(),timestamp_column_name)/60)*60,
    CURDATE())
将60乘以15将得到最接近的15分钟间隔,使用秒可以得到最接近的所需秒间隔,以此类推

要获得前一个小时,请使用截断或地板,而不是圆形


希望这能有所帮助。

半小时是30分钟。只需在时间戳上添加30分钟,并截断分和秒


从表中选择“日期”\u FORMATDATE\u ADDtimestamp\u列,间隔30分钟,“%Y-%m-%d%H:00:00”

如果您需要将时间四舍五入到下一个小时,您可以使用以下选项:

SELECT TIME_FORMAT(
  ADDTIME(
    TIMEDIFF('16:15', '10:00'), '00:59:00'
  ),
  '%H:00:00'
)

我认为这是最好的方法,因为它也将使用最少的资源-

date_add(date(date_completed), interval hour(date_completed) hour) as date_hr

要向下取整到当前小时,请选择:

从\u unixtimeflorunix\u TIMESTAMPcolumn\u name/3600*3600

该值以当前时区表示


小心这个。对于介于夏令时更改之间的日期时间,unix时间方法失败。例如:从时间戳'2012-03-11 2:14:00'-MODUNIX_时间戳'2012-03-11 2:14:00',300'中选择;我打勾是因为我只想截短?U格式慢吗?我从没听说过。你有这方面的参考/基准吗?我在谷歌上找不到任何关于DATE_格式性能差的信息,也没有任何迹象表明调用MINUTE和SECOND会比调用DATE_格式快很多。在任何情况下,性能差异不应该是纳秒级的吗?对于几乎所有现实世界的用途来说,本质上是看不见的/可以忽略不计的?@BenLee我预计操纵字符串和解析日期的速度会比分/秒慢得多,但在分析了这两种情况之后,情况就不是这样了。您的解决方案甚至可能比我的解决方案快一点,这可能是因为我的分秒呼叫两次?。但是,我的示例省略了秒,比DATE\u格式快。我将更新我的答案。对于任何其他人的信息,要截断为其他分钟间隔,例如15分钟:选择时间戳、日期子时间戳、间隔分钟时间戳%15*60+秒时间戳秒…可能重复
TIMESTAMPADD(MINUTE,
    ROUND(TIMESTAMPDIFF(MINUTE,CURDATE(),timestamp_column_name)/60)*60,
    CURDATE())
SELECT TIME_FORMAT(
  ADDTIME(
    TIMEDIFF('16:15', '10:00'), '00:59:00'
  ),
  '%H:00:00'
)
date_add(date(date_completed), interval hour(date_completed) hour) as date_hr