2009-12-17 4 views
2

Je veux discrétiser le DateTime avec la résolution de 5 minutes. Je l'ai fait en C#, mais comment convertir le code suivant en MySQL?Comment faire pour arrondir un DateTime dans MySQL?

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

Répondre

7

Il est un peu méchant quand vous le faites avec des types de données datetime; un bon candidat pour une fonction stockée.

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

Il est plus facile lorsque vous utilisez horodatages unixtime mais qui est limité à une 1970 - plage de dates 2038.

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

Bonne chance.

+0

L'approche unixtime est la seule assez précise à mes besoins =) –

+2

L'approche du temps unix échoue pour les dates qui tombent entre les changements de l'heure d'été. Par exemple: 'sélectionnez FROM_UNIXTIME (UNIX_TIMESTAMP ('2012-03-11 2:14:00') - MOD (UNIX_TIMESTAMP ('2012-03-11 2:14:00'), 300));' –

1

Vous pouvez look here. Cet exemple est un cas général d'arrondi aux X minutes les plus proches, et est écrit en T-SQL, mais la logique et la majorité des fonctions seront les mêmes dans les deux cas.

+0

SELECT CAST (MAINTENANT() COMME FLOAT) ne fonctionne pas dans MySQL –

+0

Comme je l'ai dit, alors que la plupart des fonctions sont identiques, elles ne le sont pas toutes.Vous devrez en faire vous-même. – Gausie

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

vous pouvez remplacer les deux 5 s avec d'autres valeurs

+0

Cette méthode ne fonctionne pas pour les périodes qui se situent entre les changements de l'heure d'été. Par exemple: 'from_unixtime (floor (unix_timestamp ('2012-03-11 2:14:00')/(60 * 5)) * (60 * 5))' –

0

Voici une autre variante basée sur une solution de ce thread.

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

Cette solution, contrairement à ceux qui utilisent FROM_UNIXTIME, donnera la valeur attendue pour datetimes qui entrent dans les transitions de l'heure d'été (DST). (Comparer par exemple 2012-11-03 2:14:00)

Éditer - Après une analyse comparative rapide, cependant, la première solution d'Ollie semble fonctionner plus rapidement que cela. Mais je recommande toujours contre la méthode FROM_UNIXTIME.

0

Une autre alternative:

pour obtenir le le plus proche heures:

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

Au lieu de CURDATE() vous pouvez utiliser une date arbitraire, par exemple '2000-01-01' Je ne sais pas s'il pourrait y avoir des problèmes en utilisant CURDATE() si la date du système change entre les deux appels à la fonction, ne sait pas si Mysql appelle les deux en même temps.

changer 60 de 15 obtiendrait l'intervalle de 15 minutes le plus proche, en utilisant SECOND vous pouvez obtenir le deuxième intervalle désiré le plus proche, etc.

Pour l'utilisation précédente heures TRUNCATE() ou FLOOR() au lieu de ROUND().

Espérons que cela aide.

Questions connexes