125 votes

T-SQL datetime arrondi à la minute la plus proche et aux heures les plus proches avec l'utilisation des fonctions

Dans le serveur SQL 2008, je voudrais obtenir une colonne de date arrondie à l'heure et à la minute les plus proches, de préférence avec les fonctions existantes en 2008.

Pour cette valeur de colonne 2007-09-22 15:07:38.850 le résultat sera le suivant :

2007-09-22 15:07 -- nearest minute
2007-09-22 15    -- nearest hour

6 votes

L'exemple de la minute la plus proche ne devrait-il pas être 15:08 ? Parce que les secondes d'une minute font 60...

0 votes

Avez-vous intentionnellement omis de corriger cette erreur lorsque vous avez édité sa question afin de pouvoir faire ce commentaire ?

0 votes

@MrWednesday Vous réalisez qu'il y a plus de 10 minutes entre l'édition et ce commentaire. J'imagine que la pensée est venue après.

233voto

adrift Points 24386
declare @dt datetime

set @dt = '09-22-2007 15:07:38.850'

select dateadd(mi, datediff(mi, 0, @dt), 0)
select dateadd(hour, datediff(hour, 0, @dt), 0)

retournera

2007-09-22 15:07:00.000
2007-09-22 15:00:00.000

La méthode ci-dessus ne fait que tronquer les secondes et les minutes, produisant ainsi les résultats demandés dans la question. Comme l'a souligné @OMG Ponies, si vous voulez arrondir vers le haut ou vers le bas, vous pouvez ajouter une demi-minute ou une demi-heure respectivement, puis tronquer :

select dateadd(mi, datediff(mi, 0, dateadd(s, 30, @dt)), 0)
select dateadd(hour, datediff(hour, 0, dateadd(mi, 30, @dt)), 0)

et vous obtiendrez :

2007-09-22 15:08:00.000
2007-09-22 15:00:00.000

Avant le date a été ajouté dans SQL Server 2008, j'utiliserais la méthode ci-dessus pour tronquer la partie temps d'un temps de date pour obtenir uniquement la date. L'idée est de déterminer le nombre de jours entre la date en question et un point fixe dans le temps ( 0 qui est implicitement converti en 1900-01-01 00:00:00.000 ) :

declare @days int
set @days = datediff(day, 0, @dt)

puis ajoutez ce nombre de jours au point fixe dans le temps, ce qui vous donne la date d'origine avec l'heure réglée sur 00:00:00.000 :

select dateadd(day, @days, 0)

ou plus succinctement :

select dateadd(day, datediff(day, 0, @dt), 0)

L'utilisation d'une autre partie de la date (par ex. hour , mi ) fonctionneront en conséquence.

3 votes

Je doute que quelqu'un d'autre rencontre ce problème, mais si vous essayez d'arrondir à la seconde la plus proche et que vous ajoutez 500 millisecondes, vous devrez faire datediff(second, '1/1/2000', .... vs datediff(second, 0 .... car vous obtiendrez une erreur de débordement. Les secondes à partir de 0 sont trop grandes je suppose.

0 votes

Ajouter le nombre d'heures depuis le 1er janvier 1900, au 1er janvier 1900" - J'ai rencontré cela en Java/SQL, où c'est très laid. Dans mon cas, cela aurait dû être fait du côté de Java.

0 votes

Pour les calculs avec datetimeoffset j'ai dû substituer 0 avec TODATETIMEOFFSET('1900-01-01 00:00:00', 0) pour éviter de forcer le fuseau horaire local sur le résultat.

26voto

Magnus Points 20478

"Arrondi" vers le bas comme dans votre exemple. Ceci retournera une valeur varchar de la date.

DECLARE @date As DateTime2
SET @date = '2007-09-22 15:07:38.850'

SELECT CONVERT(VARCHAR(16), @date, 120) --2007-09-22 15:07
SELECT CONVERT(VARCHAR(13), @date, 120) --2007-09-22 15

0 votes

Convertir le varchar en datetime pourrait faire l'affaire (pour l'heure) : CONVERT(datetime, CONVERT(VARCHAR(13), @date, 120)+':00:00')

18voto

Andrew Steitz Points 1060

Je réalise que cette question est ancienne et qu'il y a une réponse acceptée et une autre. Je réalise également que ma réponse ne répondra qu'à la moitié de la question, mais pour tous ceux qui souhaitent arrondir à la minute la plus proche tout en ayant une valeur compatible avec le temps en utilisant une seule fonction :

CAST(YourValueHere as smalldatetime);

Pour les heures ou les secondes, utilisez la réponse de Jeff Ogata (la réponse acceptée) ci-dessus.

1 votes

Excellente réponse, j'ai vérifié qu'il arrondit et ne tronque pas seulement. Pour tous ceux qui envisagent cette option, smalldatetime a été ajouté dans SQL 2008.

0 votes

Il s'agit de la meilleure option si vous avez besoin de corriger certaines données dans votre tableau qui ne nécessite qu'un temps à la minute près.

-1voto

Jam_Jam Points 23

Select convert(char(8), DATEADD(MINUTE, DATEDIFF(MINUTE, 0, getdate), 0), 108) as Time

arrondira les secondes à 00

0 votes

Très lent, et ne s'arrondit pas comme le demande le PO, mais s'arrondit vers le bas, ce qu'il n'a pas demandé. (Clause de non-responsabilité - Je n'ai pas voté contre vous)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X