【问题标题】:How to round a DateTime in MySQL?如何在 MySQL 中舍入 DateTime?
【发布时间】:2010-12-27 15:22:34
【问题描述】:

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

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

【问题讨论】:

    标签: c# mysql datetime math rounding


    【解决方案1】:

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

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

    祝你好运。

    【讨论】:

    • unixtime 方法是唯一能满足我的需求的方法 =)
    • 对于介于夏令时更改之间的日期时间,Unix 时间方法失败。例如:select FROM_UNIXTIME(UNIX_TIMESTAMP('2012-03-11 2:14:00') - MOD(UNIX_TIMESTAMP('2012-03-11 2:14:00'),300));
    【解决方案2】:

    您可以look here。此示例是舍入到最接近的 X 分钟的一般情况,并且是用 T-SQL 编写的,但两种情况下的逻辑和大部分函数将相同。

    【讨论】:

    • 正如我所说,虽然大多数功能是相同的,但并非所有功能都相同。你需要自己做一些。
    【解决方案3】:
    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('2012-03-11 2:14:00')/(60*5))*(60*5))
    【解决方案4】:

    您看过 MySQL 中的 CAST 功能吗?

    【讨论】:

      【解决方案5】:

      这是基于 thread 的解决方案的另一个变体。

      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 方法。

      【讨论】:

        【解决方案6】:

        另一种选择:

        获取最近的小时:

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

        希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-26
          • 2020-11-24
          • 2012-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多