如何在 MySQL 中对 DateTime 进行四舍五入?

发布于 2024-08-15 08:24:44 字数 367 浏览 5 评论 0原文

我想以 5 分钟的分辨率离散化日期时间。我是用C#做的,但是下面的代码如何转换成MySQL呢?

DateTime Floor(DateTime dateTime, TimeSpan resolution)
{
    return new DateTime
        (
             timeSpan.Ticks * 
             (long) Math.Floor
             (
                  ((double)dateTime.Ticks) / 
                  ((double)resolution.Ticks)
             )
        );
}

I want to discretize the DateTime with the resolution of 5 minutes. I did it in C#, but how to convert the following code to MySQL?

DateTime Floor(DateTime dateTime, TimeSpan resolution)
{
    return new DateTime
        (
             timeSpan.Ticks * 
             (long) Math.Floor
             (
                  ((double)dateTime.Ticks) / 
                  ((double)resolution.Ticks)
             )
        );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

呢古 2024-08-22 08:24:44

当您使用日期时间数据类型时,这有点令人讨厌;存储函数的一个很好的候选者。

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))

祝你好运。

It's a little nasty when you do it with datetime data types; a nice candidate for a stored function.

DATE_SUB(DATE_SUB(time, INTERVAL MOD(MINUTE(time),5) MINUTE ), 
         INTERVAL SECOND(time) SECOND)

It's easier when you use UNIXTIME timestamps but that's limited to a 1970 - 2038 date range.

FROM_UNIXTIME(UNIX_TIMESTAMP(time) - MOD(UNIX_TIMESTAMP(time),300))

Good luck.

酒绊 2024-08-22 08:24:44
from_unixtime(floor(unix_timestamp('2006-10-10 14:26:01')/(60*5))*(60*5))
+---------------------------------------------------------------------------+
| from_unixtime(floor(unix_timestamp('2006-10-10 14:26:01')/(60*5))*(60*5)) |
+---------------------------------------------------------------------------+
| 2006-10-10 14:25:00                                                       |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)

您可以将两个5替换为其他值

from_unixtime(floor(unix_timestamp('2006-10-10 14:26:01')/(60*5))*(60*5))
+---------------------------------------------------------------------------+
| from_unixtime(floor(unix_timestamp('2006-10-10 14:26:01')/(60*5))*(60*5)) |
+---------------------------------------------------------------------------+
| 2006-10-10 14:25:00                                                       |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)

you can replace the two 5s with other values

不离久伴 2024-08-22 08:24:44

您看过 MySQL 中的 CAST 功能吗?

Have you had a look at the CAST functionality in MySQL?

余生再见 2024-08-22 08:24:44

您可以查看此处。此示例是四舍五入到最接近的 X 分钟的一般情况,并用 T-SQL 编写,但两种情况下的逻辑和大多数函数都是相同的。

You can look here. This example is a general case for rounding to the nearest X minutes, and is written in T-SQL, but the logic and the majority of the functions will be the same in both cases.

jJeQQOZ5 2024-08-22 08:24:44

另一种选择:

要获取最近小时:

TIMESTAMPADD(MINUTE,
    ROUND(TIMESTAMPDIFF(MINUTE,CURDATE(),timestamp_column_name)/60)*60,
    CURDATE())

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

将 60 更改为 15 将获得最接近的 15 分钟间隔,使用 SECOND 您可以获得最接近的所需秒间隔,依此类推。

要获取前一小时,请使用 TRUNCATE()FLOOR()而不是ROUND()

希望这有帮助。

Another alternative:

to get the nearest hour:

TIMESTAMPADD(MINUTE,
    ROUND(TIMESTAMPDIFF(MINUTE,CURDATE(),timestamp_column_name)/60)*60,
    CURDATE())

Instead of CURDATE() you can use an arbitrary date, for example '2000-01-01'
Not sure if there could be problems using CURDATE() if the system date changes between the two calls to the function, don't know if Mysql would call both at the same time.

changing 60 by 15 would get the nearest 15 minutes interval, using SECOND you can get the nearest desired second interval, etc.

To get the previous hour use TRUNCATE() or FLOOR() instead of ROUND().

Hope this helps.

乞讨 2024-08-22 08:24:44

这是基于此线程的解决方案的另一种变体。

SELECT DATE_ADD(
           DATE_FORMAT(time, "%Y-%m-%d %H:00:00"),
           INTERVAL FLOOR(MINUTE(time)/5)*5 MINUTE
       );

与使用 FROM_UNIXTIME 的解决方案不同,此解决方案将给出夏令时 (DST) 转换范围内的日期时间的预期值。 (例如比较 2012-11-03 2:14:00)

编辑 - 然而,经过一些快速基准测试后,Ollie 的第一个解决方案的执行速度似乎比这更快。但我仍然建议不要使用 FROM_UNIXTIME 方法。

Here is another variation based on a solution from this thread.

SELECT DATE_ADD(
           DATE_FORMAT(time, "%Y-%m-%d %H:00:00"),
           INTERVAL FLOOR(MINUTE(time)/5)*5 MINUTE
       );

This solution, unlike ones that use FROM_UNIXTIME, will give the expected value for datetimes that fall within daylight saving time (DST) transitions. (Compare for example 2012-11-03 2:14:00)

Edit - After some quick benchmarking, however, Ollie's first solution appears to perform faster than this. But I still recommend against the FROM_UNIXTIME method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文