Problemas con fecha
Publicado por Jessy (1 intervención) el 01/04/2006 17:35:47
Hola, tengo esta funcion que me calcula los dias y horas de duracion de un documento tomando en cuenta el horario de trabajo, pero cuando la compilo me sale este mensaje
----------------------------
Server: Msg 241, Level 16, State 1, Procedure Difhoras, Line 138
Syntax error converting datetime from character string.
---------------------------
Favor alguien podria ayudarme
Gracias.
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
alter FUNCTION Difhoras(@StartDate DATETIME,@EndDate DATETIME)
RETURNS integer
AS
Begin
DECLARE @BusinessMM integer
DECLARE @HHFSAB datetime
DECLARE @HHFLV datetime
DECLARE @horasalidaS varchar(16)
DECLARE @horasalidaLV varchar(16)
declare @horasalidaS2 datetime
declare @horasalidaLV2 datetime
DECLARE @Guarda integer
DECLARE @DaysBetween INT
DECLARE @BusinessDays INT
DECLARE @Cnt INT
DECLARE @EvalDate DATETIME
DECLARE @cont int
DECLARE @diferencia int
DECLARE @Factual datetime
DECLARE @A INT
DECLARE @HILV datetime
DECLARE @HSLV datetime
DECLARE @HIS datetime
DECLARE @HSS datetime
DECLARE @ini VARCHAR(10)
DECLARE @fin VARCHAR(10)
DECLARE @ini2 datetime
DECLARE @fin2 datetime
DECLARE @minut INT
/*eSTA VARIABLES SON PARA EXTRAER SOLO LA HORA!! DE LA FECHA DE TERMINO DE LA ATENCION*/
DECLARE @HTerminoAten VARCHAR(8)
DECLARE @HTerminoAten2 DATETIME
--Inicializamos algunas variables
select @HHFSAB = '2006-03-17 13:00:00.000'
select @HHFLV = '2006-03-17 19:00:00.000'
select @HILV = '08:00:00.000'
select @HSLV = '19:00:00.000'
select @HIS = '09:00:00.000'
select @HSS = '13:00:00.000'
SELECT @DaysBetween = 0
SELECT @BusinessDays = 0
SELECT @Cnt=0
--acumuladorpara los minutos (Esto se utiliza para las TRIPLES que duran mas de un dia)
select @minut=0
--Calculamos cuantos dias normales hay en el rango de fechas
SELECT @DaysBetween = DATEDIFF(DAY,@StartDate,@EndDate) + 1
/*Ordenamos el formato de las fechas para que no importando como se proporcionen se comparen igual*/
SELECT @ini = (SELECT CAST((CAST(datepart(yy,@StartDate)AS
VARCHAR(4))+'/'+ CAST(datepart(mm,@StartDate)AS
VARCHAR(2))+'/'+CAST(datepart(dd,@StartDate)AS VARCHAR(2))) as
varchar(10)))
SELECT @fin = (SELECT CAST((CAST(datepart(yy,@EndDate)AS
VARCHAR(4))+'/'+ CAST(datepart(mm,@EndDate)AS VARCHAR(2))+'/'+
CAST(datepart(dd,@EndDate)AS VARCHAR(2)))as varchar(10)))
-- Ahora hacemos lo mismo para la hora de salida, esto se utilizara cuando la triple SSS se aya serrado el mismo dia.
--Este es para el dia SABADO
select @horasalidaS = (SELECT CAST((CAST(datepart(yy,@StartDate)AS VARCHAR(4))+'/'+ CAST(datepart(mm,@StartDate)AS
VARCHAR(2))+'/'+CAST(datepart(dd,@StartDate)AS VARCHAR(2))) as
varchar(10))+' '+CAST(datepart(hh,@HHFSAB)AS varchar(2) )+':'+CAST(datepart(mi,@HHFSAB)AS varchar(2))
+':'+CAST(datepart(ss,@HHFSAB)AS varchar(6)))
--convertimos el valor de @ini y @fin a tipo datetime ya que es varchar
select @ini2 = convert(datetime,@ini)
select @fin2 = convert(datetime,@fin)
/*Esto es para dias de semana L-V */
--Ejemplo==>CAST ( $157.27 AS VARCHAR(10) )
select @horasalidaLV = (SELECT CAST((CAST(datepart(yy,@StartDate)AS VARCHAR(4))+'/'+ CAST(datepart(mm,@StartDate)AS
VARCHAR(2))+'/'+CAST(datepart(dd,@StartDate)AS VARCHAR(2))) as
varchar(10))+' '+CAST(datepart(hh,@HHFLV)AS varchar(2) )+':'+CAST(datepart(mi,@HHFLV)AS varchar(2))
+':'+CAST(datepart(ss,@HHFLV)AS varchar(6)))
---
select @HTerminoAten =CAST(datepart(hh,@EndDate)AS varchar(2) )+':'+CAST(datepart(mi,@EndDate)AS varchar(2))
+':'+CAST(datepart(ss,@EndDate)AS varchar(6))
select @HTerminoAten2 = cast(@HTerminoAten as datetime)
select @horasalidaS2=cast(@horasalidaS as datetime)
select @horasalidaLV2=cast(@horasalidaLV as datetime)
--Se comparan las dos fechas
/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @EvalDate sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/
select @FActual=@ini2
select @diferencia= (datediff(dd,@StartDate,@EndDate))+1
select @cont=0
select @A = 1
select @minut = 0
IF @ini < @fin
BEGIN
------Esto es para contar las horas de varios dias
IF @A <= @diferencia begin
--if datepart(dw,@FActual) <> 7 and datepart(dw,@FActual) <> 1 begin
if @FActual = @ini2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 begin
select @cont= datediff(mi,@StartDate,@horasalidaLV2)
select @minut=@minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @ini2 AND datepart(dw,@FActual) = 7 begin
select @cont= datediff(mi,@StartDate,@horasalidaS2)
select @minut=@minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual > @ini2 and @FActual < @fin2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 begin
select @cont = datediff(mi,@HILV,@HSLV)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual > @ini2 and @FActual < @fin2 AND datepart(dw,@FActual) = 7 begin
select @cont = datediff(mi,@HIS,@HSS)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual > @ini2 and @FActual < @fin2 AND datepart(dw,@FActual) = 1 begin
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 and @HTerminoAten2 <= @HSLV begin
select @cont = datediff(mi,@HILV,@HTerminoAten2)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 and @HTerminoAten2 > @HSLV begin
select @cont = datediff(mi,@HILV,@HSLV)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) = 7 and @HTerminoAten2 <= @HSS begin
select @cont = datediff(mi,@HIS,@HTerminoAten2)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) = 7 and @HTerminoAten2 > @HSS begin
select @cont = datediff(mi,@HIS,@HSS)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if datepart(dw,@FActual) = 1 begin
select @A=@A+1
select @FActual = @FActual + 1
end
--end
end
/*Si la diferencia de fechas es igual a dos, es porque solo ha transcurrido un dia, asi que solo se valida que no vaya a marcar dias de mas*/
--y que cuente las horas transcurridas tomando en cuenta el dia que es.
IF @DaysBetween = 2 BEGIN
SELECT @BusinessDays = 1
END
ELSE
BEGIN
WHILE @Cnt < @DaysBetween
BEGIN
/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @EvalDate sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/
SELECT @EvalDate = @StartDate + @Cnt
/*Utilizando la funcion datepart con el parametro dw que calcula que dia de la semana corresponde una fecha determinada, determinados que no sea sabado (7) o domingo (1)*/
IF (datepart(dw,@EvalDate) <> 1) BEGIN -- and (datepart(dw,@EvalDate) <> 7) )
/*Si no es sabado o domingo, entonces se suma uno al total de dias que queremos desplegar*/
SELECT @BusinessDays = @BusinessDays + 1
END
--Se suma un dia mas al contador
SELECT @Cnt = @Cnt + 1
END
END
select @BusinessMM = @minut
END
ELSE
BEGIN
--Si fuese cierto que las fechas eran iguales se despliage cero
SELECT @BusinessDays = 0
--Si es sabado y la hora de termino fuera mayor a la de salida solo se concedera hasta la hora de salida
if datepart(dw,@StartDate) = 7 and @EndDate > @horasalidaS2 begin
set @Guarda = datediff(mi,@StartDate,@horasalidaS2) ;
end
else --si si no fuese ni domingo ni sabado y ademas la hora de termino fuese mayor a la de salida soolo se concidera hasta la hora de salida.
if datepart(dw,@StartDate) <> 1 and datepart(dw,@StartDate) <> 7 and @EndDate > @horasalidaLV2 begin
set @Guarda = datediff(mi,@StartDate,@horasalidaLV2) ;
end
if datepart(dw,@StartDate) = 7 and @EndDate < @horasalidaS2 begin
set @Guarda = datediff(mi,@StartDate,@EndDate) ;
end
else --si si no fuese ni domingo ni sabado y ademas la hora de termino fuese mayor a la de salida soolo se concidera hasta la hora de salida.
if datepart(dw,@StartDate) <> 1 and datepart(dw,@StartDate) <> 7 and @EndDate < @horasalidaLV2 begin
set @Guarda = datediff(mi,@StartDate,@EndDate) ;
end
select @BusinessMM= @Guarda
END
--return (@BusinessDays)
return (@BusinessMM)
END
go
--select num,dbo.Difhoras(fechaini,fechafin) from sss
----------------------------
Server: Msg 241, Level 16, State 1, Procedure Difhoras, Line 138
Syntax error converting datetime from character string.
---------------------------
Favor alguien podria ayudarme
Gracias.
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
alter FUNCTION Difhoras(@StartDate DATETIME,@EndDate DATETIME)
RETURNS integer
AS
Begin
DECLARE @BusinessMM integer
DECLARE @HHFSAB datetime
DECLARE @HHFLV datetime
DECLARE @horasalidaS varchar(16)
DECLARE @horasalidaLV varchar(16)
declare @horasalidaS2 datetime
declare @horasalidaLV2 datetime
DECLARE @Guarda integer
DECLARE @DaysBetween INT
DECLARE @BusinessDays INT
DECLARE @Cnt INT
DECLARE @EvalDate DATETIME
DECLARE @cont int
DECLARE @diferencia int
DECLARE @Factual datetime
DECLARE @A INT
DECLARE @HILV datetime
DECLARE @HSLV datetime
DECLARE @HIS datetime
DECLARE @HSS datetime
DECLARE @ini VARCHAR(10)
DECLARE @fin VARCHAR(10)
DECLARE @ini2 datetime
DECLARE @fin2 datetime
DECLARE @minut INT
/*eSTA VARIABLES SON PARA EXTRAER SOLO LA HORA!! DE LA FECHA DE TERMINO DE LA ATENCION*/
DECLARE @HTerminoAten VARCHAR(8)
DECLARE @HTerminoAten2 DATETIME
--Inicializamos algunas variables
select @HHFSAB = '2006-03-17 13:00:00.000'
select @HHFLV = '2006-03-17 19:00:00.000'
select @HILV = '08:00:00.000'
select @HSLV = '19:00:00.000'
select @HIS = '09:00:00.000'
select @HSS = '13:00:00.000'
SELECT @DaysBetween = 0
SELECT @BusinessDays = 0
SELECT @Cnt=0
--acumuladorpara los minutos (Esto se utiliza para las TRIPLES que duran mas de un dia)
select @minut=0
--Calculamos cuantos dias normales hay en el rango de fechas
SELECT @DaysBetween = DATEDIFF(DAY,@StartDate,@EndDate) + 1
/*Ordenamos el formato de las fechas para que no importando como se proporcionen se comparen igual*/
SELECT @ini = (SELECT CAST((CAST(datepart(yy,@StartDate)AS
VARCHAR(4))+'/'+ CAST(datepart(mm,@StartDate)AS
VARCHAR(2))+'/'+CAST(datepart(dd,@StartDate)AS VARCHAR(2))) as
varchar(10)))
SELECT @fin = (SELECT CAST((CAST(datepart(yy,@EndDate)AS
VARCHAR(4))+'/'+ CAST(datepart(mm,@EndDate)AS VARCHAR(2))+'/'+
CAST(datepart(dd,@EndDate)AS VARCHAR(2)))as varchar(10)))
-- Ahora hacemos lo mismo para la hora de salida, esto se utilizara cuando la triple SSS se aya serrado el mismo dia.
--Este es para el dia SABADO
select @horasalidaS = (SELECT CAST((CAST(datepart(yy,@StartDate)AS VARCHAR(4))+'/'+ CAST(datepart(mm,@StartDate)AS
VARCHAR(2))+'/'+CAST(datepart(dd,@StartDate)AS VARCHAR(2))) as
varchar(10))+' '+CAST(datepart(hh,@HHFSAB)AS varchar(2) )+':'+CAST(datepart(mi,@HHFSAB)AS varchar(2))
+':'+CAST(datepart(ss,@HHFSAB)AS varchar(6)))
--convertimos el valor de @ini y @fin a tipo datetime ya que es varchar
select @ini2 = convert(datetime,@ini)
select @fin2 = convert(datetime,@fin)
/*Esto es para dias de semana L-V */
--Ejemplo==>CAST ( $157.27 AS VARCHAR(10) )
select @horasalidaLV = (SELECT CAST((CAST(datepart(yy,@StartDate)AS VARCHAR(4))+'/'+ CAST(datepart(mm,@StartDate)AS
VARCHAR(2))+'/'+CAST(datepart(dd,@StartDate)AS VARCHAR(2))) as
varchar(10))+' '+CAST(datepart(hh,@HHFLV)AS varchar(2) )+':'+CAST(datepart(mi,@HHFLV)AS varchar(2))
+':'+CAST(datepart(ss,@HHFLV)AS varchar(6)))
---
select @HTerminoAten =CAST(datepart(hh,@EndDate)AS varchar(2) )+':'+CAST(datepart(mi,@EndDate)AS varchar(2))
+':'+CAST(datepart(ss,@EndDate)AS varchar(6))
select @HTerminoAten2 = cast(@HTerminoAten as datetime)
select @horasalidaS2=cast(@horasalidaS as datetime)
select @horasalidaLV2=cast(@horasalidaLV as datetime)
--Se comparan las dos fechas
/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @EvalDate sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/
select @FActual=@ini2
select @diferencia= (datediff(dd,@StartDate,@EndDate))+1
select @cont=0
select @A = 1
select @minut = 0
IF @ini < @fin
BEGIN
------Esto es para contar las horas de varios dias
IF @A <= @diferencia begin
--if datepart(dw,@FActual) <> 7 and datepart(dw,@FActual) <> 1 begin
if @FActual = @ini2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 begin
select @cont= datediff(mi,@StartDate,@horasalidaLV2)
select @minut=@minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @ini2 AND datepart(dw,@FActual) = 7 begin
select @cont= datediff(mi,@StartDate,@horasalidaS2)
select @minut=@minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual > @ini2 and @FActual < @fin2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 begin
select @cont = datediff(mi,@HILV,@HSLV)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual > @ini2 and @FActual < @fin2 AND datepart(dw,@FActual) = 7 begin
select @cont = datediff(mi,@HIS,@HSS)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual > @ini2 and @FActual < @fin2 AND datepart(dw,@FActual) = 1 begin
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 and @HTerminoAten2 <= @HSLV begin
select @cont = datediff(mi,@HILV,@HTerminoAten2)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) <> 1 and datepart(dw,@FActual) <> 7 and @HTerminoAten2 > @HSLV begin
select @cont = datediff(mi,@HILV,@HSLV)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) = 7 and @HTerminoAten2 <= @HSS begin
select @cont = datediff(mi,@HIS,@HTerminoAten2)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if @FActual = @fin2 AND datepart(dw,@FActual) = 7 and @HTerminoAten2 > @HSS begin
select @cont = datediff(mi,@HIS,@HSS)
select @minut = @minut + @cont
select @A=@A+1
select @FActual = @FActual + 1
end
if datepart(dw,@FActual) = 1 begin
select @A=@A+1
select @FActual = @FActual + 1
end
--end
end
/*Si la diferencia de fechas es igual a dos, es porque solo ha transcurrido un dia, asi que solo se valida que no vaya a marcar dias de mas*/
--y que cuente las horas transcurridas tomando en cuenta el dia que es.
IF @DaysBetween = 2 BEGIN
SELECT @BusinessDays = 1
END
ELSE
BEGIN
WHILE @Cnt < @DaysBetween
BEGIN
/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @EvalDate sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/
SELECT @EvalDate = @StartDate + @Cnt
/*Utilizando la funcion datepart con el parametro dw que calcula que dia de la semana corresponde una fecha determinada, determinados que no sea sabado (7) o domingo (1)*/
IF (datepart(dw,@EvalDate) <> 1) BEGIN -- and (datepart(dw,@EvalDate) <> 7) )
/*Si no es sabado o domingo, entonces se suma uno al total de dias que queremos desplegar*/
SELECT @BusinessDays = @BusinessDays + 1
END
--Se suma un dia mas al contador
SELECT @Cnt = @Cnt + 1
END
END
select @BusinessMM = @minut
END
ELSE
BEGIN
--Si fuese cierto que las fechas eran iguales se despliage cero
SELECT @BusinessDays = 0
--Si es sabado y la hora de termino fuera mayor a la de salida solo se concedera hasta la hora de salida
if datepart(dw,@StartDate) = 7 and @EndDate > @horasalidaS2 begin
set @Guarda = datediff(mi,@StartDate,@horasalidaS2) ;
end
else --si si no fuese ni domingo ni sabado y ademas la hora de termino fuese mayor a la de salida soolo se concidera hasta la hora de salida.
if datepart(dw,@StartDate) <> 1 and datepart(dw,@StartDate) <> 7 and @EndDate > @horasalidaLV2 begin
set @Guarda = datediff(mi,@StartDate,@horasalidaLV2) ;
end
if datepart(dw,@StartDate) = 7 and @EndDate < @horasalidaS2 begin
set @Guarda = datediff(mi,@StartDate,@EndDate) ;
end
else --si si no fuese ni domingo ni sabado y ademas la hora de termino fuese mayor a la de salida soolo se concidera hasta la hora de salida.
if datepart(dw,@StartDate) <> 1 and datepart(dw,@StartDate) <> 7 and @EndDate < @horasalidaLV2 begin
set @Guarda = datediff(mi,@StartDate,@EndDate) ;
end
select @BusinessMM= @Guarda
END
--return (@BusinessDays)
return (@BusinessMM)
END
go
--select num,dbo.Difhoras(fechaini,fechafin) from sss
Valora esta pregunta
0