¿Por qué el tiempo superior a 24 horas no se formateará correctamente con DateAdd?
gotqn
5
@gotqn: DateAdd () no es el problema. Convert () es el problema. Convert () se ajusta efectivamente a cero cada 24 horas. Si usa Convert () para formatear un intervalo de 27 horas, devolverá "03:00:00".
Mike Sherrill 'Cat Recall'
Cómo manejar este formato si el caso de uso dice que los resultados pueden ser negativos hh: mm: ss (por ejemplo, -340: 23: 34, 03: -4: 05,13: 54: -8, etc.)
OmGanesh
1
Este es el camino a seguir. Ninguna de las otras soluciones aquí funcionará correctamente para el formato HHMMSS más allá de las 24 horas. Esto también ayudará a mantener sus consultas ordenadas.
Krummelz
27
Para aquellos que tienen problemas con el uso de DATEADD y CONVERT durante segundos que exceden las 24 horas, podemos usar modulus para solucionarlo:
Esta debería ser la respuesta aceptada: se ocupa de los seconds, como pidió el OP, evita el uso de un ineficiente scalar functiony se ocupa de los períodos de varios días de manera adecuada. El único detalle menor que agregaría es que, en la tierra del Agente SQL, su tiempo transcurrido / intervalos de tiempo para la parte de "días" generalmente usan "days.hh: mm: ss", es decir, a en dotlugar de colon. Así, por ejemplo, 2.01:03:04durante 2 días, 1 hora, 3 minutos, 4 segundos. ¡Salud!
Respuestas:
Desea multiplicar a milisegundos a medida que se descarta la parte fraccionaria.
SELECT DATEADD(ms, 121.25 * 1000, 0)
Si lo desea sin la parte de la fecha, puede usar CONVERT, con el estilo 114
SELECT CONVERT(varchar, DATEADD(ms, 121.25 * 1000, 0), 114)
fuente
Si su tiempo excede las 24 horas , no se manejará correctamente con los métodos DATEADD y CONVERT.
SELECT CONVERT(varchar, DATEADD(ms, 24*60*60 * 1000, 0), 114) 00:00:00:000
La siguiente función manejará tiempos que excedan las 24 horas (~ máximo 35,791,394 horas).
create function [dbo].[ConvertTimeToHHMMSS] ( @time decimal(28,3), @unit varchar(20) ) returns varchar(20) as begin declare @seconds decimal(18,3), @minutes int, @hours int; if(@unit = 'hour' or @unit = 'hh' ) set @seconds = @time * 60 * 60; else if(@unit = 'minute' or @unit = 'mi' or @unit = 'n') set @seconds = @time * 60; else if(@unit = 'second' or @unit = 'ss' or @unit = 's') set @seconds = @time; else set @seconds = 0; -- unknown time units set @hours = convert(int, @seconds /60 / 60); set @minutes = convert(int, (@seconds / 60) - (@hours * 60 )); set @seconds = @seconds % 60; return convert(varchar(9), convert(int, @hours)) + ':' + right('00' + convert(varchar(2), convert(int, @minutes)), 2) + ':' + right('00' + convert(varchar(6), @seconds), 6) end
Uso:
select dbo.ConvertTimeToHHMMSS(123, 's') select dbo.ConvertTimeToHHMMSS(96.999, 'mi') select dbo.ConvertTimeToHHMMSS(35791394.999, 'hh') 0:02:03.000 1:36:59.940 35791394:59:56.400
fuente
Para aquellos que tienen problemas con el uso de DATEADD y CONVERT durante segundos que exceden las 24 horas, podemos usar modulus para solucionarlo:
SELECT CONVERT(varchar, @seconds / 86400 ) + ':' + -- Days CONVERT(varchar, DATEADD(ms, ( @seconds % 86400 ) * 1000, 0), 114) as "Converted to D:HH:MM:SS.MS"
fuente
DECLARE @seconds AS int = 896434; SELECT CONVERT(varchar, (@seconds / 86400)) --Days + ':' + CONVERT(varchar, DATEADD(ss, @seconds, 0), 108); --Hours, Minutes, Seconds
Salidas:
fuente
second
s, como pidió el OP, evita el uso de un ineficientescalar function
y se ocupa de los períodos de varios días de manera adecuada. El único detalle menor que agregaría es que, en la tierra del Agente SQL, su tiempo transcurrido / intervalos de tiempo para la parte de "días" generalmente usan "days.hh: mm: ss", es decir, a endot
lugar decolon
. Así, por ejemplo,2.01:03:04
durante 2 días, 1 hora, 3 minutos, 4 segundos. ¡Salud!Usando SQL Server 2008
declare @Seconds as int = 3600; SELECT CONVERT(time(0), DATEADD(SECOND, @Seconds, 0)) as 'hh:mm:ss'
fuente
Usando SQL Server 05 puedo hacer que esto funcione usando:
declare @OrigValue int; set @OrigValue = 121.25; select replace(str(@OrigValue/3600,len(ltrim(@OrigValue/3600))+abs(sign(@OrigValue/359999)-1)) + ':' + str((@OrigValue/60)%60,2) + ':' + str(@OrigValue%60,2),' ','0')
fuente
SELECT substring(convert (varchar(23),Dateadd(s,10000,LEFT(getdate(),11)),121),12,8)
10000 es su valor en segundos
fuente
DECLARE @TimeinSecond INT SET @TimeinSecond = 340 -- Change the seconds SELECT RIGHT('0' + CAST(@TimeinSecond / 3600 AS VARCHAR),2) + ':' + RIGHT('0' + CAST((@TimeinSecond / 60) % 60 AS VARCHAR),2) + ':' + RIGHT('0' + CAST(@TimeinSecond % 60 AS VARCHAR),2)
fuente
Esto es lo que uso (normalmente para informes de correo electrónico de tablas html)
declare @time int, @hms varchar(20) set @time = 12345 set @hms = cast(cast((@Time)/3600 as int) as varchar(3)) +':'+ right('0'+ cast(cast(((@Time)%3600)/60 as int) as varchar(2)),2) +':'+ right('0'+ cast(((@Time)%3600)%60 as varchar(2)),2) +' (hh:mm:ss)' select @hms
fuente
DECLARE @Seconds INT = 86200; SELECT CONVERT(VARCHAR(15), CAST(CONVERT(VARCHAR(12), @Seconds / 60 / 60 % 24) +':'+ CONVERT(VARCHAR(2), @Seconds / 60 % 60) +':'+ CONVERT(VARCHAR(2), @Seconds % 60) AS TIME), 100) AS [HH:MM:SS (AM/PM)]
fuente
Puedes probar esto
set @duration= 112000 SELECT "Time" = cast (@duration/3600 as varchar(3)) +'H' + Case when ((@duration%3600 )/60)<10 then '0'+ cast ((@duration%3600 )/60)as varchar(3)) else cast ((@duration/60) as varchar(3)) End
fuente