Как округлить DateTime в MySQL? - PullRequest
2 голосов
/ 17 декабря 2009

Я хочу дискретизировать DateTime с разрешением 5 минут. Я сделал это в C #, но как преобразовать следующий код в MySQL?

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

Ответы [ 6 ]

7 голосов
/ 17 декабря 2009

Это немного неприятно, когда вы делаете это с типами данных 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))

Удачи.

1 голос
/ 11 августа 2010
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 с другими значениями

1 голос
/ 17 декабря 2009

Вы можете посмотреть здесь . Этот пример является общим случаем округления до ближайших X минут и написан на T-SQL, но логика и большинство функций будут одинаковыми в обоих случаях.

0 голосов
/ 25 марта 2013

Другая альтернатива:

для получения ближайшего часа:

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

Вместо CURDATE() вы можете использовать произвольную дату, например '2000-01-01' Не уверен, что могут возникнуть проблемы с использованием CURDATE(), если системная дата изменяется между двумя вызовами функции, не знаю, будет ли Mysql вызывать оба одновременно.

при изменении 60 на 15 будет получен ближайший 15-минутный интервал, с помощью ВТОРОГО вы можете получить ближайший желаемый второй интервал и т. Д.

Чтобы получить предыдущий час, используйте TRUNCATE() или FLOOR() вместо ROUND().

Надеюсь, это поможет.

0 голосов
/ 01 августа 2012

Вот еще один вариант, основанный на решении из этой нити .

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)

Edit - Однако после некоторого быстрого бенчмаркинга первое решение Олли работает быстрее, чем это. Но я все еще рекомендую против метода FROM_UNIXTIME.

0 голосов
/ 17 декабря 2009

Вы смотрели на функциональность CAST в MySQL?

...