Fecha y hora de T-SQL redondeada al minuto y a las horas más cercanas con funciones de uso

113

En SQL Server 2008, me gustaría que la columna de fecha y hora se redondee a la hora y al minuto más cercanos, preferiblemente con las funciones existentes en 2008.

Para este valor de columna 2007-09-22 15:07:38.850, la salida se verá así:

2007-09-22 15:08 -- nearest minute
2007-09-22 15    -- nearest hour
user219628
fuente
6
¿No debería ser el ejemplo de minutos más cercano 15:08? Porque los segundos en un minuto son 60 ...
OMG Ponies
¿No corrigió intencionalmente ese error cuando editó su pregunta para poder hacer ese comentario?
Mr miércoles
@MrWed Wednesday Te das cuenta de que hay más de 10 minutos entre la edición y ese comentario. Me imagino que el pensamiento ocurrió después.
lc.

Respuestas:

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

volverá

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

Lo anterior solo trunca los segundos y minutos, produciendo los resultados solicitados en la pregunta. Como señaló @OMG Ponies, si desea redondear hacia arriba / hacia abajo, puede agregar medio minuto o media hora respectivamente, luego truncar:

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

y obtendrás:

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

Antes de que se agregara el tipo de datos de fecha en SQL Server 2008, usaría el método anterior para truncar la parte de tiempo de una fecha y hora para obtener solo la fecha. La idea es determinar el número de días entre la fecha y hora en cuestión y un punto fijo en el tiempo ( 0que implícitamente se convierte en 1900-01-01 00:00:00.000):

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

y luego agregue esa cantidad de días al punto fijo en el tiempo, lo que le da la fecha original con la hora establecida en 00:00:00.000:

select dateadd(day, @days, 0)

o más sucintamente:

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

El uso de una parte de fecha diferente (por ejemplo hour, mi) funcionará en consecuencia.

Jeff Ogata
fuente
2
Dudo que alguien más se encuentre con esto, pero si está tratando de redondear hacia ARRIBA al segundo más cercano y agregar 500 milisegundos, querrá hacer dateiff (segundo, '1/1/2000', .... vs dateiff (segundo, 0 .... ya que obtendrá un error de desbordamiento. Los segundos desde 0 son demasiado grandes, supongo.
Eric Twilegar
'Agregue la cantidad de horas desde el 1 de enero de 1900 hasta el 1 de enero de 1900': encontré esto en Java / SQL, donde se ve feo. En mi caso, realmente debería haberse hecho en el lado de Java.
Corwin Newall
Para los cálculos con datetimeoffset, tuve que sustituir 0con TODATETIMEOFFSET('1900-01-01 00:00:00', 0)para evitar forzar la zona horaria local en el resultado.
krlmlr
26

"Redondeado" hacia abajo como en su ejemplo. Esto devolverá un valor varchar de la fecha.

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
Magnus
fuente
Convertir el varchar de nuevo a datetime podría hacer (por hora):CONVERT(datetime, CONVERT(VARCHAR(13), @date, 120)+':00:00')
Decula
10

Me doy cuenta de que esta pregunta es antigua y hay una respuesta alternativa y aceptada. También me doy cuenta de que mi respuesta solo responderá la mitad de la pregunta, pero para cualquiera que quiera redondear al minuto más cercano y aún tener un valor compatible con fecha y hora usando solo una función :

CAST(YourValueHere as smalldatetime);

Durante horas o segundos, use la respuesta de Jeff Ogata (la respuesta aceptada) anterior.

Andrew Steitz
fuente
1
Excelente respuesta, he verificado que se redondea y no solo se trunca. Para cualquier otra persona que busque en esta opción, smalldatetimese agregó en SQL 2008.
BradC
Esta es la mejor opción si necesita corregir algunos datos en su tabla que solo requieren un tiempo de espera por minuto.
Cifrado
-1

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

redondeará los segundos a 00

Mermelada mermelada
fuente
Muy lento, y no redondea como pidió el OP, sino que redondea hacia abajo, por lo que no pidió. (Descargo de responsabilidad: no lo rechacé)
Ingeniero