web-dev-qa-db-fra.com

MYSQL Date Heure autour de l'heure la plus proche

J'ai un champ date/heure dans une base de données MySQL et souhaite afficher le résultat à l'heure la plus proche.

par exemple. 2012-04-01 00:00:01 devrait lire 2012-04-01 00:00:00

33
user1217917

Mise à jour: Je pense/ https://stackoverflow.com/a/21330407/480943 est une meilleure réponse.


Vous pouvez le faire avec une arithmétique de date:

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

Explications:

  • DATE_FORMAT : DATE_FORMAT(the_date, "%Y-%m-%d %H:00:00") renvoie la date tronquée à l'heure la plus proche (règle les minutes et les secondes parties sur zéro).

  • MINUTE : MINUTE(the_date) obtient la valeur en minutes de la date.

  • IF : Ceci est une condition; Si la valeur du paramètre 1 est vraie, elle renvoie le paramètre 2, sinon elle renvoie le paramètre 3. Donc, IF(MINUTE(the_date) < 30, 0, 1) signifie "Si la valeur des minutes est inférieure à 30, retourne 0, sinon renvoie 1". C'est ce que nous allons utiliser pour arrondir - c'est le nombre d'heures à ajouter.

  • DATE_ADD : Ceci ajoute le nombre d'heures pour le tour dans le résultat.

40
Ben Lee

la première solution de soul tronque au lieu d'arrondir et la deuxième solution ne fonctionne pas avec les cas d'heure avancée tels que:

select FROM_UNIXTIME(UNIX_TIMESTAMP('2012-03-11 2:14:00') - MOD(UNIX_TIMESTAMP('2012-03-11 2:14:00'),300));

Voici une autre méthode (1):

DATE_ADD(
    tick,
    INTERVAL (IF((MINUTE(tick)*60)+SECOND(tick) < 1800, 0, 3600) - (MINUTE(tick)*60)+SECOND(tick)) SECOND
)

Si vous n'avez pas à vous soucier des secondes, vous pouvez le simplifier comme ceci (2):

DATE_ADD(
    tick,
    INTERVAL (IF(MINUTE(tick) < 30, 0, 60) - MINUTE(tick)) MINUTE
)

Ou si vous préférez tronquer au lieu de arrondir, voici une version plus simple de la méthode de soul (3):

DATE_SUB(tick, INTERVAL MINUTE(tick)*60+SECOND(tick) SECOND)

EDIT: J'ai analysé certaines de ces requêtes sur mon ordinateur local et découvert que pour 100 000 lignes, les délais moyens étaient les suivants:

  • méthode UNIXTIME de soul: 0,0423 ms (rapide, mais ne fonctionne pas avec DST)
  • Ma méthode 3: 0.1255 ms
  • Ma méthode 2: 0,1289 ms
  • Méthode DATE_FORMAT de Ben Lee: 0,1495 ms
  • Ma méthode 1: 0.1506 ms
12
Code Commander

De Comment arrondir un DateTime dans MySQL? :

C'est un peu désagréable de le faire avec des types de données datetime. un candidat de Nice pour une fonction stockée.

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

C’est plus facile lorsque vous utilisez les horodatages UNIXTIME, mais cela est limité à une plage de dates allant de 1970 à 2038.

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

Bonne chance.

5
Ghostman

Cela retournera l'heure suivante, c'est-à-dire que '2012-01-02 18:02:30' sera converti en '2012-01-02 19:00:00'

TIMESTAMPADD(HOUR,
    TIMESTAMPDIFF(HOUR,CURDATE(),timestamp_column_name),
    CURDATE())

Au lieu de CURDATE(), vous pouvez utiliser une date arbitraire, par exemple '2000-01-01' Vous ne savez pas s'il pourrait y avoir des problèmes d'utilisation de CURDATE() si la date système change entre les deux appels à la fonction, ne savez pas si Mysql les appellerait de la même manière temps.

pour obtenir l'heure la plus proche heure serait:

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

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

Pour obtenir l'heure précédente, utilisez TRUNCATE() ou FLOOR() au lieu de ROUND().

J'espère que cela t'aides.

1
TMC

Pour arrondir à l'heure courante, sélectionnez:

FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(column_name) / 3600) * 3600).

La valeur est exprimée dans le fuseau horaire actuel doc

0
Zibi

Si vous avez besoin d'arrondir l'heure à l'heure suivante, vous pouvez utiliser ceci:

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

Je pense que c’est le meilleur moyen, car il utilisera également le moins de ressources possible

date_add(date(date_completed), interval hour(date_completed) hour) as date_hr
0
Dane Thomas